#include <bits/stdc++.h>
using namespace std;
long long gcd(long long a, long long b) { return b == 0 ? a : gcd(b, a % b); }
const int MAXN = 100000;
const int MOD = 1000000007;
const int MAXCYC = 42;
const int MAXBITS = 17;
void inc(int &a, int b) {
  if ((a += b) >= MOD) a -= MOD;
}
void dec(int &a, int b) {
  if ((a -= b) < 0) a += MOD;
}
int pw(int x, int n) {
  int ret = 1;
  while (true) {
    if (n & 1) ret = (long long)ret * x % MOD;
    if ((n >>= 1) == 0) return ret;
    x = (long long)x * x % MOD;
  }
}
int n, m;
vector<pair<int, int>> adj[MAXN];
int preidx[MAXN], npre;
int par[MAXN], parlen[MAXN];
vector<int> cyc[MAXCYC];
int ncyc;
void dfs(int at) {
  preidx[at] = npre++;
  for (int i = (0); i < (((int)(adj[at]).size())); ++i) {
    int to = adj[at][i].first, len = adj[at][i].second;
    if (to == par[at]) continue;
    if (preidx[to] != -1) {
      if (preidx[to] < preidx[at]) {
        assert(ncyc < MAXCYC);
        cyc[ncyc].clear();
        cyc[ncyc].push_back(len);
        for (int x = at; x != to; x = par[x]) cyc[ncyc].push_back(parlen[x]);
        ++ncyc;
      }
      continue;
    } else {
      par[to] = at, parlen[to] = len;
      dfs(to);
    }
  }
}
void whtmod(int *a, int nbits) {
  for (int bit = (0); bit < (nbits); ++bit)
    for (int off = 0; off < (1 << nbits); off += 2 << bit)
      for (int i = (0); i < (1 << bit); ++i) {
        int x = a[off + i], y = a[off + (1 << bit) + i];
        a[off + i] = a[off + (1 << bit) + i] = x;
        inc(a[off + i], y);
        dec(a[off + (1 << bit) + i], y);
      }
}
void whtll(long long *a, int nbits) {
  for (int bit = (0); bit < (nbits); ++bit)
    for (int off = 0; off < (1 << nbits); off += 2 << bit)
      for (int i = (0); i < (1 << bit); ++i) {
        long long x = a[off + i], y = a[off + (1 << bit) + i];
        a[off + i] = a[off + (1 << bit) + i] = x;
        a[off + i] += y;
        a[off + (1 << bit) + i] -= y;
      }
}
long long acan[1 << MAXBITS];
int aways[1 << MAXBITS];
long long bcan[1 << MAXBITS];
int bways[1 << MAXBITS];
pair<int, int> solve() {
  npre = 0;
  for (int i = (0); i < (n); ++i) preidx[i] = -1;
  ncyc = 0;
  par[0] = -1, parlen[0] = 0;
  dfs(0);
  int sum = 0;
  for (int at = (0); at < (n); ++at)
    for (int i = (0); i < (((int)(adj[at]).size())); ++i) {
      int to = adj[at][i].first, len = adj[at][i].second;
      if (at < to) sum ^= len;
    }
  memset(acan, 0, sizeof(acan));
  acan[sum] = 1;
  memset(aways, 0, sizeof(aways));
  inc(aways[sum], 1);
  whtmod(aways, MAXBITS);
  for (int i = (0); i < (ncyc); ++i) {
    memset(bcan, 0, sizeof(bcan));
    for (int j = (0); j < (((int)(cyc[i]).size())); ++j) bcan[cyc[i][j]] = 1;
    memset(bways, 0, sizeof(bways));
    for (int j = (0); j < (((int)(cyc[i]).size())); ++j)
      inc(bways[cyc[i][j]], 1);
    whtll(acan, MAXBITS);
    whtll(bcan, MAXBITS);
    for (int k = (0); k < (1 << MAXBITS); ++k) acan[k] *= bcan[k];
    whtll(acan, MAXBITS);
    for (int k = (0); k < (1 << MAXBITS); ++k) acan[k] = acan[k] != 0 ? 1 : 0;
    whtmod(bways, MAXBITS);
    for (int k = (0); k < (1 << MAXBITS); ++k)
      aways[k] = (long long)aways[k] * bways[k] % MOD;
  }
  whtmod(aways, MAXBITS);
  int mlt = pw(1 << MAXBITS, MOD - 2);
  for (int k = (0); k < (1 << MAXBITS); ++k)
    aways[k] = (long long)aways[k] * mlt % MOD;
  for (int k = (0); k < (1 << MAXBITS); ++k)
    if (acan[k]) return make_pair(k, aways[k]);
}
void run() {
  scanf("%d%d", &n, &m);
  for (int i = (0); i < (m); ++i) {
    int a, b, c;
    scanf("%d%d%d", &a, &b, &c);
    --a, --b;
    adj[a].push_back(make_pair(b, c));
    adj[b].push_back(make_pair(a, c));
  }
  pair<int, int> ans = solve();
  printf("%d %d\n", ans.first, ans.second);
}
int main() {
  run();
  return 0;
}
