#include <bits/stdc++.h>
using namespace std;
const int maxn = 5e3 + 5;
const int maxm = 5e5 + 5;
namespace MST {
struct edge {
int u, v, w;
}E[maxm];
int n, m;
int tot = 0;
void addedge(int u, int v, int w) {
E[++tot].u = u;
E[tot].v = v;
E[tot].w = w;
}
int fa[maxn];
void init() {
for (int i = 1; i <= n; i++) {
fa[i] = i;
}
}
int find(int x) {
return x == fa[x] ? x : fa[x] = find(fa[x]);
}
int Union(int u, int v) {
int fu = find(u), fv = find(v);
fa[fu] = fv;
}
int better(int i, int j) {
if (j == 0)return 1;
if (E[i].w != E[j].w) {
return E[i].w < E[j].w;
}
else return i < j;
}
int best[maxn];
int used[maxm];
int solve() {
int sum = 0, merge = 0;
bool isupdate = 1;
while (isupdate) {
isupdate = 0;
memset(best, 0, sizeof best);
for (int i = 1; i <= tot; i++) {//找到每个连通块的最短出边
if (used[i])continue;
int fu = find(E[i].u), fv = find(E[i].v);
if (fu == fv)continue;
if (better(i, best[fu]))best[fu] = i;
if (better(i, best[fv]))best[fv] = i;
}
for (int u = 1; u <= n; u++) {
if (best[u] && !used[best[u]]) {
isupdate = 1;
sum += E[best[u]].w;
merge++;
Union(E[best[u]].u, E[best[u]].v);
used[best[u]] = 1;
}
}
}
return merge == n - 1 ? sum : -1;
}
}
using namespace MST;
int main() {
cin >> n >> m;
for (int i = 1; i <= m; i++) {
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
addedge(u, v, w);
}
init();
int ans=solve();
if (ans != -1) {
cout << ans << endl;
}
else {
cout << "orz
";
}
}