#include <bits/stdc++.h>
using namespace std;
struct edge {
  int a, b;
  long long c;
  bool operator<(const edge &x) const { return c > x.c; }
};
struct dsu {
  int n;
  vector<int> par, sz, cnt;
  dsu(int N) {
    n = N;
    par.resize(n);
    sz.resize(n);
    cnt.resize(n);
    for (int i = 0; i < n; ++i) {
      par[i] = i;
      sz[i] = 1;
      cnt[i] = 0;
    }
  }
  int root(int v) {
    if (par[v] == v) return v;
    return root(par[v]);
  }
  void merge(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y) return;
    if (sz[y] > sz[x]) swap(x, y);
    par[y] = x;
    sz[x] += sz[y];
    cnt[x] += cnt[y];
    ++cnt[x];
  }
};
long long solve(int n, int m, vector<edge> &E) {
  sort(E.begin(), E.end());
  long long ans = 0;
  dsu *T = new dsu(n);
  for (int i = 0; i < m; ++i) {
    int a = E[i].a;
    int b = E[i].b;
    long long c = E[i].c;
    if (T->root(a) != T->root(b)) {
      a = T->root(a);
      b = T->root(b);
      if (T->sz[a] + T->sz[b] == T->cnt[a] + T->cnt[b]) continue;
      ans += c;
      T->merge(a, b);
    } else {
      int x = T->root(a);
      if (T->cnt[x] < T->sz[x]) {
        ans += c;
        ++T->cnt[x];
      }
    }
  }
  return ans;
}
int main() {
  cin.sync_with_stdio(false);
  int n, m;
  cin >> n >> m;
  vector<edge> E;
  for (int i = 0; i < m; ++i) {
    int a, b;
    long long c;
    cin >> a >> b >> c;
    --a, --b;
    E.push_back({a, b, c});
  }
  cout << solve(n, m, E) << '\n';
  return 0;
}
