#include <fstream>
#include <algorithm>
#include <vector>
using namespace std;
ifstream cin("apm.in");
ofstream cout("apm.out");
struct Op{int x;int y;int c;};
vector<Op> edge,sol;
bool mycmp(Op s,Op t)
{return s.c<t.c;}
const int lim=2e5+3;
int link[lim],dim[lim];
int tata(int x)
{int cpy=x,aux;
while(x!=link[x])x=link[x];
while(cpy!=link[cpy])aux=cpy,cpy=link[cpy],link[aux]=x;
return x;}
void unite(int x,int y)
{x=tata(x);y=tata(y);
if(dim[x]<dim[y])swap(x,y);
link[y]=x;dim[x]+=dim[y];}
int main()
{int n,m,x,y,c,s=0;
cin>>n>>m;
for(int i=0;i<m;++i)
cin>>x>>y>>c,edge.push_back({x,y,c});
sort(edge.begin(),edge.end(),mycmp);
for(int i=1;i<=n;++i)link[i]=i,dim[i]=1;
for(auto t:edge)if(tata(t.x)!=tata(t.y))
unite(t.x,t.y),sol.push_back(t),s+=t.c;
cout<<s<<'\n'<<sol.size()<<'\n';
for(auto t:sol)cout<<t.x<<' '<<t.y<<'\n';
return 0;}