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;
clock_t timeStart, timeFinish;
void timeBegin() { timeStart = clock(); }
void timeEnd() { timeFinish = clock(); }
void timeDuration() {
  timeEnd();
  double time_taken = double(timeFinish - timeStart) / double(CLOCKS_PER_SEC);
  cout << "Time taken by program is : " << fixed << time_taken
       << setprecision(5);
  cout << " sec " << endl;
}
class InputReader {
 public:
  InputReader() {
    input_file = stdin;
    cursor = 0;
    fread(buffer, SIZE, 1, input_file);
  }
  InputReader(const char *file_name) {
    input_file = fopen(file_name, "r");
    cursor = 0;
    fread(buffer, SIZE, 1, input_file);
  }
  inline InputReader &operator>>(int &n) {
    while ((buffer[cursor] < '0' || buffer[cursor] > '9') &&
           buffer[cursor] != '-') {
      advance();
    }
    int sign = 1;
    if (buffer[cursor] == '-') {
      sign = -1;
      advance();
    }
    n = 0;
    while ('0' <= buffer[cursor] && buffer[cursor] <= '9') {
      n = n * 10 + buffer[cursor] - '0';
      advance();
    }
    n *= sign;
    return *this;
  }

 private:
  FILE *input_file;
  static const int SIZE = 1 << 17;
  int cursor;
  char buffer[SIZE];
  inline void advance() {
    ++cursor;
    if (cursor == SIZE) {
      cursor = 0;
      fread(buffer, SIZE, 1, input_file);
    }
  }
};
const int MAXN = 200000;
const int MAXM = 200000;
const int SMALL = 1000;
struct Edge {
  int a;
  int b;
  int c;
  bool operator<(const Edge &other) const { return c < other.c; }
};
vector<pair<int, int> > g[1 + MAXN];
set<int> comps;
vector<int> nodes[1 + MAXN];
int where[1 + MAXN];
int f[1 + MAXN];
Edge edge[1 + MAXM];
void doComplementComponents(int n) {
  for (int i = 1; i <= n; i++) {
    for (auto it : comps) {
      f[it] = 0;
    }
    where[i] = i;
    nodes[i].push_back(i);
    comps.insert(i);
    for (auto it : g[i]) {
      if (it.first < i) {
        f[where[it.first]]++;
      }
    }
    vector<int> bad;
    bad.push_back(i);
    int best = i;
    for (auto it : comps) {
      if (f[it] != nodes[it].size()) {
        bad.push_back(it);
        if (nodes[it].size() > nodes[best].size()) {
          best = it;
        }
      }
    }
    for (auto it : bad) {
      comps.erase(it);
      if (it != best) {
        for (auto node : nodes[it]) {
          nodes[best].push_back(node);
          where[node] = best;
        }
        nodes[it].clear();
      }
    }
    comps.insert(best);
  }
}
int dad[1 + MAXN], h[1 + MAXN];
int findDad(int node) {
  if (dad[node] == node) {
    return node;
  }
  return dad[node] = findDad(dad[node]);
}
void join(int a, int b) {
  if (h[a] > h[b]) {
    swap(a, b);
  }
  if (h[a] == h[b]) {
    h[b]++;
  }
  dad[a] = b;
}
long long connectComponents(int m) {
  for (auto it : comps) {
    dad[it] = it;
    h[it] = 1;
  }
  long long answer = 0;
  for (int i = 1; i <= m; i++) {
    int a = findDad(where[edge[i].a]), b = findDad(where[edge[i].b]);
    if (a != b) {
      answer += edge[i].c;
      join(a, b);
    }
  }
  return answer;
}
bool isEdge[1 + SMALL][1 + SMALL];
vector<int> t[1 + SMALL];
void DFS(int node, int father, int x) {
  where[node] = x;
  for (auto son : t[node]) {
    if (son != father) {
      DFS(son, node, x);
    }
  }
}
int main() {
  timeBegin();
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  int n, m;
  int xorSum = 0;
  cin >> n >> m;
  for (int i = 1; i <= m; i++) {
    int a, b, c;
    cin >> a >> b >> c;
    g[a].push_back({b, c});
    g[b].push_back({a, c});
    edge[i] = {a, b, c};
    xorSum ^= c;
  }
  if (xorSum == 0) {
    cout << "0\n";
    return 0;
  }
  doComplementComponents(n);
  sort(edge + 1, edge + m + 1);
  long long m0 = 1LL * n * (n - 1) / 2 - m;
  if (m0 > n - comps.size()) {
    cout << connectComponents(m) << "\n";
  } else {
    assert(n <= SMALL);
    for (int i = 1; i <= m; i++) {
      isEdge[edge[i].a][edge[i].b] = isEdge[edge[i].b][edge[i].a] = true;
    }
    for (int i = 1; i <= n; i++) {
      for (int j = i + 1; j <= n; j++) {
        if (!isEdge[i][j]) {
          t[i].push_back(j);
          t[j].push_back(i);
        }
      }
    }
    long long answer = connectComponents(m) + xorSum;
    for (int i = 1; i <= n; i++) {
      for (int j = i + 1; j <= n; j++) {
        if (!isEdge[i][j]) {
          int x = where[j] == j ? i : j;
          DFS(i, j, x);
          comps.insert(x);
          answer = min(answer, connectComponents(m));
          comps.erase(x);
          for (auto node : nodes[where[j]]) {
            where[node] = where[j];
          }
        }
      }
    }
    cout << answer << "\n";
  }
  return 0;
}
