#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
ll link[1005],s[1005];//arrays for storing the parents(or representatives) of the set and the size of each set
int find_p(int x)// finding the representative(or parent) of the set
{
while (x != link[x])
x = link[x];
return x;
}
bool same(int a, int b)// checking whether the elements belong to the same set or different set
{
return find_p(a) == find_p(b);
}
void unite(int a, int b) {// joining the two set
a = find_p(a);
b = find_p(b);
if (s[a] < s[b]) swap(a,b);
s[a] += s[b];
link[b] = a;
}
bool sortcol(const vector<ll> &v1,const vector<ll> &v2)// sorting the edges based on their weight
{
return v1[2]<v2[2];
}
int main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
ll n,v,ans=0;
cin>>v>>n;//no of vertices and edges;
vector<vector<ll>> adj(n,vector<ll>(3));// creating a matrix with n rows and 3 columns there is a edge from adj[i][0] -> adj[i][1] with a weight adj[i][2];
for(ll i=0;i<n;i++)
{
cin>>adj[i][0]>>adj[i][1]>>adj[i][2];
}
sort(adj.begin(),adj.end(),sortcol);// sorting the matrix with respect to the third column which contains the edge weight
for(ll i=0;i<v;i++)
{
link[i]=i;// Initially setting the nodes parnent to itself
s[i]=1;// initially each set caaries only onr node
}
for(ll i=0;i<n;i++)
{
if(!same(adj[i][0],adj[i][1]))// if the two nodes of an edge belongs to diiferent set
{
ans+=adj[i][2];// storing the total weight of the MST
unite(adj[i][0],adj[i][1]);// uniting the sets the two nodes belong to
cout<<adj[i][0]<<"->"<<adj[i][1]<<"\n";// printing the edges that final MST will contain
}
}
cout<<ans<<"\n";
}