import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
//求最小生成树 用并查集
import java.util.Scanner;
public class NewOptimal {
static Scanner sc;
static List<Rute> list;
static int n,m; //n表示麦田的片数 m表示可以建立的水渠的数量
static int[] pre;
static String temp;
static String[] cmd;
static int totalcost;
public static void main(String[] args) {
sc = new Scanner(System.in);
n = sc.nextInt();
m = sc.nextInt();
list = new ArrayList<>();
sc.nextLine();
pre = new int[n+1];
for(int i=1;i<=m;i++) {
temp = sc.nextLine();
cmd = temp.split(" ");
list.add(new Rute(Integer.parseInt(cmd[0]),Integer.parseInt(cmd[1]),Integer.parseInt(cmd[2])));
pre[Integer.parseInt(cmd[0])] = Integer.parseInt(cmd[0]);
pre[Integer.parseInt(cmd[1])] = Integer.parseInt(cmd[1]);
}
Collections.sort(list, new Comparator<Rute>() {
@Override
public int compare(Rute o1, Rute o2) {
// TODO Auto-generated method stub
//按照费用从小到大排序
return o1.cost-o2.cost;
}
});
for(int i=0;i<list.size();i++) {
if(find(list.get(i).start) == find(list.get(i).end)) {
continue;
}
union(list.get(i).start,list.get(i).end);
totalcost += list.get(i).cost;
}
System.out.print(totalcost);
}
public static int find(int x) {
if(pre[x] == x)
return x;
else
return pre[x] = find(pre[x]);
}
public static void union(int x,int y) {
int start = find(x);
int end = find(y);
if(start>end) pre[start] = end;
else pre[end] = pre[start];
}
}
class Rute{
public int start;
public int end;
public int cost;
public Rute(int start, int end, int cost) {
this.start = start;
this.end = end;
this.cost = cost;
}
}