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>
#include <ext/pb_ds/assoc_container.hpp>

#define endl "\n" 
using namespace std;
using ll = long long;
using ld = long double;
using pii = pair<int, int>;

template<typename T>
using ordered_set = __gnu_pbds::tree<T, __gnu_pbds::null_type, less<T>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update>;

template <typename T>
void vout(T s){ cout << s << endl; exit(0); }

constexpr int N = 1e5 + 5;
constexpr int M = 100 + 1;
constexpr int mod = 998244353;

int n, m, cur = 0;
vector<vector<int>> gr;
vector<tuple<int, int, int>> ed;
vector<int> deg;
set<int> unused;
set<int> comp;
vector<int> col;
bool cycle = 0;

struct dsu {
  vector<int> p, s;
  ll sum = 0;
  int cnt;

  dsu(int n) : cnt(n), p(n), s(n, 1) {
    iota(p.begin(), p.end(), 0);
  }

  int get(int x) {
    return p[x] == x ? x : p[x] = get(p[x]);
  }

  void uni(int a, int b, int c) {
    a = get(a);
    b = get(b);
    if (a == b)
      return;
    if (s[a] < s[b])
      swap(a, b);
    p[b] = a;
    s[a] += s[b];
    sum += c;
    cnt--;
  }
};

void dfs(int v, int par = -1) {
  comp.insert(v);
  unused.erase(v);
  col[v] = cur;
  gr[v].push_back(-1);
  gr[v].push_back(n);
  sort(gr[v].begin(), gr[v].end());
  for (int i = 1; i < gr[v].size(); i++) {
    if (gr[v][i - 1] + 1 < gr[v][i]) {
      if (!cycle) {
        auto it = comp.upper_bound(gr[v][i - 1]);
        while(it != comp.end() && (*it == v || *it == par))
          it++;
        if (it != comp.end() && *it < gr[v][i])
          cycle = 1;
      }
      while(1) {
        auto it = unused.upper_bound(gr[v][i - 1]);
        if (it == unused.end() || *it >= gr[v][i])
          break;
        dfs(*it, v);
      }
    }
  }
}

void solve() {
  cin >> n >> m;
  col.resize(n);
  gr.resize(n);
  for (int i = 0; i < n; i++)
    unused.insert(i);
  int sum = 0;
  for (int i = 0, a, b, c; i < m; i++) {
    cin >> a >> b >> c;
    a--;
    b--;
    gr[a].push_back(b);
    gr[b].push_back(a);
    ed.emplace_back(a, b, c);
    sum ^= c;
  }
  for (int i = 0; i < n; i++) {
    if (unused.count(i)) {
      comp.clear();
      ++cur;
      dfs(i);
    }
  }
  sort(ed.begin(), ed.end(), [](const auto& a, const auto& b) {
    return get<2>(a) < get<2>(b);
  });
  dsu d(cur + 1);
  int w = 1e9;
  for (const auto& [a, b, c]: ed) {
    if (col[a] == col[b]) {
      w = c;
      break;
    }  
  }
  for (const auto& [a, b, c]: ed) {
    d.uni(col[a], col[b], c);
  }
  // case when can't make all other edges zero
  if (!cycle) {
    cout << d.sum + min(sum, w) << endl;
  } else 
    cout << d.sum;
}

int main() {
  //freopen("zhopa.txt", "r", stdin);
  //freopen("logins.txt", "w", stdout);
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  // int tests;
  // cin >> tests;
  // while(tests--)
  // auto start = chrono::high_resolution_clock::now();
    solve();
  // auto end = chrono::high_resolution_clock::now();
  // cout << endl << (chrono::duration_cast<chrono::duration<double>>(end - start)).count();
  return 0;
}
