import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
import java.lang.Math;
class point {
int index=-2;
int key;
int value;
int cap;
ArrayList<Integer> list = new ArrayList<Integer>(); //хранит массив roads,связанных с этой вершиной
}
class rib {
int from;
int to;
int distance;
}
class PriorityQueue{
int count;
point[] heap;
PriorityQueue(int n){
int i;
this.heap = new point[n];
for(i = 0; i < n; i++){
this.heap[i] = new point();
}
this.count = 0;
}
public void insert(point u){
int i = this.count++;
point temp;
this.heap[i] = u;
while (i > 0 && this.heap[(i-1)/2].key > this.heap[i].key){
temp = this.heap[(i-1)/2];
this.heap[(i-1)/2] = this.heap[i];
this.heap[i] = temp;
this.heap[i].index=i;
i = (i-1)/2;
}
this.heap[i].index=i;
}
public point ExtractMin(){
point temp;
temp = this.heap[0];
this.count--;
if(this.count > 0){
this.heap[0] = this.heap[this.count];
this.heap[0].index=0;
heapify(this.heap, 0);
}
return temp;
}
public void heapify(point[] heap, int i){
int l, r, j;
point temp;
for(;;){
l = 2*i+1;
r = l+1;
j = i;
if(l < this.count && (heap[l].key < heap[j].key)) j = l;
if(r < this.count && (heap[r].key < heap[j].key)) j = r;
if(i == j) break;
temp = heap[i];
heap[i] = heap[j];
heap[j] = temp;
this.heap[i].index=i;
this.heap[j].index=j;
i = j;
}
}
public void increaseKey(point x, int y){
int i = x.index;
point temp;
x.key=y;
while(i > 0 && this.heap[(i-1)/2].key > y){
temp = this.heap[(i-1)/2];
this.heap[(i-1)/2] = this.heap[i];
this.heap[i] = temp;
this.heap[i].index=i;
i = (i-1)/2;
}
x.index=i;
}
}
public class Prim {
public static void main(String[] arg) {
Scanner sc = new Scanner(System.in);
int i=0,j=0,n=sc.nextInt(),m=sc.nextInt(),first,second,third,distance=0;
point [] graph=new point[n];
rib [] roads=new rib[m];
PriorityQueue q = new PriorityQueue(m);
for(i=0;i<n;i++)
{
graph[i]=new point();
}
for(i=0;i<m;i++)
{
roads[i]=new rib();
roads[i].from=sc.nextInt();
roads[i].to=sc.nextInt();
roads[i].distance=sc.nextInt();
graph[roads[i].from].cap++;
graph[roads[i].from].list.add(i);
graph[roads[i].to].cap++;
graph[roads[i].to].list.add(i);
}
point temp1;
point temp2;
//добавляем нулевую вершину по алгоритму Прима
for(i=0;i<graph[0].list.size();i++)
{
graph[0].key=0;
graph[0].index=-2;
q.insert(graph[0]);
}
int count=0;
while(q.count!=0)
{
temp1=q.ExtractMin();
distance+=temp1.key;
count++;
temp1.index=-1;
for(i=0;i<temp1.cap;i++)
{
//обозначение второй вершины
if(graph[roads[temp1.list.get(i)].to].index!=-1)
temp2=graph[roads[temp1.list.get(i)].to];
else
temp2=graph[roads[temp1.list.get(i)].from];
//обновляем расстояния после соединения точки и позицию точек в пирамиде
if(temp2.index==-2)
{
temp2.key=roads[temp1.list.get(i)].distance;
q.insert(temp2);
}
else if(temp2.key>roads[temp1.list.get(i)].distance)
{
//temp2.key=roads[temp1.list.get(i)].distance;
q.increaseKey(temp2,roads[temp1.list.get(i)].distance);
}
}
}
System.out.println(distance);
}
}