#include <iostream>
#include <vector>
#include <queue>
#include <functional>
#include <string.h>

using namespace std;
static const int INF = 1e9;
static const int SIZE = 10001;
typedef pair<int, int> P;
struct edge
{
	int to;
	int cost;
};

bool isUsed[SIZE];
vector<edge> G[SIZE];

void solve()
{
	int V, E;
	cin >> V >> E;
	for (int i = 0; i < E; ++i)
	{
		int from, to, cost;
		cin >> from >> to >> cost;
		edge e1, e2;
		e1.to = to;
		e1.cost = cost;
		e2.to = from;
		e2.cost = cost;
		G[from].push_back(e1);
		G[to].push_back(e2);
	}
	memset(isUsed, 0, sizeof(isUsed));
	int ans = 0;
	priority_queue<P, vector<P>, greater<P> > pque;
	pque.push(P(0, 0));
	while (!pque.empty())
	{
		P p = pque.top();
		pque.pop();
		int v = p.second;
		if (isUsed[v])
		{
			continue;
		}
		isUsed[v] = true;
		ans += p.first;
		for (int i = 0; i < G[v].size(); ++i)
		{
			edge e = G[v][i];
			pque.push(P(e.cost, e.to));
		}
	}
	cout << ans << endl;
}

int main()
{
	solve();
	return(0);
}
#include <bits/stdc++.h>

using namespace std;

#define fi first
#define se second

typedef pair<int,int> ii;
typedef pair<int,ii> iii;

class UnionFindDS{
private:
	vector<int> p, h, sz;	// parent, height (rank), size
	int num;
public:
	UnionFindDS(int N){
		p.assign(N,0); for (int i=0; i<N; i++) p[i] = i;
		h.assign(N,0); sz.assign(N,1);
		num = N;
	}
	int numSets(){ return num; }
	int findSet(int i){ return p[i] == i ? i : p[i] = findSet(p[i]); }
	int sizeSet(int i){ return sz[findSet(i)]; }
	bool isSameSet(int i, int j){ return findSet(i) == findSet(j); }
	void unionSet(int i, int j){
		int x = findSet(i), y = findSet(j);
		if (x == y) return;
		
		num--;
		if (h[x] > h[y]){ p[y] = x; sz[x] += sz[y]; }
		else			{ p[x] = y; sz[y] += sz[x]; h[y] += (h[y] == h[x]); }
	}
};

priority_queue< iii,vector<iii>,greater<iii> > pq;

int main(){

	ios_base::sync_with_stdio(0);

	int V, E;
	cin >> V >> E;

	int u, v, w;
	for (int i=0; i<E; i++){
		cin >> u >> v >> w;

		pq.push(iii(w,ii(u,v)));
	}

	UnionFindDS uf(V);

	int sum = 0;
	while (uf.numSets() > 1 && !pq.empty()){
		iii front = pq.top(); pq.pop();

		u = front.se.fi; v = front.se.se; w = front.fi;

		if (uf.isSameSet(u,v)) continue;

		uf.unionSet(u,v); sum += w;
	}

	if (uf.numSets() > 1) cout << -1  << endl;		// impossible to form spanning tree
	else 				  cout << sum << endl;

	return 0;
}