#include <bits/stdc++.h>
using namespace std;
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
template <class S, class T>
ostream& operator<<(ostream& os, const pair<S, T>& p) {
  return os << "(" << p.first << ", " << p.second << ")";
}
template <class T>
ostream& operator<<(ostream& os, const vector<T>& p) {
  os << "[ ";
  for (auto& it : p) os << it << " ";
  return os << "]";
}
template <class T>
ostream& operator<<(ostream& os, const unordered_set<T>& p) {
  os << "[ ";
  for (auto& it : p) os << it << " ";
  return os << "]";
}
template <class S, class T>
ostream& operator<<(ostream& os, const unordered_map<S, T>& p) {
  os << "[ ";
  for (auto& it : p) os << it << " ";
  return os << "]";
}
template <class T>
ostream& operator<<(ostream& os, const set<T>& p) {
  os << "[ ";
  for (auto& it : p) os << it << " ";
  return os << "]";
}
template <class T>
ostream& operator<<(ostream& os, const multiset<T>& p) {
  os << "[ ";
  for (auto& it : p) os << it << " ";
  return os << "]";
}
template <class S, class T>
ostream& operator<<(ostream& os, const map<S, T>& p) {
  os << "[ ";
  for (auto& it : p) os << it << " ";
  return os << "]";
}
template <class T>
void dbs(string str, T t) {
  cerr << str << " : " << t << "\n";
}
template <class T, class... S>
void dbs(string str, T t, S... s) {
  long long idx = str.find(',');
  cerr << str.substr(0, idx) << " : " << t << ",";
  dbs(str.substr(idx + 1), s...);
}
template <class T>
void prc(T a, T b) {
  cerr << "[";
  for (T i = a; i != b; ++i) {
    if (i != a) cerr << ", ";
    cerr << *i;
  }
  cerr << "]\n";
}
long long power(long long x, long long y) {
  long long res = 1;
  while (y) {
    if (y & 1) res = (res * x) % 1000000007;
    y = y / 2, x = (x * x) % 1000000007;
  }
  return res % 1000000007;
}
vector<vector<pair<long long, long long> > > arr(100005);
long long visited[100005];
long long basis[100005][32];
long long curr;
vector<long long> temp;
long long val[100005];
void dfs(long long u, long long par, long long xorest) {
  visited[u] = curr;
  val[u] = xorest;
  for (auto v : arr[u]) {
    if (v.first == par) continue;
    if (!visited[v.first]) {
      dfs(v.first, u, xorest ^ v.second);
    } else {
      temp.push_back(xorest ^ val[v.first] ^ v.second);
    }
  }
}
void gauss() {
  long long i;
  for (auto v : temp) {
    long long x = v;
    for (i = 30; i >= 0; i--) {
      if (x & (1LL << i)) {
        if (basis[curr][i])
          x ^= (basis[curr][i]);
        else {
          basis[curr][i] = x;
          break;
        }
      }
    }
  }
}
long long query(long long index, long long ans) {
  long long i;
  for (i = 30; i >= 0; i--) {
    ans = min(ans, ans ^ basis[index][i]);
  }
  return ans;
}
signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  long long n, m, q;
  cin >> n >> m;
  long long i;
  for (i = 0; i < m; i++) {
    long long u, v, w;
    cin >> u >> v >> w;
    arr[u].push_back(make_pair(v, w));
    arr[v].push_back(make_pair(u, w));
  }
  for (i = 1; i <= n; i++) {
    if (!visited[i]) {
      curr++;
      temp.clear();
      dfs(i, 0, 0);
      gauss();
    }
  }
  q = 1;
  for (i = 0; i < q; i++) {
    long long u = 1, v = n;
    if (visited[u] != visited[v])
      cout << "XIT\n";
    else
      cout << query(visited[u], val[u] ^ val[v]) << "\n";
  }
}

### Prompt

Your challenge is to write a CPP solution to the following problem:

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;
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
template <class S, class T>
ostream& operator<<(ostream& os, const pair<S, T>& p) {
  return os << "(" << p.first << ", " << p.second << ")";
}
template <class T>
ostream& operator<<(ostream& os, const vector<T>& p) {
  os << "[ ";
  for (auto& it : p) os << it << " ";
  return os << "]";
}
template <class T>
ostream& operator<<(ostream& os, const unordered_set<T>& p) {
  os << "[ ";
  for (auto& it : p) os << it << " ";
  return os << "]";
}
template <class S, class T>
ostream& operator<<(ostream& os, const unordered_map<S, T>& p) {
  os << "[ ";
  for (auto& it : p) os << it << " ";
  return os << "]";
}
template <class T>
ostream& operator<<(ostream& os, const set<T>& p) {
  os << "[ ";
  for (auto& it : p) os << it << " ";
  return os << "]";
}
template <class T>
ostream& operator<<(ostream& os, const multiset<T>& p) {
  os << "[ ";
  for (auto& it : p) os << it << " ";
  return os << "]";
}
template <class S, class T>
ostream& operator<<(ostream& os, const map<S, T>& p) {
  os << "[ ";
  for (auto& it : p) os << it << " ";
  return os << "]";
}
template <class T>
void dbs(string str, T t) {
  cerr << str << " : " << t << "\n";
}
template <class T, class... S>
void dbs(string str, T t, S... s) {
  long long idx = str.find(',');
  cerr << str.substr(0, idx) << " : " << t << ",";
  dbs(str.substr(idx + 1), s...);
}
template <class T>
void prc(T a, T b) {
  cerr << "[";
  for (T i = a; i != b; ++i) {
    if (i != a) cerr << ", ";
    cerr << *i;
  }
  cerr << "]\n";
}
long long power(long long x, long long y) {
  long long res = 1;
  while (y) {
    if (y & 1) res = (res * x) % 1000000007;
    y = y / 2, x = (x * x) % 1000000007;
  }
  return res % 1000000007;
}
vector<vector<pair<long long, long long> > > arr(100005);
long long visited[100005];
long long basis[100005][32];
long long curr;
vector<long long> temp;
long long val[100005];
void dfs(long long u, long long par, long long xorest) {
  visited[u] = curr;
  val[u] = xorest;
  for (auto v : arr[u]) {
    if (v.first == par) continue;
    if (!visited[v.first]) {
      dfs(v.first, u, xorest ^ v.second);
    } else {
      temp.push_back(xorest ^ val[v.first] ^ v.second);
    }
  }
}
void gauss() {
  long long i;
  for (auto v : temp) {
    long long x = v;
    for (i = 30; i >= 0; i--) {
      if (x & (1LL << i)) {
        if (basis[curr][i])
          x ^= (basis[curr][i]);
        else {
          basis[curr][i] = x;
          break;
        }
      }
    }
  }
}
long long query(long long index, long long ans) {
  long long i;
  for (i = 30; i >= 0; i--) {
    ans = min(ans, ans ^ basis[index][i]);
  }
  return ans;
}
signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  long long n, m, q;
  cin >> n >> m;
  long long i;
  for (i = 0; i < m; i++) {
    long long u, v, w;
    cin >> u >> v >> w;
    arr[u].push_back(make_pair(v, w));
    arr[v].push_back(make_pair(u, w));
  }
  for (i = 1; i <= n; i++) {
    if (!visited[i]) {
      curr++;
      temp.clear();
      dfs(i, 0, 0);
      gauss();
    }
  }
  q = 1;
  for (i = 0; i < q; i++) {
    long long u = 1, v = n;
    if (visited[u] != visited[v])
      cout << "XIT\n";
    else
      cout << query(visited[u], val[u] ^ val[v]) << "\n";
  }
}

```