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;
map<int, int> g[1010000];
int xorsum = 0;
int n, m;
set<int> e;
int col[1010000];
vector<int> fxxk[1010000];
class Union_Find_Set {
  int *pa;
  int n;

 public:
  int Getpa(int x) { return pa[x] == x ? x : (pa[x] = Getpa(pa[x])); }
  int operator[](int x) { return Getpa(x); }
  Union_Find_Set(int _size = 1010000) {
    n = _size;
    pa = new int[_size + 2];
    Init(_size);
  }
  ~Union_Find_Set() { delete pa; }
  void Init(int n) {
    for (int i = 0; i <= n; i++) pa[i] = i;
  }
  void Merge(int x, int y) { pa[Getpa(x)] = Getpa(y); }
  bool Query(int x, int y) { return Getpa(x) == Getpa(y); }
  int Size() { return n; }
};
void add(int x, int y, int w) {
  g[x][y] = w;
  g[y][x] = w;
  xorsum ^= w;
}
vector<pair<int, pair<int, int> > > edge;
long long ans = 0;
void dfs(int pos, int c) {
  fxxk[c].push_back(pos);
  int lst = -1;
  col[pos] = c;
  while (lst <= n) {
    int t = *e.lower_bound(lst);
    lst = t + 1;
    if (t > n) break;
    if (g[pos][t]) continue;
    e.erase(t);
    dfs(t, c);
  }
}
void init() {
  int x, y, w;
  cin >> n >> m;
  for (int i = 0; i < m; i++) {
    scanf("%d%d%d", &x, &y, &w);
    add(x, y, w);
  }
}
void work() {
  int colcnt = 0;
  for (int i = 1; i <= n; i++) {
    if (col[i]) continue;
    ;
    ;
    col[i] = i;
    e.clear();
    for (int j = 1; j <= n + 1; j++)
      if (col[j] == 0) e.insert(j);
    dfs(i, i);
    colcnt++;
  }
  long long maxedgenum = (long long)n * (n - 1) / 2;
  long long remainedgenum = maxedgenum - m;
  ;
  ;
  ;
  ;
  if (n - colcnt == remainedgenum)
    ans = xorsum;
  else
    ans = 0;
  Union_Find_Set ufs(n + 1);
  ufs.Init(n + 1);
  for (int i = 1; i <= n; i++)
    for (auto p : g[i]) {
      if (p.second && p.first > i && col[p.first] != col[i]) {
        edge.push_back({p.second, {col[p.first], col[i]}});
      }
    }
  sort(edge.begin(), edge.end());
  for (auto E : edge) {
    if (ufs.Query(E.second.first, E.second.second)) continue;
    ans += E.first;
    ufs.Merge(E.second.first, E.second.second);
  }
  cout << ans << endl;
}
int main() {
  init();
  int casenum = 1;
  for (int testcase = 1; testcase <= casenum; testcase++) {
    work();
  }
  return ~~(0 ^ 0 ^ 0);
}
