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 N = 2e5 + 113;
map<int, bool> edges[N];
set<int> unused;
bool used[N];
int color[N];
int snm[N];
int getroot(int v) {
  if (snm[v] == v) return v;
  return snm[v] = getroot(snm[v]);
}
bool merge(int a, int b) {
  a = getroot(a), b = getroot(b);
  if (a == b) return 0;
  snm[a] = b;
  return 1;
}
signed main() {
  cin.tie(NULL);
  ios_base::sync_with_stdio(false);
  int n, m;
  cin >> n >> m;
  vector<pair<int, pair<int, int>>> e;
  int minans = 0;
  for (int i = 0; i < m; i++) {
    int u, v, w;
    cin >> u >> v >> w;
    minans ^= w;
    e.push_back({w, {u, v}});
    edges[u][v] = 1;
    edges[v][u] = 1;
  }
  for (int i = 1; i <= n; i++) unused.insert(i);
  queue<int> d;
  int c = 0;
  bool cangood = 0;
  for (int i = 1; i <= n; i++) {
    if (!used[i]) {
      c++;
      used[i] = 1;
      d.push(i);
      unused.erase(i);
      while (d.size()) {
        int cnt = 0;
        int v = d.front();
        if (!cangood) {
          for (int j = 1; j <= n; j++) {
            if (j != v && !edges[v][j] && used[j]) cnt++;
          }
        }
        if (i == v && cnt >= 1) cangood = 1;
        if (cnt >= 2) cangood = 1;
        color[v] = c;
        d.pop();
        vector<int> toerase;
        for (auto j : unused) {
          if (!edges[v][j]) toerase.push_back(j);
        }
        for (auto j : toerase) used[j] = 1, unused.erase(j), d.push(j);
      }
    }
  }
  for (int i = 1; i <= c; i++) snm[i] = i;
  sort(e.begin(), e.end());
  long long sum = 0;
  for (auto i : e)
    sum += i.first * merge(color[i.second.first], color[i.second.second]);
  if (cangood) {
    cout << sum << endl;
    return 0;
  }
  for (auto i : e) {
    if (color[i.second.first] != color[i.second.second])
      minans = min(minans, i.first);
  }
  cout << sum + minans << endl;
}
