2 0
 6 8
1 4 1
1 5 1
1 6 1
2 4 1
2 5 1
2 6 1
3 5 1
3 6 1
 6 12
1 3 8763000
1 4 8763000
1 5 8763000
1 6 8763000
2 3 8763000
2 4 1
2 5 8763000
2 6 1
3 5 8763000
3 6 8763000
4 5 8763000
4 6 2

0
 0
 8763002

#include <bits/stdc++.h>
template <typename... Args>
void pr(Args... args) {}
using namespace std;
using ll = long long;
const int MM = 2e5 + 5;
int n, m;
int sum;
ll ans;
struct Dsu {
  int par[MM];
  void init() { iota(par, par + MM, 0); }
  int find(int x) {
    while (x != par[x]) x = par[x], par[x] = par[par[x]];
    return x;
  }
  bool connected(int a, int b) { return find(a) == find(b); }
  void merge(int a, int b) { par[find(a)] = find(b); }
} d1, d2;
vector<array<int, 3>> old, edges;
set<pair<int, int>> st;
int deg[MM];
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cin >> n >> m;
  for (int i = 0, a, b, c; i < m; i++) {
    cin >> a >> b >> c;
    sum ^= c;
    old.push_back({c, a, b});
    st.insert({a, b});
    st.insert({b, a});
    deg[a]++, deg[b]++;
  }
  d2.init();
  sort((old).begin(), (old).end());
  for (auto [c, a, b] : old) {
    a = d2.find(a), b = d2.find(b);
    if (a != b) {
      d2.merge(a, b);
      edges.push_back({c, a, b});
    }
  }
  if ((ll)n * n <= 4 * m) {
    d1.init();
    for (int i = 1; i <= n; i++) {
      for (int j = 1; j < i; j++) {
        if (!st.count({i, j})) {
          edges.push_back({0, i, j});
          d1.merge(i, j);
        }
      }
    }
    d2.init();
    sort((edges).begin(), (edges).end());
    for (auto [c, a, b] : edges) {
      if (!d2.connected(a, b)) {
        d2.merge(a, b);
        ans += c;
      } else {
        sum = min(sum, c);
      }
    }
    cout << ans + sum << '\n';
    return 0;
  }
  for (int i = 1; i <= n; i++) {
    if (deg[i] < n - 1) {
      edges.push_back({0, 0, i});
    }
  }
  d2.init();
  sort((edges).begin(), (edges).end());
  for (auto [c, a, b] : edges) {
    a = d2.find(a), b = d2.find(b);
    if (a != b) {
      d2.merge(a, b);
      ans += c;
    }
  }
  cout << ans << '\n';
}
