#!/usr/bin/env python

# -*- coding: utf-8 -*-



"""

input:

6 9

0 1 1

0 2 3

1 2 1

1 3 7

2 4 1

1 4 3

3 4 1

3 5 1

4 5 6



output:

5

"""



import sys

from operator import attrgetter





class Edge(object):

    __slots__ = ('source', 'target', 'weight')



    def __init__(self):

        self.weight = float('inf')

        self.source, self.target = None, None





class UnionFind(object):

    __slots__ = ('size', 'tree_height_rank_list', 'ancestor_list')



    def __init__(self, size):

        self.size = int(size)

        self.tree_height_rank_list = [0] * self.size

        self.ancestor_list = [i for i in range(self.size)]



    def _find(self, x):

        if x != self.ancestor_list[x]:

            self.ancestor_list[x] = self._find(self.ancestor_list[x])

        return self.ancestor_list[x]



    def same(self, x, y):

        return self._find(x) == self._find(y)



    def _link(self, x, y):

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

            self.ancestor_list[y] = x

        else:

            self.ancestor_list[x] = y

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

                self.tree_height_rank_list[y] += 1



    def union(self, x, y):

        self._link(self._find(x), self._find(y))





def generate_edge_table(v_table):

    for index, each in enumerate(v_table):

        source, target, weight = list(map(int, each))

        init_edge_table[index].source = source

        init_edge_table[index].target = target

        init_edge_table[index].weight = weight



    return init_edge_table





def graph_Kruskal():

    total_cost = 0

    edge_table.sort(key=attrgetter('weight'))

    # MST--> E = V + 1

    union_find_case = UnionFind(size=vertices + 1)

    for edge in edge_table:

        if not union_find_case.same(edge.source, edge.target):

            total_cost += edge.weight

            union_find_case.union(edge.source, edge.target)



    return total_cost





if __name__ == '__main__':

    _input = sys.stdin.readlines()

    vertices, edges = list(map(int, _input[0].split()))

    v_info = [x.split() for x in _input[1:]]



    init_edge_table = [Edge() for _ in range(edges)]

    edge_table = generate_edge_table(v_info)

    print((graph_Kruskal()))
#!/usr/bin/env python

# -*- coding: utf-8 -*-



"""

input:

6 9

0 1 1

0 2 3

1 2 1

1 3 7

2 4 1

1 4 3

3 4 1

3 5 1

4 5 6



output:

5

"""



import sys

import heapq as hp



WHITE, GRAY, BLACK = 0, 1, 2





def generate_adj_table(v_table):

    for each in v_table:

        v_from, v_to, edge_weight = list(map(int, each))

        init_adj_table[v_from][v_to] = edge_weight

        init_adj_table[v_to][v_from] = edge_weight



    return init_adj_table





def prim_span_tree():

    distance[init_v] = 0

    distance_heap = []

    hp.heappush(distance_heap, (0, init_v))



    while distance_heap:

        current_vertex = hp.heappop(distance_heap)[1]



        color[current_vertex] = BLACK



        for adj_vertex, adj_weight in list(adj_table[current_vertex].items()):

            if color[adj_vertex] is not BLACK:

                if adj_weight < distance[adj_vertex]:

                    distance[adj_vertex] = adj_weight

                    parent[adj_vertex] = current_vertex

                    color[adj_vertex] = GRAY

                    hp.heappush(distance_heap, (adj_weight, adj_vertex))



    return distance





if __name__ == '__main__':

    _input = sys.stdin.readlines()

    vertices, edges = list(map(int, _input[0].split()))

    v_info = [x.split() for x in _input[1:]]



    parent = [-1] * vertices

    distance = [float('inf')] * vertices

    color = [WHITE] * vertices

    init_v = 0



    init_adj_table = tuple(dict() for _ in range(vertices))

    adj_table = generate_adj_table(v_info)

    print((sum(prim_span_tree())))
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
input:
6 9
0 1 1
0 2 3
1 2 1
1 3 7
2 4 1
1 4 3
3 4 1
3 5 1
4 5 6
output:
5
"""
import sys
from operator import attrgetter


class Edge(object):
    __slots__ = ("source", "target", "weight")

    def __init__(self):
        self.weight = float("inf")
        self.source, self.target = None, None


class UnionFind(object):
    __slots__ = ("size", "tree_height_rank_list", "ancestor_list")

    def __init__(self, size):
        self.size = int(size)
        self.tree_height_rank_list = [0] * self.size
        self.ancestor_list = [i for i in range(self.size)]

    def _find(self, x):
        if x != self.ancestor_list[x]:
            self.ancestor_list[x] = self._find(self.ancestor_list[x])
        return self.ancestor_list[x]

    def same(self, x, y):
        return self._find(x) == self._find(y)

    def _link(self, x, y):
        if self.tree_height_rank_list[x] > self.tree_height_rank_list[y]:
            self.ancestor_list[y] = x
        else:
            self.ancestor_list[x] = y
            if self.tree_height_rank_list[x] == self.tree_height_rank_list[y]:
                self.tree_height_rank_list[y] += 1

    def union(self, x, y):
        self._link(self._find(x), self._find(y))


def generate_edge_table(v_table):
    for index, each in enumerate(v_table):
        source, target, weight = list(map(int, each))
        init_edge_table[index].source = source
        init_edge_table[index].target = target
        init_edge_table[index].weight = weight
    return init_edge_table


def graph_Kruskal():
    total_cost = 0
    edge_table.sort(key=attrgetter("weight"))
    # MST--> E = V + 1
    union_find_case = UnionFind(size=vertices + 1)
    for edge in edge_table:
        if not union_find_case.same(edge.source, edge.target):
            total_cost += edge.weight
            union_find_case.union(edge.source, edge.target)
    return total_cost


if __name__ == "__main__":
    _input = sys.stdin.readlines()
    vertices, edges = list(map(int, _input[0].split()))
    v_info = [x.split() for x in _input[1:]]
    init_edge_table = [Edge() for _ in range(edges)]
    edge_table = generate_edge_table(v_info)
    print((graph_Kruskal()))

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
input:
6 9
0 1 1
0 2 3
1 2 1
1 3 7
2 4 1
1 4 3
3 4 1
3 5 1
4 5 6
output:
5
"""
import sys
import heapq as hp

