#include <bits/stdc++.h>
using namespace std;
const int maxn = 100005;
const int maxm = 200005;
struct Edge {
  int u, v, w, nxt;
} edge[maxm];
int head[maxn], tot;
int W[maxn];
bool vis[maxn];
void init() {
  tot = 0;
  memset(head, -1, sizeof(head));
  memset(W, 0, sizeof(W));
  memset(vis, false, sizeof(vis));
}
void addedge(int u, int v, int w) {
  edge[tot].u = u;
  edge[tot].v = v;
  edge[tot].w = w;
  edge[tot].nxt = head[u];
  head[u] = tot++;
}
int xian[31];
void initXian() { memset(xian, 0, sizeof(xian)); }
vector<int> base;
void add(int x) {
  for (int i = 30; i >= 0; i--) {
    if (((x >> i) & 1) == 1) {
      if (xian[i] == 0) {
        xian[i] = x;
        break;
      } else {
        x ^= xian[i];
      }
    }
  }
}
int query(int x) {
  for (int i = 30; i >= 0; i--) {
    if (((x >> i) & 1) == 1) {
      x ^= xian[i];
    }
  }
  return x;
}
void dfs(int u, int now) {
  vis[u] = true;
  W[u] = now;
  for (int i = head[u]; i != -1; i = edge[i].nxt) {
    int v = edge[i].v;
    if (!vis[v]) {
      dfs(v, now ^ edge[i].w);
    } else {
      add(now ^ edge[i].w ^ W[v]);
    }
  }
}
int main() {
  init();
  initXian();
  int n, m;
  scanf("%d%d", &n, &m);
  for (int i = 0; i < m; i++) {
    int u, v, w;
    scanf("%d%d%d", &u, &v, &w);
    addedge(u, v, w);
    addedge(v, u, w);
  }
  dfs(1, 0);
  printf("%d\n", query(W[n]));
  return 0;
}
