#include <bits/stdc++.h>
using namespace std;
const int oo = 2139063143;
const int N = 501000;
const double eps = 1e-7;
template <typename T>
inline void sc(T &x) {
  x = 0;
  static int p;
  p = 1;
  static char c;
  c = getchar();
  while (!isdigit(c)) {
    if (c == '-') p = -1;
    c = getchar();
  }
  while (isdigit(c)) {
    x = (x << 1) + (x << 3) + (c - 48);
    c = getchar();
  }
  x *= p;
}
template <typename T>
inline void print(T x) {
  if (x < 0) putchar('-'), x = -x;
  if (x >= 10) print(x / 10);
  putchar(x % 10 + '0');
}
template <typename T>
inline void pr(T x) {
  print(x), putchar('\n');
}
template <typename T1, typename T2>
void chkmax(T1 &A, T2 B) {
  A = A >= B ? A : B;
}
template <typename T1, typename T2>
void chkmin(T1 &A, T2 B) {
  A = A <= B ? A : B;
}
const int P1 = 1e9 + 7, P2 = 1e9 + 9;
int del(int x, int P) { return x >= P ? x - P : x; }
void fwt(int *a, int n, bool op, const int P) {
  const int inv2 = (P + 1) >> 1;
  for (int i = 1; i < n; i <<= 1)
    for (int j = 0, sb = i << 1; j < n; j += sb)
      for (int k = j; k < j + i; k++) {
        int x = a[k], y = a[k + i];
        a[k] = del(x + y, P), a[k + i] = del(x - y + P, P);
        if (!op)
          a[k] = (long long)a[k] * inv2 % P,
          a[k + i] = (long long)a[k + i] * inv2 % P;
      }
}
struct EDGE {
  int v, w, id, nx;
} lb[N << 1];
int tot = 1, top[N];
void add(int u, int v, int w, int id) {
  lb[++tot] = (EDGE){v, w, id, top[u]}, top[u] = tot;
}
int fa[N], d[N], dep[N];
bool vis[N], in[N];
void dfs(int u) {
  vis[u] = 1;
  for (int kb = top[u]; kb; kb = lb[kb].nx) {
    int v = lb[kb].v, w = lb[kb].w, id = lb[kb].id;
    if (vis[v]) continue;
    in[id] = 1;
    dep[v] = dep[u] + 1, fa[v] = u, d[v] = w;
    dfs(v);
  }
}
int n, m, x[N], y[N], w[N], a1[N], a2[N], b1[N], b2[N];
int main() {
  sc(n), sc(m);
  int S = 0, ma = 0;
  for (int i = 1; i <= m; i++) {
    sc(x[i]), sc(y[i]), sc(w[i]);
    add(x[i], y[i], w[i], i), add(y[i], x[i], w[i], i);
    S ^= w[i];
    chkmax(ma, w[i]);
  }
  int s = 1;
  while (s <= ma) s <<= 1;
  a1[0] = 1, a2[0] = 1;
  fwt(a1, s, 1, P1), fwt(a2, s, 1, P2);
  dfs(1);
  for (int i = 1; i <= m; i++)
    if (!in[i]) {
      int x = ::x[i], y = ::y[i], w = ::w[i];
      memset(b1, 0, sizeof(int) * (s + 1));
      ++b1[w];
      while (x != y) {
        if (dep[x] < dep[y]) swap(x, y);
        ++b1[d[x]];
        x = fa[x];
      }
      memcpy(b2, b1, sizeof(int) * (s + 1));
      fwt(b1, s, 1, P1), fwt(b2, s, 1, P2);
      for (int i = 0; i < s; i++)
        a1[i] = (long long)a1[i] * b1[i] % P1,
        a2[i] = (long long)a2[i] * b2[i] % P2;
    }
  fwt(a1, s, 0, P1), fwt(a2, s, 0, P2);
  int mi = 1e9, ans = 0;
  for (int i = 0; i < s; i++)
    if (a1[i] || a2[i]) {
      int g = S ^ i;
      if (mi > g) mi = g, ans = a1[i];
    }
  printf("%d %d\n", mi, ans);
  return 0;
}
