#include<cstdio>
#include<algorithm>
#include<cstring>
#define maxn 5005
using namespace std;
int n,m,cst[maxn];
struct node{
int to,nxt,w;
}e[400005];
int fir[maxn],cnt_e;
void Node(int u,int v,int w){
e[++cnt_e]=(node){v,fir[u],w},fir[u]=cnt_e;
e[++cnt_e]=(node){u,fir[v],w},fir[v]=cnt_e;
}
int Heap[maxn],Pos[maxn],siz;//Heap[i]为于i位置上点的编号,pos[i]为i号点在Heap中的位置 , 小根堆
void swap(int pos1,int pos2){
Heap[pos1]^=Heap[pos2],Heap[pos2]^=Heap[pos1],Heap[pos1]^=Heap[pos2];
Pos[Heap[pos1]]=pos1,Pos[Heap[pos2]]=pos2;
}
void shift(int pos){ // 往上调整
while(pos>1){
if(cst[Heap[pos]]<cst[Heap[pos>>1]]) swap(pos,pos>>1);
else return;
pos>>=1;
}
}
void put(int emt){ // 放入元素
Heap[++siz]=emt;
//printf("%d",Heap[siz]);
Pos[emt]=siz;
shift(siz);
}
void maintain(int pos){ // 向下调整
int nxt;
while((nxt=pos<<1)<=siz){
(nxt+1<=siz) && (cst[Heap[nxt]]>cst[Heap[nxt+1]]) && (nxt++);
if(cst[Heap[nxt]]>cst[Heap[pos]]) return;
swap(pos,nxt);
pos=nxt;
}
}
int get(){
int ret=Heap[1];
Heap[1]=Heap[siz--],Pos[Heap[1]]=1;
maintain(1);
return ret;
}
int prim(){
memset(cst,127/3,sizeof cst);siz=0;
for(int i=1;i<=n;i++) put(i);
cst[1]=0;
shift(Pos[1]);
int Loc,sum=0;
for(int i=1;i<=n;i++){
Loc=get();
sum+=cst[Loc];
for(int i=fir[Loc];i;i=e[i].nxt)
if(cst[e[i].to]>e[i].w){
cst[e[i].to]=e[i].w;
shift(Pos[e[i].to]);
}
}
return sum;
}
int main(){
int u,v,w;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
scanf("%d%d%d",&u,&v,&w),
Node(u,v,w);
printf("%d",prim());
}