#include <bits/stdc++.h>   using namespace std;   int gcd(int x, int y) { return (!y ? x : gcd(y, x % y)); }   const int maxn = 2e5;   vector<int> g[maxn], tree[maxn];   map<pair<int, int>, int> we;   int par[maxn];   int gpar(int v) { return (par[v] == v ? v : par[v] = gpar(par[v])); }   bool mrg(int u, int v) {     u = gpar(u);     v = gpar(v);     if (u == v) return false;     par[v] = u;     return true;   }   int h[maxn];   void dfs(int v, int p) {     for (auto u : tree[v]) {       if (u == p) continue;       par[u] = v;       h[u] = h[v] + 1;       dfs(u, v);     }   }   vector<int> get_path(int u, int v) {     if (h[u] < h[v]) swap(u, v);     vector<int> p, rig;     while (h[u] > h[v]) {       p.push_back(u);       u = par[u];     }     while (u != v) {       p.push_back(u);       rig.push_back(v);       u = par[u], v = par[v];     }     p.push_back(u);     reverse(rig.begin(), rig.end());     for (auto i : rig) p.push_back(i);     return p;   }   const int maxb = 18;   int mods[2] = {int(1e9 + 7), int(1e9 + 9)};   int mod;   const int N = (1 << maxb);   int bpw(int a, int b) {     int ans = 1;     while (b) {       if (b & 1) ans = 1LL * ans * a % mod;       a = 1LL * a * a % mod;       b >>= 1;     }     return ans;   }   void fwht(int* a, int val) {     for (int len = 2; len <= N; len *= 2)       for (int i = 0; i < N; i += len) {         int nxt = len / 2;         for (int j = 0; j < nxt; j++) {           int x = a[i + j], y = a[i + j + nxt];           a[i + j] = (x + y) % mod;           a[i + j + nxt] = (x - y + mod) % mod;         }       }     if (val == -1) {       int inv = bpw(N, mod - 2);       for (int i = 0; i < N; i++) a[i] = 1LL * a[i] * inv % mod;     }   }   int ans[2][N], cnt[N];   int32_t main() {     ios::sync_with_stdio(0), cin.tie(0);     int n, m;     cin >> n >> m;     int tot = 0;     for (int i = 0; i < m; i++) {       int u, v, w;       cin >> u >> v >> w;       u--, v--;       g[u].push_back(v);       g[v].push_back(u);       we[{u, v}] = we[{v, u}] = w;       tot ^= w;     }     for (int i = 0; i < n; i++) par[i] = i;     vector<pair<int, int> > bads;     for (int i = 0; i < n; i++) {       for (auto j : g[i]) {         if (mrg(i, j)) {           tree[i].push_back(j);           tree[j].push_back(i);         } else if (i < j)           bads.push_back({i, j});       }     }     if (bads.size() == 0) {       cout << tot <<     << 1 <<   n ;       return 0;     }     dfs(0, 0);     for (int it = 0; it < 2; it++) {       mod = mods[it];       for (int i = 0; i < N; i++) ans[it][i] = 1;       for (auto t : bads) {         vector<int> p = get_path(t.first, t.second);         p.push_back(p[0]);         memset(cnt, 0, sizeof cnt);         for (int i = 0; i + 1 < p.size(); i++) {           int w = we[{p[i], p[i + 1]}];           cnt[w]++;         }         fwht(cnt, 1);         for (int i = 0; i < N; i++) ans[it][i] = 1LL * ans[it][i] * cnt[i] % mod;       }       fwht(ans[it], -1);     }     int jav = 1e9, who = -1;     for (int i = 0; i < N; i++)       if (ans[0][i] || ans[1][i]) {         if ((i ^ tot) < jav) {           jav = i ^ tot;           who = i;         }       }     assert(who != -1);     cout << jav <<     << ans[0][who] <<   n ;   }