# Original solution
#!/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()))

# Optimized solution
#!/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())))