# Appreciation
# Code
#include <iostream>
#include <queue>
#include <tuple>
using namespace std;
#define endl '\n'
#define MAX 100000
int P[MAX+1], R[MAX+1];
struct Road { int a, b, c; };
bool operator < (Road u, Road v);
void merge(int x, int y);
int find(int x);
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N, M;
cin >> N >> M;
priority_queue<Road> PQ;
for (int i=0; i<M; i++) {
int A, B, C;
cin >> A >> B >> C;
PQ.push({A, B, C});
}
for (int i=1; i<=N; i++) {
P[i] = i;
R[i] = 1;
}
int cnt = 0, ans = 0;
while (cnt < N-2) {
auto [a, b, c] = PQ.top();
PQ.pop();
if (find(a) != find(b)) {
merge(a, b);
cnt++;
ans += c;
}
}
cout << ans << endl;
}
bool operator < (const Road u, const Road v)
{
return make_tuple(-u.c, u.a, u.b) < make_tuple(-v.c, v.a, v.b);
}
void merge(int x, int y)
{
x = find(x);
y = find(y);
if (R[x] < R[y]) swap(x, y);
P[y] = x;
if (R[x] == R[y]) R[x]++;
}
int find(int x)
{
if (P[x] == x) return x;
return P[x] = find(P[x]);
}