WHITE, GRAY, BLACK = 0, 1, 2


def generate_adj_table(v_table):
    for each in v_table:
        v_from, v_to, edge_weight = list(map(int, each))
        init_adj_table[v_from][v_to] = edge_weight
        init_adj_table[v_to][v_from] = edge_weight
    return init_adj_table


def prim_span_tree():
    distance[init_v] = 0
    distance_heap = []
    hp.heappush(distance_heap, (0, init_v))
    while distance_heap:
        current_vertex = hp.heappop(distance_heap)[1]
        color[current_vertex] = BLACK
        for adj_vertex, adj_weight in list(adj_table[current_vertex].items()):
            if color[adj_vertex] is not BLACK:
                if adj_weight < distance[adj_vertex]:
                    distance[adj_vertex] = adj_weight
                    parent[adj_vertex] = current_vertex
                    color[adj_vertex] = GRAY
                    hp.heappush(distance_heap, (adj_weight, adj_vertex))
    return distance


if __name__ == "__main__":
    _input = sys.stdin.readlines()
    vertices, edges = list(map(int, _input[0].split()))
    v_info = [x.split() for x in _input[1:]]
    parent = [-1] * vertices
    distance = [float("inf")] * vertices
    color = [WHITE] * vertices
    init_v = 0
    init_adj_table = tuple(dict() for _ in range(vertices))
    adj_table = generate_adj_table(v_info)
    print((sum(prim_span_tree())))

-from operator import attrgetter +import heapq as hp + +WHITE, GRAY, BLACK = 0, 1, 2 -class Edge(object): -    __slots__ = ("source", "target", "weight") - -    def __init__(self): -        self.weight = float("inf") -        self.source, self.target = None, None +def generate_adj_table(v_table): +    for each in v_table: +        v_from, v_to, edge_weight = list(map(int, each)) +        init_adj_table[v_from][v_to] = edge_weight +        init_adj_table[v_to][v_from] = edge_weight +    return init_adj_table -class UnionFind(object): -    __slots__ = ("size", "tree_height_rank_list", "ancestor_list") - -    def __init__(self, size): -        self.size = int(size) -        self.tree_height_rank_list = [0] * self.size -        self.ancestor_list = [i for i in range(self.size)] - -    def _find(self, x): -        if x != self.ancestor_list[x]: -            self.ancestor_list[x] = self._find(self.ancestor_list[x]) -        return self.ancestor_list[x] - -    def same(self, x, y): -        return self._find(x) == self._find(y) - -    def _link(self, x, y): -        if self.tree_height_rank_list[x] > self.tree_height_rank_list[y]: -            self.ancestor_list[y] = x -        else: -            self.ancestor_list[x] = y -            if self.tree_height_rank_list[x] == self.tree_height_rank_list[y]: -                self.tree_height_rank_list[y] += 1 - -    def union(self, x, y): -        self._link(self._find(x), self._find(y)) - - -def generate_edge_table(v_table): -    for index, each in enumerate(v_table): -        source, target, weight = list(map(int, each)) -        init_edge_table[index].source = source -        init_edge_table[index].target = target -        init_edge_table[index].weight = weight -    return init_edge_table - - -def graph_Kruskal(): -    total_cost = 0 -    edge_table.sort(key=attrgetter("weight")) -    # MST--> E = V + 1 -    union_find_case = UnionFind(size=vertices + 1) -    for edge in edge_table: -        if not union_find_case.same(edge.source, edge.target): -            total_cost += edge.weight -            union_find_case.union(edge.source, edge.target) -    return total_cost +def prim_span_tree(): +    distance[init_v] = 0 +    distance_heap = [] +    hp.heappush(distance_heap, (0, init_v)) +    while distance_heap: +        current_vertex = hp.heappop(distance_heap)[1] +        color[current_vertex] = BLACK +        for adj_vertex, adj_weight in list(adj_table[current_vertex].items()): +            if color[adj_vertex] is not BLACK: +                if adj_weight < distance[adj_vertex]: +                    distance[adj_vertex] = adj_weight +                    parent[adj_vertex] = current_vertex +                    color[adj_vertex] = GRAY +                    hp.heappush(distance_heap, (adj_weight, adj_vertex)) +    return distance -    init_edge_table = [Edge() for _ in range(edges)] -    edge_table = generate_edge_table(v_info) -    print((graph_Kruskal())) +    parent = [-1] * vertices +    distance = [float("inf")] * vertices +    color = [WHITE] * vertices +    init_v = 0 +    init_adj_table = tuple(dict() for _ in range(vertices)) +    adj_table = generate_adj_table(v_info) +    print((sum(prim_span_tree())))