#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100100;
const int SIZE = 1 << 17, MOD = 1000000007, INV = 742744451;
int onCycle[MAXN];
vector<int> adj[MAXN];
vector<int> adjW[MAXN];
vector<vector<int>> cycles;
int par[MAXN], weights[MAXN];
int sPtr;
int add(int a, int b) {
  a += b;
  if (a >= MOD) a -= MOD;
  return a;
}
int sub(int a, int b) {
  a -= b;
  if (a < 0) a += MOD;
  return a;
}
int mult(long long int a, long long int b) {
  a *= b;
  a %= MOD;
  return (int)a;
}
void dfs(int u, int p) {
  onCycle[u] = 1;
  for (int ii = 0; ii < (int)adj[u].size(); ++ii) {
    int v = adj[u][ii];
    int we = adjW[u][ii];
    if (v == p) continue;
    if (onCycle[v] == 1) {
      vector<int> addCycle;
      int cur = u;
      while (cur != v) {
        addCycle.push_back(weights[cur]);
        cur = par[cur];
      }
      addCycle.push_back(we);
      cycles.push_back(addCycle);
    } else if (onCycle[v] == 0) {
      weights[v] = we;
      par[v] = u;
      dfs(v, u);
    }
  }
  onCycle[u] = 2;
}
vector<int> fftXOR(vector<int> &arr, int n, bool invert) {
  vector<int> ans = arr;
  for (int b = 1; b < n; b <<= 1) {
    for (int i = 0; i < n; ++i) {
      if ((i & b) != 0) continue;
      long long int u = ans[i], v = ans[i + b];
      ans[i] = add(u, v);
      ans[i + b] = sub(u, v);
    }
  }
  if (invert) {
    for (int i = 0; i < n; i++) ans[i] = mult(ans[i], INV);
  }
  return ans;
}
vector<int> multXOR(vector<int> &a1, vector<int> &a2) {
  a1 = fftXOR(a1, SIZE, false);
  a2 = fftXOR(a2, SIZE, false);
  for (int i = 0; i < (int)a1.size(); ++i) {
    a1[i] = mult(a1[i], a2[i]);
  }
  a1 = fftXOR(a1, SIZE, true);
  return a1;
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  int totalCost = 0;
  int n, m;
  cin >> n >> m;
  for (int i = 0; i < m; ++i) {
    int u, v, we;
    cin >> u >> v >> we;
    --u;
    --v;
    adj[u].push_back(v);
    adjW[u].push_back(we);
    adj[v].push_back(u);
    adjW[v].push_back(we);
    totalCost ^= we;
  }
  for (int i = 0; i < n; ++i) onCycle[i] = 0;
  for (int i = 0; i < n; ++i) {
    if (onCycle[i] == 0) {
      sPtr = 0;
      dfs(i, -1);
    }
  }
  vector<int> curWays(SIZE);
  vector<int> numWays(SIZE);
  curWays[0] = 1;
  numWays[0] = 1;
  for (int i = 0; i < (int)cycles.size(); ++i) {
    vector<int> nxt(SIZE);
    vector<int> nxt2(SIZE);
    vector<int> curCycle = cycles[i];
    for (int x : curCycle) {
      nxt2[x] = 1;
      nxt[x]++;
    }
    curWays = multXOR(curWays, nxt);
    numWays = multXOR(numWays, nxt2);
  }
  int min = (int)2e9;
  long long int ways = 1;
  for (int i = 0; i < SIZE; ++i) {
    if (numWays[i] == 0) continue;
    int gets = totalCost ^ i;
    if (gets <= min) {
      if (gets < min) {
        min = gets;
        ways = curWays[i];
      } else {
        ways = add(ways, curWays[i]);
      }
    }
  }
  cout << min << " " << ways << endl;
  return 0;
}
