#define MAXN 1000
#define MAXM 1000000
using namespace std;
struct edge{
int x;
int y;
int a;
};
int father[MAXN+1];
edge edgetype[MAXM];
bool used[MAXN+1];
int n,m;
int cmp(const void *a,const void *b){
edge ta=*(edge *)a;
edge tb=*(edge *)b;
return ta.a-tb.a;
}
void initialize(){
scanf("%d %d",&n,&m);
for (int i=1;i<=n;i++){
father[i]=i;
used[i]=false;
}
for (int i=0;i<m;i++)
scanf("%d %d %d",&edgetype[i].x,&edgetype[i].y,&edgetype[i].a);
qsort(edgetype,m,sizeof(edgetype[0]),cmp);
}
int getfather(int v){
if (father[v]==v) return v;
return father[v]=getfather(father[v]);
}
void judge(int x,int y){
int fx=getfather(x);
int fy=getfather(y);
if (fx!=fy) father[fx]=fy;
}
bool same(int x,int y){
int fx=getfather(x);
int fy=getfather(y);
return fx==fy;
}
int kruscal(void){
int x=1;
int count=0,index=0;
while (x<n&&index<m){
if (!same(edgetype[index].x,edgetype[index].y)){
judge(edgetype[index].x,edgetype[index].y);
count+=edgetype[index].a;
++x;
}
index++;
}
return count;
}
int main (void){
initialize();
printf("%d",kruscal());
//while (1);
return 0;
}
/*
8 13
1 7 1
1 2 9
1 6 9
2 8 2
2 3 9
3 8 3
3 4 9
4 8 4
4 5 9
5 7 5
5 6 9
6 7 6
7 8 7
------
28
*/