#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 10;
const int maxm = maxn * 2;
long long rd() {
  long long t;
  scanf("%I64d", &t);
  return t;
}
const int mo = 1e9;
struct L_B {
  long long d[65], p[65];
  int cnt;
  L_B() {
    memset(d, 0, sizeof(d));
    memset(p, 0, sizeof(p));
    cnt = 0;
  }
  bool insert(long long val) {
    for (int i = 62; i >= 0; i--)
      if (val & (1LL << i)) {
        if (!d[i]) {
          d[i] = val;
          break;
        }
        val ^= d[i];
      }
    return val > 0;
  }
  long long query_max() {
    long long ret = 0;
    for (int i = 62; i >= 0; i--)
      if ((ret ^ d[i]) > ret) ret ^= d[i];
    return ret;
  }
  long long query_min() {
    for (int i = 0; i <= 62; i++)
      if (d[i]) return d[i];
    return 0;
  }
  void rebuild() {
    for (int i = 62; i >= 0; i--)
      for (int j = i - 1; j >= 0; j--)
        if (d[i] & (1LL << j)) d[i] ^= d[j];
    for (int i = 0; i <= 62; i++)
      if (d[i]) p[cnt++] = d[i];
  }
  long long kthquery(long long k) {
    int ret = 0;
    if (k >= (1LL << cnt)) return -1;
    for (int i = 62; i >= 0; i--)
      if (k & (1LL << i)) ret ^= p[i];
    return ret;
  }
  bool cunzai(long long x) {
    for (int i = 62; i >= 0; --i) {
      if ((x >> i) & 1) {
        x = x ^ d[i];
      }
      if (x == 0) return 1;
    }
    return 0;
  }
  long long querymin(long long x) {
    for (int i = 62; i >= 0; --i) {
      if ((x >> i) & 1 and d[i]) {
        x ^= d[i];
      }
    }
    return x;
  }
};
L_B lb;
struct node {
  int v, nxt, w;
} edge[maxm];
int tot = 1, head[maxn];
void add(int x, int y, int w) {
  edge[++tot] = (node){y, head[x], w};
  head[x] = tot;
}
bool vis[maxn];
int a[maxn];
void dfs(int x, int from, int res) {
  a[x] = res;
  vis[x] = 1;
  for (int i = head[x]; i; i = edge[i].nxt) {
    if ((i ^ 1) == from) continue;
    int y = edge[i].v;
    if (vis[y]) {
      lb.insert(res ^ edge[i].w ^ a[y]);
    } else
      dfs(y, i, res ^ edge[i].w);
  }
}
signed main() {
  int n, m;
  cin >> n >> m;
  for (int i = 1; i <= m; i++) {
    int x = rd(), y = rd(), w = rd();
    add(x, y, w), add(y, x, w);
  }
  dfs(1, 0, 0);
  cout << lb.querymin(a[n]) << '\n';
  return 0;
}

### Prompt

Develop a solution in CPP to the problem described below:

You are given an undirected graph with weighted edges. The length of some path between two vertices is the bitwise xor of weights of all edges belonging to this path (if some edge is traversed more than once, then it is included in bitwise xor the same number of times). You have to find the minimum length of path between vertex 1 and vertex n.

Note that graph can contain multiple edges and loops. It is guaranteed that the graph is connected.

Input

The first line contains two numbers n and m (1 ≤ n ≤ 100000, n - 1 ≤ m ≤ 100000) — the number of vertices and the number of edges, respectively.

Then m lines follow, each line containing three integer numbers x, y and w (1 ≤ x, y ≤ n, 0 ≤ w ≤ 108). These numbers denote an edge that connects vertices x and y and has weight w.

Output

Print one number — the minimum length of path between vertices 1 and n.

Examples

Input

3 3
1 2 3
1 3 2
3 2 0


Output

2


Input

2 2
1 1 3
1 2 3


Output

0

### Response

```cpp
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 10;
const int maxm = maxn * 2;
long long rd() {
  long long t;
  scanf("%I64d", &t);
  return t;
}
const int mo = 1e9;
struct L_B {
  long long d[65], p[65];
  int cnt;
  L_B() {
    memset(d, 0, sizeof(d));
    memset(p, 0, sizeof(p));
    cnt = 0;
  }
  bool insert(long long val) {
    for (int i = 62; i >= 0; i--)
      if (val & (1LL << i)) {
        if (!d[i]) {
          d[i] = val;
          break;
        }
        val ^= d[i];
      }
    return val > 0;
  }
  long long query_max() {
    long long ret = 0;
    for (int i = 62; i >= 0; i--)
      if ((ret ^ d[i]) > ret) ret ^= d[i];
    return ret;
  }
  long long query_min() {
    for (int i = 0; i <= 62; i++)
      if (d[i]) return d[i];
    return 0;
  }
  void rebuild() {
    for (int i = 62; i >= 0; i--)
      for (int j = i - 1; j >= 0; j--)
        if (d[i] & (1LL << j)) d[i] ^= d[j];
    for (int i = 0; i <= 62; i++)
      if (d[i]) p[cnt++] = d[i];
  }
  long long kthquery(long long k) {
    int ret = 0;
    if (k >= (1LL << cnt)) return -1;
    for (int i = 62; i >= 0; i--)
      if (k & (1LL << i)) ret ^= p[i];
    return ret;
  }
  bool cunzai(long long x) {
    for (int i = 62; i >= 0; --i) {
      if ((x >> i) & 1) {
        x = x ^ d[i];
      }
      if (x == 0) return 1;
    }
    return 0;
  }
  long long querymin(long long x) {
    for (int i = 62; i >= 0; --i) {
      if ((x >> i) & 1 and d[i]) {
        x ^= d[i];
      }
    }
    return x;
  }
};
L_B lb;
struct node {
  int v, nxt, w;
} edge[maxm];
int tot = 1, head[maxn];
void add(int x, int y, int w) {
  edge[++tot] = (node){y, head[x], w};
  head[x] = tot;
}
bool vis[maxn];
int a[maxn];
void dfs(int x, int from, int res) {
  a[x] = res;
  vis[x] = 1;
  for (int i = head[x]; i; i = edge[i].nxt) {
    if ((i ^ 1) == from) continue;
    int y = edge[i].v;
    if (vis[y]) {
      lb.insert(res ^ edge[i].w ^ a[y]);
    } else
      dfs(y, i, res ^ edge[i].w);
  }
}
signed main() {
  int n, m;
  cin >> n >> m;
  for (int i = 1; i <= m; i++) {
    int x = rd(), y = rd(), w = rd();
    add(x, y, w), add(y, x, w);
  }
  dfs(1, 0, 0);
  cout << lb.querymin(a[n]) << '\n';
  return 0;
}

```