#include <bits/stdc++.h>   #pragma GCC optimize( Ofast,unroll-loops,no-stack-protector,fast-math )   #pragma GCC target( sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native )   using namespace std;   using i32 = int;   using i64 = long long;   using u8 = unsigned char;   using u32 = unsigned;   using u64 = unsigned long long;   using f64 = double;   using f80 = long double;   long long power(long long a, long long b, long long p) {     if (!b) return 1;     long long t = power(a, b / 2, p);     t = t * t % p;     if (b & 1) t = t * a % p;     return t;   }   long long exgcd(long long a, long long b, long long &x, long long &y) {     if (b == 0) {       x = 1;       y = 0;       return a;     }     long long px, py;     long long d = exgcd(b, a % b, px, py);     x = py;     y = px - a / b * py;     return d;   }   template <class T>   inline void freshmin(T &a, const T &b) {     if (a > b) a = b;   }   template <class T>   inline void freshmax(T &a, const T &b) {     if (a < b) a = b;   }   namespace io {   const int BUFSIZE = 1 << 20;   int isize, osize;   char ibuf[BUFSIZE + 10], obuf[BUFSIZE + 10];   char *is, *it, *os = obuf, *ot = obuf + BUFSIZE;   char getchar() {     if (is == it) {       is = ibuf;       it = ibuf + fread(ibuf, 1, BUFSIZE, stdin);       if (is == it) return EOF;     }     return *is++;   }   char getalpha() {     char c = getchar();     while (!isalpha(c)) c = getchar();     return c;   }   void putchar(char c) {     *os++ = c;     if (os == ot) {       fwrite(obuf, 1, BUFSIZE, stdout);       os = obuf;     }   }   int inp() {     int x = 0, f = 0;     char ch;     for (ch = getchar(); !isdigit(ch); ch = getchar())       if (ch ==  - ) f = 1;     for (; isdigit(ch); x = x * 10 + ch -  0 , ch = getchar())       ;     return f ? -x : x;   }   long long inp_ll() {     long long x = 0;     int f = 0;     char ch;     for (ch = getchar(); !isdigit(ch); ch = getchar())       if (ch ==  - ) f = 1;     for (; isdigit(ch); x = x * 10 + ch -  0 , ch = getchar())       ;     return f ? -x : x;   }   template <class T>   bool read(T &x) {     x = 0;     char ch = getchar();     if (ch == EOF) return 0;     for (; !isdigit(ch);) {       ch = getchar();       if (ch == EOF) return 0;     }     for (; isdigit(ch); x = x * 10 + ch -  0 , ch = getchar())       ;     return 1;   }   template <class T>   void write(T x) {     static char s[22];     static char *it = s + 20;     static char *end = s + 20;     if (x < 0) {       putchar( - );       x = -x;     }     do {       *--it = x % 10 +  0 ;       x /= 10;     } while (x);     for (; it < end; ++it) putchar(*it);   }   template <>   void write(const char *s) {     for (; *s; ++s) putchar(*s);   }   template <>   void write(char c) {     putchar(c);   }   template <class T, class V>   void write(T x, V y) {     write(x);     write(y);   }   template <class T>   void writeln(T x) {     write(x);     putchar(  n );   }   struct ender {     ~ender() {       if (os != obuf) fwrite(obuf, 1, os - obuf, stdout);     }   } __ender;   }  // namespace io   template <class T>   void print(const T &a) {     for (auto x : a) printf( %d  , x);     puts(  );   }   const int MAXN = 1 << 18;   const int MAXK = 17;   const int INF = 1000000010;   using namespace io;   using tiii = tuple<int, int, int>;   int n, m;   vector<pair<int, int> > v[MAXN];   vector<tiii> e;   int pre[MAXN], weight[MAXN], dis[MAXN];   void dfs(int x) {     for (auto p : v[x]) {       int y = p.first, z = p.second;       if (y == pre[x]) continue;       pre[y] = x;       weight[y] = z;       dis[y] = dis[x] + 1;       dfs(y);     }   }   int F[MAXN];   int father(int x) { return F[x] == x ? x : F[x] = father(F[x]); }   const int K = 2;   const int mods[] = {1000000007, 998244353, 1000000009};   void FWT(int a[], int n, int mod) {     int MOD = mod;     for (int d = 1; d < n; d <<= 1)       for (int m = d << 1, i = 0; i < n; i += m)         for (int j = 0; j < d; j++) {           long long x = a[i + j], y = a[i + j + d];           a[i + j] = (x + y) % MOD;           a[i + j + d] = (x - y + MOD) % MOD;         }   }   void IFWT(int a[], int n, int mod) {     int MOD = mod;     int inv = (mod + 1) / 2;     for (int d = 1; d < n; d <<= 1)       for (int m = d << 1, i = 0; i < n; i += m)         for (int j = 0; j < d; j++) {           long long x = a[i + j], y = a[i + j + d];           a[i + j] = (x + y) % MOD;           a[i + j + d] = (x - y + MOD) % MOD;           a[i + j] = (long long)a[i + j] * inv % MOD;           a[i + j + d] = (long long)a[i + j + d] * inv % MOD;         }   }   int a[K][MAXN];   int b[MAXN];   void solve() {     n = inp();     m = inp();     int sum = 0;     for (int i = 1; i <= n; ++i) F[i] = i;     for (int i = 1; i <= m; ++i) {       int x = inp(), y = inp(), z = inp();       sum ^= z;       int fx = father(x), fy = father(y);       if (fx == fy) {         e.push_back(tiii{x, y, z});       } else {         F[fx] = fy;         v[x].push_back({y, z});         v[y].push_back({x, z});       }     }     dfs(1);     for (int k = 0; k < K; ++k) {       a[k][sum] = 1;       FWT(a[k], 1 << 17, mods[k]);     }     for (auto p : e) {       int x, y, z;       tie(x, y, z) = p;       vector<int> w(1, z);       while (x != y) {         if (dis[x] < dis[y]) swap(x, y);         w.push_back(weight[x]);         x = pre[x];       }       for (int k = 0; k < K; ++k) {         for (int i = 0; i < 1 << 17; ++i) b[i] = 0;         for (auto x : w) b[x]++;         FWT(b, 1 << 17, mods[k]);         for (int i = 0; i < 1 << 17; ++i) a[k][i] = (u64)a[k][i] * b[i] % mods[k];       }     }     for (int k = 0; k < K; ++k) {       IFWT(a[k], 1 << 17, mods[k]);     }     for (int i = 0; i < 1 << 17; ++i)       if (a[0][i] || a[1][i]) {         printf( %d %d n , i, a[0][i]);         break;       }   }   int main() {     solve();     return 0;   }