#include <bits/stdc++.h>
using namespace std;
const int maxn = 3e5 + 7, mod = 1e9 + 7, inf = 1e9, MAXN = 1e6 + 7;
const double eps = 1e-9;
mt19937 rnd(time(0));
int n, m;
int dst[maxn];
vector<pair<int, int> > gr[maxn];
set<pair<int, int> > edge;
map<pair<int, int>, int> Edge;
int p[maxn], used[maxn];
int ptr = 0;
vector<int> cycle[maxn];
vector<int> val[maxn];
void dfs(int u, int pr, int depth) {
  dst[u] = depth;
  p[u] = pr;
  used[u] = 1;
  for (auto v : gr[u]) {
    if (!used[v.first]) {
      dfs(v.first, u, depth + 1);
    } else if (v.first != pr && dst[u] >= dst[v.first]) {
      int pp = u;
      while (pp != v.first) {
        cycle[ptr].push_back(pp);
        pp = p[pp];
      }
      cycle[ptr++].push_back(v.first);
    }
  }
}
const int K = 1 << 17;
const int mod1 = 1000000007;
const int mod2 = 998244353;
int sum(int x, int y) {
  if (x + y < 0) return x + y + mod1;
  if (x + y >= mod1) return x + y - mod1;
  return x + y;
}
int mult(int x, int y) {
  return ((long long)x * (long long)y) % (long long)mod1;
}
vector<int> hadamard(vector<int> v) {
  for (int step = K; step > 1; step /= 2) {
    for (int start = 0; start < K; start += step) {
      for (int w = 0; w < step / 2; w++) {
        int F = sum(v[start + w], v[start + step / 2 + w]);
        int S = sum(v[start + w], -v[start + step / 2 + w]);
        v[start + w] = F;
        v[start + step / 2 + w] = S;
      }
    }
  }
  return v;
}
int pw(int a, int b) {
  if (b == 0) return 1;
  if (b == 1) return a % mod1;
  if (b % 2) return mult(a, pw(a, b - 1));
  int R = pw(a, b / 2);
  return mult(R, R);
}
int rev1 = pw(K, mod1 - 2);
vector<int> mult(vector<int> v, vector<int> u) {
  v = hadamard(v), u = hadamard(u);
  for (int i = 0; i < K; i++) v[i] = mult(v[i], u[i]);
  v = hadamard(v);
  for (int i = 0; i < K; i++) {
    v[i] = mult(v[i], rev1);
  }
  return v;
}
int sum2(int x, int y) {
  if (x + y < 0) return x + y + mod2;
  if (x + y >= mod2) return x + y - mod2;
  return x + y;
}
int mult2(int x, int y) {
  return ((long long)x * (long long)y) % (long long)mod2;
}
vector<int> hadamard2(vector<int> v) {
  for (int step = K; step > 1; step /= 2) {
    for (int start = 0; start < K; start += step) {
      for (int w = 0; w < step / 2; w++) {
        int F = sum2(v[start + w], v[start + step / 2 + w]);
        int S = sum2(v[start + w], -v[start + step / 2 + w]);
        v[start + w] = F;
        v[start + step / 2 + w] = S;
      }
    }
  }
  return v;
}
int pw2(int a, int b) {
  if (b == 0) return 1;
  if (b == 1) return a % mod2;
  if (b % 2) return mult2(a, pw2(a, b - 1));
  int R = pw2(a, b / 2);
  return mult2(R, R);
}
int rev2 = pw2(K, mod2 - 2);
vector<int> mult2(vector<int> v, vector<int> u) {
  v = hadamard2(v), u = hadamard2(u);
  for (int i = 0; i < K; i++) v[i] = mult2(v[i], u[i]);
  v = hadamard2(v);
  for (int i = 0; i < K; i++) {
    v[i] = mult2(v[i], rev2);
  }
  return v;
}
void solve() {
  cin >> n >> m;
  for (int i = 0; i < m; ++i) {
    int a, b, c;
    cin >> a >> b >> c, --a, --b;
    if (a > b) swap(a, b);
    edge.insert(make_pair(a, b));
    Edge[make_pair(a, b)] = c;
    gr[a].emplace_back(b, c);
    gr[b].emplace_back(a, c);
  }
  dfs(0, 0, 0);
  int RES = 0;
  for (int idx = 0; idx < ptr; ++idx) {
    vector<int> nw = cycle[idx];
    nw.push_back(nw[0]);
    for (int i = 1; i < nw.size(); ++i) {
      int a = nw[i - 1], b = nw[i];
      if (a > b) swap(a, b);
      val[idx].push_back(Edge[make_pair(a, b)]);
      edge.erase(make_pair(a, b));
    }
  }
  for (auto v : edge) {
    RES ^= Edge[make_pair(v.first, v.second)];
  }
  for (int i = 0; i < ptr; ++i) {
    int pp = 0;
    vector<int> nw = val[i];
    for (auto v : nw) pp ^= v;
    for (int j = 0; j < nw.size(); ++j) {
      nw[j] = (pp ^ nw[j]);
    }
    val[i] = nw;
  }
  vector<int> nw(K), nww(K);
  nw[0] = 1;
  nww[0] = 1;
  for (int i = 0; i < ptr; ++i) {
    vector<int> cur(K, 0);
    for (auto v : val[i]) cur[v]++;
    nw = mult(nw, cur);
    nww = mult2(nww, cur);
  }
  int mn = inf, cnt = 0;
  for (int i = 0; i < K; ++i) {
    if (nw[i] == 0 && nww[i] == 0) continue;
    if ((i ^ RES) < mn) {
      mn = (i ^ RES);
      cnt = nw[i];
    } else if ((i ^ RES) == mn) {
      cnt += nw[i];
      cnt %= mod1;
    }
  }
  cout << mn << " " << cnt << '\n';
}
signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.precision(20);
  cout << fixed;
  int t = 1;
  for (int i = 0; i < t; ++i) {
    solve();
  }
  return 0;
}
