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;
const int MAXN = 1000005;
int T;
bool flag[MAXN], isall, isintree[MAXN];
int n, m, fa[MAXN], du[MAXN], outdu[MAXN], tot;
long long duoutout;
vector<int> p;
long long ans, xs;
int findf(int x) { return x == fa[x] ? x : fa[x] = findf(fa[x]); }
void unions(int x, int y) {
  if (findf(x) != findf(y)) {
    fa[findf(x)] = findf(y);
  }
  return;
}
struct edges {
  int u, v;
  long long val;
  edges() {}
  edges(int _u, int _v, long long _val) {
    u = _u;
    v = _v;
    val = _val;
  }
} e[MAXN], e2[MAXN];
set<pair<int, int> > se;
void ins(pair<int, int> PI) {
  if (PI.first > PI.second) swap(PI.first, PI.second);
  se.insert(PI);
}
bool query(pair<int, int> PI) {
  if (PI.first > PI.second) swap(PI.first, PI.second);
  return se.find(PI) != se.end();
}
int main() {
  scanf("%d %d", &n, &m);
  for (int i = 1; i <= n; ++i) {
    fa[i] = i;
  }
  for (int i = 1; i <= m; ++i) {
    scanf("%d %d %lld", &e[i].u, &e[i].v, &e[i].val);
    ins(make_pair(e[i].u, e[i].v));
    xs ^= e[i].val;
    du[e[i].u]++;
    du[e[i].v]++;
  }
  for (int i = 1; i <= n; ++i) {
    if (n <= 1000 || du[i] >= n - 3) {
      flag[i] = true;
      p.push_back(i);
    }
  }
  isall = p.size() == n;
  for (int i = 1; i <= m; ++i) {
    if (flag[e[i].u] && flag[e[i].v]) e2[++tot] = e[i];
    if (flag[e[i].u] && !flag[e[i].v]) {
      e2[++tot] = e[i];
      e2[tot].v = n + 1;
      outdu[e[i].u]++;
    }
    if (!flag[e[i].u] && flag[e[i].v]) {
      e2[++tot] = e[i];
      e2[tot].u = n + 1;
      outdu[e[i].v]++;
    }
    if (!flag[e[i].u] && !flag[e[i].v]) duoutout++;
  }
  for (int i = 0; i < p.size(); ++i) {
    for (int j = i + 1; j < p.size(); ++j) {
      if (query(make_pair(p[i], p[j])) == 0) {
        e2[++tot] = edges(p[i], p[j], 0);
      }
    }
  }
  if (!isall) {
    for (int i = 0; i < p.size(); ++i) {
      if (outdu[p[i]] != n - p.size()) {
        e2[++tot] = edges(p[i], n + 1, 0);
      }
    }
  }
  sort(e2 + 1, e2 + 1 + tot,
       [](const edges &A, const edges &B) { return A.val < B.val; });
  long long need = 1;
  for (int i = 1; i <= tot; ++i) {
    if (findf(e2[i].u) != findf(e2[i].v)) {
      ans += e2[i].val;
      unions(e2[i].u, e2[i].v);
      isintree[i] = true;
    }
  }
  for (int i = 1; i <= tot; ++i) {
    if (e2[i].val == 0 && !isintree[i]) need = 0;
  }
  if (duoutout != 1LL * (n - p.size()) * (n - p.size() - 1) / 2) xs = 0;
  printf("%lld\n", ans + need * xs);
  return 0;
}
