#include <stdio.h>
#include <stdlib.h>
#define EMAX 100000
#define VMAX 10000
typedef struct graph_tag{

 int w;
 int source;
 int target;

}GRAPH;

GRAPH E[EMAX];
int P[VMAX];

void swap(int *a, int *b){
int v;
   v = *a;
   *a = *b;
   *b = v;
}
QSort(int l, int r){
int m;


 if(l < r){
 m = partition(l, r);
 QSort(l, m-2);
 QSort(m, r);
 }

}

int partition(int l, int r){
int i = l, j = 0, v;



 for(j = l; j <= r; j++){
    if(E[r].w >= E[j].w){
      swap(&(E[i].w), &(E[j].w));
      swap(&(E[i].source), &(E[j].source));
      swap(&(E[i].target), &(E[j].target));
      i++;
    }

 }

 return i;

}

void unite(int s, int t){
int ps, pt;
 ps  = find(s);
 pt = find(t);


 P[ps] = pt;

}

int find(int s){
int p;
  p = s;
 while(P[p] != p){
  p = P[p];

 }
 return p;
}

int main(){
int v, e, count, sum = 0;

 scanf("%d", &v);
 scanf("%d", &e);

 for(count = 0; count < e; count++){
  scanf("%d", &(E[count].source));
  scanf("%d", &(E[count].target));
  scanf("%d", &(E[count].w));
 }

 for(count = 0; count < v; count++)
   P[count] = count;

 QSort(0, e-1);

 for(count = 0; count < e; count++){

    if(find(E[count].source) != find(E[count].target)){
       sum += E[count].w;
       unite(E[count].source, E[count].target);
    }
 }


 printf("%d\n", sum);


 return 0;
}