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 n, m;
const int MAXN = 2e5 + 10;
vector<pair<int, int> > gr[MAXN];
int cc[MAXN];
int cc_count = 0;
int t[MAXN];
int r[MAXN];
int root(int x) { return x == t[x] ? x : t[x] = root(t[x]); }
void unite(int x, int y) {
  if ((x = root(x)) == (y = root(y))) return;
  if (r[x] < r[y]) swap(x, y);
  r[x] += r[y];
  t[y] = x;
  return;
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  cin >> n >> m;
  int extra = 0;
  for (int i = 1; i <= m; ++i) {
    int u, v, w;
    cin >> u >> v >> w;
    extra ^= w;
    gr[u].emplace_back(v, w);
    gr[v].emplace_back(u, w);
  }
  for (int i = 1; i <= n; ++i) {
    sort((gr[i]).begin(), (gr[i]).end());
  }
  set<int> available;
  for (int i = 1; i <= n; ++i) {
    available.insert(i);
  }
  while (available.size()) {
    ++cc_count;
    queue<int> q;
    q.push(*available.begin());
    available.erase(*available.begin());
    while (q.size()) {
      int node = q.front();
      q.pop();
      cc[node] = cc_count;
      gr[node].emplace_back(n + 1, 0);
      for (int i = 0; i < gr[node].size() - 1; ++i) {
        while (available.size()) {
          auto p = available.lower_bound(gr[node][i].first + 1);
          if (p != available.end() && *p < gr[node][i + 1].first) {
            q.push(*p);
            available.erase(*p);
          } else
            break;
        }
      }
      while (available.size() && *available.begin() < gr[node][0].first) {
        q.push(*available.begin());
        available.erase(available.begin());
      }
      gr[node].pop_back();
    }
  }
  long long ans = 0;
  vector<pair<int, pair<int, int> > > edges;
  for (int i = 1; i <= n; ++i) {
    for (auto &x : gr[i]) {
      if (cc[i] == cc[x.first]) {
        extra = min(extra, x.second);
      } else {
        if (cc[i] < cc[x.first]) {
          edges.emplace_back(x.second, make_pair(cc[i], cc[x.first]));
        }
      }
    }
  }
  int zeros = n - cc_count;
  if (zeros + m != 1ll * n * (n - 1) / 2) extra = 0;
  sort((edges).begin(), (edges).end());
  for (int i = 1; i <= cc_count; ++i) {
    t[i] = i;
    r[i] = 1;
  }
  for (auto &x : edges) {
    if (root(x.second.first) != root(x.second.second)) {
      ans += x.first;
      unite(x.second.first, x.second.second);
    } else {
    }
  }
  cout << ans + extra << '\n';
  return 0;
}
