#include <bits/stdc++.h>
using namespace std;
const int N = (1 << 17), inv = 5e8 + 4, mod = 1e9 + 7;
mt19937 mt(time(0));
struct data {
  int to, next, v;
} e[N * 2];
long long X[N + 20], XX[N + 20], YY[N + 20], Y[N + 20];
int low[N], dfn[N], n, m, i, j, head[N], bridge[N], cnt, fa[N], size[N], ans,
    u[N], v[N], w[N], col[N], ind;
vector<int> vec[N];
void ins(int u, int v, int w) {
  e[++cnt].to = v;
  e[cnt].next = head[u];
  head[u] = cnt;
  e[cnt].v = w;
}
void insert(int u, int v, int w) {
  ins(u, v, w);
  ins(v, u, w);
}
int find(int x) { return x == fa[x] ? x : fa[x] = find(fa[x]); }
void merge(int x, int y) {
  if (find(x) == find(y)) return;
  size[find(y)] += size[find(x)];
  fa[find(x)] = find(y);
}
void tarjan(int x, int fa) {
  low[x] = dfn[x] = ++ind;
  for (int i = head[x]; i; i = e[i].next)
    if (!dfn[e[i].to]) {
      tarjan(e[i].to, e[i].v);
      low[x] = min(low[x], low[e[i].to]);
      if (dfn[x] < low[e[i].to]) bridge[e[i].v] = 1;
    } else if (e[i].v != fa)
      low[x] = min(low[x], dfn[e[i].to]);
}
void fwt(long long *x, int n, int flag) {
  for (int i = 1; i < n; i <<= 1) {
    for (int p = i << 1, j = 0; j < n; j += p) {
      for (int k = 0; k < i; ++k) {
        long long l = x[j + k], r = x[j + k + i];
        if (flag == 1)
          x[j + k] = (l + r) % mod, x[j + k + i] = (l - r + mod) % mod;
        else
          x[j + k] = (l + r) * inv % mod,
                x[j + k + i] = (l - r + mod) % mod * inv % mod;
      }
    }
  }
}
int main() {
  for (scanf("%d%d", &n, &m), i = 1; i <= m; ++i)
    scanf("%d%d%d", u + i, v + i, w + i), insert(u[i], v[i], i);
  for (i = 1; i <= n; ++i)
    if (!dfn[i]) tarjan(i, 0);
  for (i = 1; i <= n; ++i) fa[i] = i, size[i] = 1;
  for (i = 1; i <= m; ++i)
    if (!bridge[i]) merge(u[i], v[i]);
  ind = 0;
  for (i = 1; i <= n; ++i)
    if (find(i) == i && size[i] > 1) col[i] = ++ind;
  for (i = 1; i <= m; ++i)
    if (!bridge[i])
      vec[col[find(u[i])]].push_back(w[i]);
    else
      ans ^= w[i];
  X[ans] = 1;
  fwt(X, N, 1);
  XX[ans] = mt();
  fwt(XX, N, 1);
  for (i = 1; i <= ind; ++i) {
    memset(Y, 0, sizeof(Y));
    memset(YY, 0, sizeof(YY));
    ans = 0;
    for (auto &x : vec[i]) ans ^= x;
    for (auto &x : vec[i]) Y[ans ^ x]++;
    for (auto &x : vec[i]) YY[ans ^ x] += mt();
    fwt(Y, N, 1);
    fwt(YY, N, 1);
    for (j = 0; j < N; ++j)
      X[j] = X[j] * Y[j] % mod, XX[j] = XX[j] * YY[j] % mod;
  }
  fwt(X, N, -1);
  fwt(XX, N, -1);
  for (i = 0; i < N; ++i)
    if (X[i] || XX[i]) return 0 * printf("%d %I64d\n", i, X[i]);
}
