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>
using namespace std;
int f[200005];
int find(int u) { return u == f[u] ? u : f[u] = find(f[u]); }
int deg[200005];
struct Edge {
  int u, v;
  long long int w;
} e[200005];
int vis[200005];
bool merge(int u, int v) {
  int fu = find(u);
  int fv = find(v);
  if (fu != fv) {
    f[fv] = fu;
    return true;
  }
  return false;
}
int main(void) {
  int n, m;
  scanf("%d %d", &n, &m);
  unordered_set<long long int> edges;
  long long int all = 0;
  for (int i = 0; i < n; i++) f[i] = i;
  for (int i = 0; i < m; i++) {
    scanf("%d %d %lld", &e[i].u, &e[i].v, &e[i].w);
    e[i].u--;
    e[i].v--;
    edges.insert(1ll * e[i].u * n + e[i].v);
    edges.insert(1ll * e[i].v * n + e[i].u);
    all ^= e[i].w;
  }
  sort(e, e + m, [](const Edge& e1, const Edge& e2) { return e1.w < e2.w; });
  unordered_set<int> nodes;
  long long int ans = 0;
  int use_edges = 0;
  for (int i = 0; i < n; i++) nodes.insert(i);
  for (int i = 0; i < n; i++) {
    if (vis[i]) continue;
    queue<int> q;
    q.push(i);
    while (!q.empty()) {
      int x = q.front();
      q.pop();
      vis[x] = true;
      vector<int> temp;
      for (auto v : nodes) {
        if (x == v) continue;
        if (edges.find(1ll * x * n + v) == edges.end()) {
          if (merge(x, v)) {
            temp.emplace_back(v);
            use_edges++;
          }
        }
      }
      for (auto v : temp) {
        nodes.erase(v);
        q.push(v);
      }
    }
  }
  for (int i = 0; i < m; i++) {
    if (merge(e[i].u, e[i].v)) {
      ans += e[i].w;
    }
  }
  if (use_edges + m == 1ll * n * (n - 1) / 2) ans += all;
  printf("%lld\n", ans);
  return 0;
}
