#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;
#define M 100 //最多边数
#define N 100 //最多顶点数
typedef struct edge
{
int a;
int b;
int value;
}edge;
edge edges[M];
int final[N]; //存储父节点
int nodecount[N];
//存储该节点孩子结点的个数
bool cmp(edge a,edge b)
{
return a.value<b.value;
}
int findp(int n)
//寻找父节点
{
if(final[n]==n)
return n;
else
final[n]=findp(final[n]);
return final[n];
}
bool Union(int x,int y)
//合并
{
int rootx=findp(x);
int rooty=findp(y);
if(rootx==rooty)
return false;
else if(nodecount[rootx]<=nodecount[rooty])
{
final[rootx]=rooty;
nodecount[rooty]+=nodecount[rootx];
}
else
{
final[rooty]=rootx;
nodecount[rootx]+=nodecount[rooty];
}
return true;
}
int main ()
{
int num=0;
int n,m,sum;
int i;
while ( scanf ( "%d%d", &n, &m ) != EOF )
{
num=0;
//记录生成树中的边的数目
sum=0;
for(i=1;i<=m;i++)
{
scanf("%d%d%d",&edges[i].a,&edges[i].b,&edges[i].value);
}
for(i=1;i<=n;i++)
//初始化
{
final[i]=i;
nodecount[i]=1;
}
sort(edges+1,edges+m+1,cmp);
//排序
for(i=1;i<=m;i++)
//遍历所有的边
{
if(Union(edges[i].a,edges[i].b))
//合并
{
num++;//记录最小生成树的边数
sum+=edges[i].value;
printf("%d->%d
",edges[i].a,edges[i].b);
}
if(num==n-1)
//找到了最小生成树
break;
}
printf("%d
",sum);
}
return 0;
}