/*
INPUT
6
10
1 2 6
1 3 1
1 4 5
2 3 5
2 5 3
3 4 5
3 5 6
3 6 4
4 6 2
5 6 6
OUTPUT
15
*/
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int N=1e5;
struct node
{
int u,v,w;
bool operator<(const node &C)const
{
return w<C.w;//表示以w从小到大排序
}
}t[N];
int n,m;
int p[1001];
int cha(int x)
{
//return x==p[x]?p[x]:cha(p[x]);
if(x!=p[x])
{
p[x]=cha(p[x]);//一直找到祖先
}
return p[x];
}
int cl()
{
int sum=0,top=0;
for(int i=0;i<m;i++)//从第一条边开始遍历
{
int x=t[i].u;
int y=t[i].v;
x=cha(x);
y=cha(y);
if(x!=y)//假如不是同一祖宗,就连,如果是同一个祖宗也连的话,就会形成回路
{
p[x]=y;//则将其中一个点作为另一个点的祖宗,就把点与点连起来了
sum+=t[i].w;
top++;//累计连接线的条数
}
if(top==n-1) return sum;//要使n个点全部连通,至少需要n-1条边
}
return -1;//无法连通
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)//n个点,m条边
{
for(int i=1;i<=n;i++)
p[i]=i;//并查集 开始全部初始化为本身
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&t[i].u,&t[i].v,&t[i].w//分别代表起点,终点,权值
}
sort (t,t+m);//保证后面取数都是目前最小的
printf("%d\n",cl());
}
return 0;
}