//最小生成树就是选出一些边,要求所有点连通,并且权和尽量小
//最小生成树kruskal算法
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
#include<map>
#include<queue>
using namespace std;
#define maxn 210
int p[maxn];//并查集
int n;//点数
int m;//边数
struct stu
{
int u,v,w;//u为边的起点,v为边的终点,w为边的权值
}node[maxn];
int cmp(stu a,stu b)
{
return a.w<b.w;//按边的权值从小到大排序
}
int find(int x)
{
return x==p[x]?x:p[x]=find(p[x]);
}
int kruskal()
{
int ans=0;
for(int i=0;i<=n;i++)
{
p[i]=i;//初始化并查集
}
sort(node,node+m,cmp);
for(int i=0;i<m;i++)
{
int x=find(node[i].u);//找出两个端点所在集合编号
int y=find(node[i].v);
if(x!=y)//如果在不同集合,合并
{
ans+=node[i].w;
p[x]=y;//把x作为y的儿子
}
}
return ans;
}
int main()
{
int a,b,c;
scanf("%d%d",&n,&m);
memset(node,0,sizeof(node));
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&node[i].u,&node[i].v,&node[i].w);
}
printf("%d\n",kruskal());
return 0;
}