#include<iostream>
#include<algorithm>
using namespace std;
#define maxSize 100
#define INF 0x3f3f3f3f
typedef struct
{
int no; //顶点编号
char info; //顶点其他信息
}VertexType;
typedef struct
{
int edges[maxSize][maxSize];
int n,e; //分别为顶点数和边数
VertexType vex[maxSize]; //存放结点信息
}MGraph;
typedef struct
{
int a,b;
int w;
}Road;
int cmp(Road r1,Road r2)
{return r1.w<r2.w;}
Road road[maxSize];
int v[maxSize];
int getRoot(int a)
{
while(a!=v[a])
a=v[a];
return a;
}
void Kruskal(MGraph g,int &sum,Road road[])
{
int i;
int N,E,a,b;
N=g.n;
E=g.e;
sum=0;
for(i=0;i<N;++i)
v[i]=i;
sort(road,road+E,cmp);
for(i=0;i<E;++i)
{
a=getRoot(road[i].a);
b=getRoot(road[i].b);
if(a!=b)
{
v[a]=b;
sum+=road[i].w;
}
}
}
/*
5 8
0 1 5 1 4 4 0 3 2 3 4 3
1 2 3 2 3 6 0 2 1 2 4 2
*/
int main()
{
MGraph g;
int n,e,sum;
cin>>n>>e;
g.n=n,g.e=e*2;
int c=0;
for(int i=0;i<e;++i)
{
int a,b,w;
cin>>a>>b>>w;
road[c].a=a,road[c].b=b,road[c++].w=w;
road[c].a=a,road[c].b=b,road[c++].w=w;
}
Kruskal(g,sum,road);
cout<<sum<<endl;
}