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>
#pragma GCC optimize("O3", "unroll-loops")
#pragma GCC target("sse4.2")
using namespace std;
mt19937 gen(chrono::high_resolution_clock::now().time_since_epoch().count());
void flush() { cout << flush; }
void flushln() { cout << endl; }
void println() { cout << '\n'; }
template <class T>
void print(const T &x) {
  cout << x;
}
template <class T>
void read(T &x) {
  cin >> x;
}
template <class T, class... U>
void read(T &x, U &...u) {
  read(x);
  read(u...);
}
template <class T, class... U>
void print(const T &x, const U &...u) {
  print(x);
  print(u...);
}
template <class T, class... U>
void println(const T &x, const U &...u) {
  print(x);
  println(u...);
}
template <class T, class U>
inline bool chmin(T &x, const U &y) {
  return y < x ? x = y, 1 : 0;
}
template <class T, class U>
inline bool chmax(T &x, const U &y) {
  return y > x ? x = y, 1 : 0;
}
template <class T>
inline void sort(T &a) {
  sort((a).begin(), (a).end());
}
template <class T>
inline void rsort(T &a) {
  sort((a).rbegin(), (a).rend());
}
template <class T>
inline void reverse(T &a) {
  reverse((a).begin(), (a).end());
}
template <class T, class U>
inline istream &operator>>(istream &str, pair<T, U> &p) {
  return str >> p.first >> p.second;
}
template <class T>
inline istream &operator>>(istream &str, vector<T> &a) {
  for (auto &i : a) str >> i;
  return str;
}
template <class T>
inline T sorted(T a) {
  sort(a);
  return a;
}
struct dsu {
  struct rnk {
    int val = 1;
    int get() const { return val; }
    void add(const rnk &r) { val += r.val; }
  };
  vector<int> p;
  vector<rnk> r;
  int comp = 0, edge = 0;
  dsu() {}
  bool empty() const { return p.empty(); }
  dsu(int n) {
    p = vector<int>(n);
    r = vector<rnk>(n);
    for (int i = 0; i < n; ++i) p[i] = i;
    comp = n;
  }
  int getp(int v) { return v == p[v] ? v : p[v] = getp(p[v]); }
  bool check(int a, int b) { return getp(a) == getp(b); }
  bool unite(int a, int b) {
    a = getp(a);
    b = getp(b);
    if (a == b) return false;
    ++edge;
    --comp;
    if (r[a].get() > r[b].get()) swap(a, b);
    p[a] = b;
    r[b].add(r[a]);
    return true;
  }
};
vector<vector<pair<int, int>>> G;
vector<bool> used;
vector<pair<int, pair<int, int>>> edge;
vector<int> vert;
void dfs(int v) {
  if (used[v]) return;
  used[v] = true;
  vert.push_back(v);
  for (auto i : G[v]) {
    dfs(i.first);
    edge.push_back({i.second, {v, i.first}});
  }
}
int clique = 0;
int comp = 0;
void generate(int v) {
  ++comp;
  edge.clear();
  dfs(v);
  if (signed((edge).size()) ==
      signed((vert).size()) * (long long)(signed((vert).size()) - 1)) {
    ++clique;
  }
  sort(edge);
}
set<int> st;
vector<pair<int, int>> tree;
void dfsadd(int v) {
  st.erase(v);
  set<int> cant;
  for (auto i : G[v]) cant.insert(i.first);
  int was = -1;
  while (true) {
    auto it = st.upper_bound(was);
    if (it == st.end()) break;
    was = *it;
    if (cant.count(was)) continue;
    dfsadd(was);
    tree.push_back({was, v});
    tree.push_back({v, was});
  }
}
signed main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cout << fixed << setprecision(12);
  int n, m;
  read(n, m);
  int x = 0;
  int mnw = 1000000007;
  G.resize(n);
  for (int i = 0; i < m; ++i) {
    int u, v, w;
    read(u, v, w);
    --u, --v;
    G[u].push_back({v, w});
    G[v].push_back({u, w});
    chmin(mnw, w);
    x ^= w;
  }
  vector<int> sizes;
  used = vector<bool>(n);
  for (int i = 0; i < n; ++i) {
    if (!used[i]) {
      generate(i);
      sizes.push_back(signed((vert).size()));
    }
  }
  if (comp >= 2) {
    if (comp == 2) {
      if (min(sizes[0], sizes[1]) == 1) {
        if (clique == 2) {
          println(min(mnw, x));
          return 0;
        }
      }
    }
    println(0);
    return 0;
  }
  for (int i = 0; i < n; ++i) st.insert(i);
  while (signed((st).size())) {
    dfsadd(*st.begin());
  }
  0;
  0;
  0;
  long long add = 0;
  if (signed((edge).size()) + signed((tree).size()) == n * (long long)(n - 1)) {
    dsu d(n);
    for (auto i : tree) d.unite(i.first, i.second);
    int mnw = 1000000007;
    for (auto i : edge)
      if (d.check(i.second.first, i.second.second)) chmin(mnw, i.first);
    add = min(x, mnw);
  }
  dsu d(n);
  for (auto i : tree) d.unite(i.first, i.second);
  sort(edge);
  long long ans = 0;
  for (auto i : edge)
    if (d.unite(i.second.first, i.second.second)) {
      ans += i.first;
    }
  println(ans + add);
  return 0;
}
