#include <stdio.h>
#include <vector>
#include <queue>
using namespace std;
struct side{
    int n;
    int m;
    int l;
};
side sides[100000];
void mergesort(int l,int r){
    if(l==r)return;
    side temp;
    if(l==r-1){
        if(sides[l].l>sides[r].l){
            temp=sides[l];
            sides[l]=sides[r];
            sides[r]=temp;
        }
        return;
    }
    int mid=(l+r)/2,now=0;
    side b[r-l+1];
    mergesort(l,mid-1);
    mergesort(mid,r);
    for(int i=0;i<=r-l;i++){
        if(sides[i+l-now].l<sides[mid+now].l){
            b[i]=sides[i+l-now];
            if(i+l-now==mid-1){
                for(i++;i<=r-l;i++){
                    b[i]=sides[mid+now];
                    now++;
                }
            }
        }
        else{
            b[i]=sides[mid+now];
            now++;
            if(mid+now>r){
                for(i++;i<=r-l;i++)
                    b[i]=sides[i+l-now];
            }
        }
    }
    for(int i=0;i<=r-l;i++)
        sides[i+l]=b[i];
}
int main(){
    int n,m,a,ans=0,c=1;
    bool tree[10000];
    scanf("%d%d",&n,&m);
    if(m==0){
        printf("0\n");
        return 0;
    }
    tree[0]=true;
    for(int i=1;i<n;i++){
        tree[i]=false;
    }
    for(int i=0;i<m;i++){
        scanf("%d%d%d",&sides[i].n,&sides[i].m,&sides[i].l);
    }
    mergesort(0,m-1);
    while(c<n){
        a=0;
        while(tree[sides[a].n]==tree[sides[a].m])a++;
        ans+=sides[a].l;
        tree[sides[a].n]=tree[sides[a].m]=true;
        c++;
    }
    printf("%d\n",ans);
}
#include <algorithm>
#include <iostream>
#include <vector>

struct Edge {
	int start;
	int target;
	int weight;
};

class UnionFind {
	std::vector<int> m_nodes;

public:
	UnionFind(size_t size) : m_nodes(size) {
		for (size_t i = 0; i < size; i++)
			m_nodes[i] = i;
	}

	int find(int index) {
		int ret = m_nodes[index];
		if (ret == index) return ret;

		ret = find(ret);
		m_nodes[index] = ret;
		return ret;
	}

	void merge(int x, int y) {
		x = find(x);
		y = find(y);
		m_nodes[x] = y;
	}
};

int main()
{
	int v, e;
	std::cin >> v >> e;

	std::vector<Edge> edges;
	edges.reserve(e);

	for (int i = 0; i < e; i++) {
		Edge edge;
		std::cin >> edge.start >> edge.target >> edge.weight;
		edges.push_back(edge);
	}

	std::sort(edges.begin(), edges.end(), [](Edge& x, Edge& y) { return x.weight < y.weight; });

	UnionFind uf(v);
	uint_least64_t weight = 0;

	for (Edge& edge : edges) {
		int s = uf.find(edge.start);
		int t = uf.find(edge.target);

		if (s != t) {
			uf.merge(s, t);
			weight += edge.weight;
		}
	}

	std::cout << weight << std::endl;

	return 0;
}