#include <cstdio>
#define NMAX 200001
#define MMAX 400001
//min heap
using namespace std;
struct Muchie
{
int x,y,c;
} G[NMAX];
int n,m;
int H[MMAX];
FILE * fout=fopen("heapuri.out","w");
long long int cost;
int A[NMAX];//retin indicii muchiilor selectate in APM
int h[NMAX];//inaltimea arborelui cu radacina i
int tata[NMAX];
void citire();
//void inserare(int H[NMAX], int& n, int x);
//void afisare_heap(int H[NMAX], int n);
void creare_heap_inserare(int H[NMAX], int &n);
void combinare(int H[NMAX], int m, int i);
void creare_heap_combinare(int H[NMAX], int &n);
int extragere(int H[NMAX], int &n);
int Find(int x);
void Union(int i, int j);
void afisare();
int main()
{
int i,nr=0,mmin,cx,cy;
citire();
creare_heap_combinare(H,m);
while(nr<n-1)
{
mmin=extragere(H,m);
cx=Find(G[mmin].x);
cy=Find(G[mmin].y);
if(cx!=cy)
{
nr++;
A[nr]=mmin;
cost+=G[mmin].c;
Union(cx,cy);
}
}
fclose(fout);
return 0;
}
void afisare()
{
int i;
fprintf(fout, "%d\n", cost);
fprintf(fout, "%d\n", n-1);
for(i=1; i<n; i++)
fprintf(fout, "%d %d\n", G[A[i]].x, G[A[i]].y);
fclose(fout);
}
void inserare(int H[NMAX], int& n, int x)
//se insereaza x in heapul H care are n elemente
{
int fiu,tata;
n++;
fiu=n;
tata=fiu/2;// tata=fiu>>1;
while(tata!=0 && H[tata]>x)
{
H[fiu]=H[tata];
fiu=tata;
tata=fiu/2; // tata=fiu>>1;
}
H[fiu]=x;
}
void afisare_heap(int H[NMAX], int n)
{
int i;
for(i=1; i<=n; i++)
fprintf(fout,"%d ",H[i]);
fprintf(fout,"\n");
}
void combinare(int H[NMAX], int n, int i)
{
int x=H[i],tata,fiu;
tata=i;
fiu=i*2;
while (fiu<=n)
{
if(fiu+1<=n && G[H[fiu+1]].c<G[H[fiu]].c) fiu++;
if(G[H[fiu]].c>G[x].c)
{
H[tata]=H[fiu];
tata=fiu;
fiu=tata*2;
}
else break;
}
H[tata]=x;
}
void creare_heap_combinare(int H[NMAX], int &n)
{
FILE* fin=fopen("heapuri.in","r");
int nr,i,x;
n=0;
for(i=1;i<=n;i++) H[i]=0;
for(i=n/2; i>0; i--)
combinare(H,n,i);
}
int extragere(int H[NMAX], int &n)
{
int min=H[1];
H[1]=H[n--];
combinare(H,n,1);
return min;
}
void citire()
{
FILE* fin=fopen("apm.in","r");
// ifstream fin("apm.in");
int i;
fscanf(fin,"%d",&n,&m);
for(i=1; i<=m; i++)
{
fscanf(fin,"%d",&G[i].x,&G[i].y,&G[i].c);
//fin>>G[i].x>>G[i].y>>G[i].c;
}
}
int Find(int x)
{
int rad=x,aux;
while(tata[rad]) rad=tata[rad];
while(tata[x])
{
aux=tata[x];
tata[x]=rad;
x=aux;
}
return rad;
}
void Union(int i, int j)// j fiul al lui i,j si i radacini
{
if(h[i]<h[j]) //i devine fiul al lui j
tata[i]=j;
else
{
tata[j]=i;
if(h[i]==h[j]) h[i]++;
}
}