import sys





class UnionFind():

    def __init__(self, n):

        self.n = n

        self.p = [i for i in range(n + 5)]

        self.rank = [0 for i in range(n + 5)]



    def find_set(self, x):

        if self.p[x] != x:

            self.p[x] = self.find_set(self.p[x])

        return self.p[x]



    def unite(self, x, y):

        px, py = self.find_set(x), self.find_set(y)

        if px == py:

            return

        if self.rank[px] > self.rank[py]:

            self.p[py] = px

        else:

            self.p[px] = py

            if self.rank[px] == self.rank[py]:

                self.rank[py] += 1





def main():

    sys.setrecursionlimit(int(1e5))

    nvertices, nedges = list(map(int, input().split()))

    E = []

    uf = UnionFind(nvertices)

    for i in range(nedges):

        s, t, w = list(map(int, input().split()))

        E.append((w, s, t))

    E.sort()



    ans = 0

    for w, s, t in E:

        if uf.find_set(s) != uf.find_set(t):

            ans += w

            uf.unite(s, t)



    print(ans)





main()
import sys





class UnionFind:



    def __init__(self, nvertices):

        self.rank = [1] * (nvertices + 5)

        self.p = [i for i in range(nvertices + 5)]



    def find_set(self, u):

        if u != self.p[u]:

            self.p[u] = self.find_set(self.p[u])

        return self.p[u]



    def unite(self, u, v):

        x = self.find_set(u)

        y = self.find_set(v)

        if x == y:

            return

        if self.rank[x] > self.rank[y]:

            self.p[y] = x

        else:

            self.p[x] = y

            if self.rank[x] == self.rank[y]:

                self.rank[y] += 1



    def is_connected(self, u, v):

        return self.find_set(u) == self.find_set(v)





def main():

    sys.setrecursionlimit(int(1e5))

    nvertices, nedges = list(map(int, input().split()))

    edges = []

    for i in range(nedges):

        u, v, w = list(map(int, input().split()))

        edges.append((w, u, v))



    edges.sort(key=lambda e: e[0])

    ans = 0

    uf = UnionFind(nvertices)

    for w, u, v in edges:

        if not uf.is_connected(u, v):

            uf.unite(u, v)

            ans += w



    print(ans)





main()
import sys


class UnionFind:
    def __init__(self, n):
        self.n = n
        self.p = [i for i in range(n + 5)]
        self.rank = [0 for i in range(n + 5)]

    def find_set(self, x):
        if self.p[x] != x:
            self.p[x] = self.find_set(self.p[x])
        return self.p[x]

    def unite(self, x, y):
        px, py = self.find_set(x), self.find_set(y)
        if px == py:
            return
        if self.rank[px] > self.rank[py]:
            self.p[py] = px
        else:
            self.p[px] = py
            if self.rank[px] == self.rank[py]:
                self.rank[py] += 1


def main():
    sys.setrecursionlimit(int(1e5))
    nvertices, nedges = list(map(int, input().split()))
    E = []
    uf = UnionFind(nvertices)
    for i in range(nedges):
        s, t, w = list(map(int, input().split()))
        E.append((w, s, t))
    E.sort()
    ans = 0
    for w, s, t in E:
        if uf.find_set(s) != uf.find_set(t):
            ans += w
            uf.unite(s, t)
    print(ans)


main()

import sys


class UnionFind:
    def __init__(self, nvertices):
        self.rank = [1] * (nvertices + 5)
        self.p = [i for i in range(nvertices + 5)]

    def find_set(self, u):
        if u != self.p[u]:
            self.p[u] = self.find_set(self.p[u])
        return self.p[u]

    def unite(self, u, v):
        x = self.find_set(u)
        y = self.find_set(v)
        if x == y:
            return
        if self.rank[x] > self.rank[y]:
            self.p[y] = x
        else:
            self.p[x] = y
            if self.rank[x] == self.rank[y]:
                self.rank[y] += 1

    def is_connected(self, u, v):
        return self.find_set(u) == self.find_set(v)


def main():
    sys.setrecursionlimit(int(1e5))
    nvertices, nedges = list(map(int, input().split()))
    edges = []
    for i in range(nedges):
        u, v, w = list(map(int, input().split()))
        edges.append((w, u, v))
    edges.sort(key=lambda e: e[0])
    ans = 0
    uf = UnionFind(nvertices)
    for w, u, v in edges:
        if not uf.is_connected(u, v):
            uf.unite(u, v)
            ans += w
    print(ans)


main()

-    def __init__(self, n): -        self.n = n -        self.p = [i for i in range(n + 5)] -        self.rank = [0 for i in range(n + 5)] +    def __init__(self, nvertices): +        self.rank = [1] * (nvertices + 5) +        self.p = [i for i in range(nvertices + 5)] -    def find_set(self, x): -        if self.p[x] != x: -            self.p[x] = self.find_set(self.p[x]) -        return self.p[x] +    def find_set(self, u): +        if u != self.p[u]: +            self.p[u] = self.find_set(self.p[u]) +        return self.p[u] -    def unite(self, x, y): -        px, py = self.find_set(x), self.find_set(y) -        if px == py: +    def unite(self, u, v): +        x = self.find_set(u) +        y = self.find_set(v) +        if x == y: -        if self.rank[px] > self.rank[py]: -            self.p[py] = px +        if self.rank[x] > self.rank[y]: +            self.p[y] = x -            self.p[px] = py -            if self.rank[px] == self.rank[py]: -                self.rank[py] += 1 +            self.p[x] = y +            if self.rank[x] == self.rank[y]: +                self.rank[y] += 1 + +    def is_connected(self, u, v): +        return self.find_set(u) == self.find_set(v) -    E = [] +    edges = [] +    for i in range(nedges): +        u, v, w = list(map(int, input().split())) +        edges.append((w, u, v)) +    edges.sort(key=lambda e: e[0]) +    ans = 0 -    for i in range(nedges): -        s, t, w = list(map(int, input().split())) -        E.append((w, s, t)) -    E.sort() -    ans = 0 -    for w, s, t in E: -        if uf.find_set(s) != uf.find_set(t): +    for w, u, v in edges: +        if not uf.is_connected(u, v): +            uf.unite(u, v) -            uf.unite(s, t)