#include <iostream>
#include<bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
int main()
{
int m,n;
while(~scanf("%d%d",&n,&m))
{
int ma[120][120]= {0};
int dis[120];
bool vis[120]= {0};
memset(ma,inf,sizeof(ma));
memset(dis,inf,sizeof(dis));
for(int i=1; i<=m; i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
ma[a][b]=ma[b][a]=min(ma[a][b],c);//俩个点之间可能有多个边,这里要取最小
} //忘了就可能错
dis[1]=0; //下面其实就和Dijkstra差不多,这里从1这个点开始
while(1)
{
int minn=inf,q=-1;
for(int i=1; i<=n; i++) //找出距离1最短的边
{
if(dis[i]<minn&&vis[i]==0)
{
minn=dis[i];
q=i;
}
}
if(q==-1)break; //找不到就退出循环
vis[q]=1; //标记已经加入的点
for(int i=1; i<=n; i++)
{ //这里是和Dijkstra不同的,Dijkstra是加上那个边
//这里是只要这个边,和1到这个点的距离,看哪个大
//因为这里是求最小的权值和,其实就加入ma[q][i]这个一个边
//就能把i这个点加入,权值也就多了这么一条边
//这里的标记数组还不能忘记,因为这里是只加了ma[q][i]这么一条边
//不能像Dijkstra对每个点都进行操作,已经加入的点就不能操作了,因为这里只是改变了那一条边
if(ma[q][i]<dis[i]&&vis[i]==0)
{
dis[i]=ma[q][i];
}
}
}
int sum=0;
for(int i=1; i<=n; i++)
{
sum+=dis[i];
}
printf("%d\n",sum);
}
return 0;
}