#include<iostream>
#include<cstdio>
#include<vector>
const int N=1e5+5,M=44;
typedef long long ll;
const ll mod=1e9+7,inv2=(mod+1)/2;
void FWT(ll *a,int n,bool inv=0) {
    int x,y;
    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++) {
                x=a[j+k];y=a[i+j+k];
                a[j+k]=(x+y)%mod;a[i+j+k]=(x+mod-y)%mod;
                if(inv) a[j+k]=1LL*a[j+k]*inv2%mod,a[i+j+k]=1LL*a[i+j+k]*inv2%mod;
            }
}
std::vector<int> g[N];
std::vector<int> bcc[N],val[N];
struct Edge {
    int u,v,w;
    void input() {
        scanf("%d%d%d",&u,&v,&w);
    }
}e[N+M];
int dfn[N],low[N],stk[N],top,tot,cnt,n,m,blg[N];
void tarjan(int u,int fa) {
    dfn[u]=low[u]=++tot;stk[top++]=u;
    for(int v:g[u]) {
        if(!dfn[v]) tarjan(v,u),low[u]=std::min(low[v],low[u]);
        else low[u]=std::min(low[u],dfn[v]);
    }
    if(low[u]!=dfn[u]) return;
    ++cnt;
    while(1) {
        int v=stk[--top];
        blg[v]=cnt;
        bcc[cnt].push_back(v);
        if(v==u) break;
    }
}
ll f[N<<2],h[N<<2];
int main() {
    scanf("%d%d",&n,&m);
    int mx=0;
    for(int i=1;i<=m;i++) {
        e[i].input();
        g[e[i].u].push_back(e[i].v);
        g[e[i].v].push_back(e[i].u);
        mx=std::max(mx,e[i].w);
    }
    for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i,i);
    int ans=0;
    int len=1;
    while(len<=mx) len<<=1;
    for(int i=1,u,v;i<=m;i++) {
        u=e[i].u;
        v=e[i].v;
        if(blg[u]!=blg[v]) ans^=e[i].w;
        else val[blg[u]].push_back(e[i].w);
    }
    f[ans]++;
    FWT(f,len);
    for(int i=1;i<=cnt;i++) if(val[i].size()>1) {
        for(int j=0;j<len;j++) h[j]=0;
        int t=0;
        for(int v:val[i]) t^=v;
        for(int v:val[i]) h[t^v]++;
        FWT(h,len);
        for(int j=0;j<len;j++) f[j]=f[j]*h[j]%mod;
    }
    FWT(f,len,1);
    for(int i=0;i<len;i++) if(f[i]) {
        printf("%d %lld\n",i,f[i]);
        break;
    }
    return 0;
}


#include<iostream>
#include<cstdio>
#include<vector>
const int N=1e5+5,M=44;
typedef long long ll;
const ll mod=1e9+7,inv2=(mod+1)/2;
void FWT(ll *a,int n,bool inv=0) {
    int x,y;
    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++) {
                x=a[j+k];y=a[i+j+k];
                a[j+k]=(x+y)%mod;a[i+j+k]=(x+mod-y)%mod;
                if(inv) a[j+k]=1LL*a[j+k]*inv2%mod,a[i+j+k]=1LL*a[i+j+k]*inv2%mod;
            }
}
std::vector<int> g[N];
std::vector<int> bcc[N],val[N];
struct Edge {
    int u,v,w;
    void input() {
        scanf("%d%d%d",&u,&v,&w);
    }
}e[N+M];
int dfn[N],low[N],stk[N],top,tot,cnt,n,m,blg[N];
void tarjan(int u,int fa) {
    dfn[u]=low[u]=++tot;stk[top++]=u;
    for(int v:g[u]) if(v!=fa) {
        if(!dfn[v]) tarjan(v,u),low[u]=std::min(low[v],low[u]);
        else low[u]=std::min(low[u],dfn[v]);
    }
    if(low[u]!=dfn[u]) return;
    ++cnt;
    while(1) {
        int v=stk[--top];
        blg[v]=cnt;
        bcc[cnt].push_back(v);
        if(v==u) break;
    }
}
ll f[N<<2],h[N<<2];
int main() {
    scanf("%d%d",&n,&m);
    int mx=0;
    for(int i=1;i<=m;i++) {
        e[i].input();
        g[e[i].u].push_back(e[i].v);
        g[e[i].v].push_back(e[i].u);
        mx=std::max(mx,e[i].w);
    }
    for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i,i);
    int ans=0;
    int len=1;
    while(len<=mx) len<<=1;
    for(int i=1,u,v;i<=m;i++) {
        u=e[i].u;
        v=e[i].v;
        if(blg[u]!=blg[v]) ans^=e[i].w;
        else val[blg[u]].push_back(e[i].w);
    }
    f[ans]++;
    FWT(f,len);
    for(int i=1;i<=cnt;i++) if(val[i].size()>1) {
        for(int j=0;j<len;j++) h[j]=0;
        int t=0;
        for(int v:val[i]) t^=v;
        for(int v:val[i]) h[t^v]++;
        FWT(h,len);
        for(int j=0;j<len;j++) f[j]=f[j]*h[j]%mod;
    }
    FWT(f,len,1);
    for(int i=0;i<len;i++) if(f[i]) {
        printf("%d %lld\n",i,f[i]);
        break;
    }
    return 0;
}


#include<iostream>
#include<cstdio>
#include<vector>
const int N=1e5+5,M=44;
typedef long long ll;
const ll mod=1e9+7,inv2=(mod+1)/2;
void FWT(ll *a,int n,bool inv=0) {
    int x,y;
    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++) {
                x=a[j+k];y=a[i+j+k];
                a[j+k]=(x+y)%mod;a[i+j+k]=(x+mod-y)%mod;
                if(inv) a[j+k]=a[j+k]*inv2%mod,a[i+j+k]=a[i+j+k]*inv2%mod;
            }
}
std::vector<int> g[N];
std::vector<int> bcc[N],val[N];
struct Edge {
    int u,v,w;
    void input() {
        scanf("%d%d%d",&u,&v,&w);
    }
}e[N+M];
int dfn[N],low[N],stk[N],top,tot,cnt,n,m,blg[N];
void tarjan(int u,int fa) {
    dfn[u]=low[u]=++tot;stk[top++]=u;
    for(int v:g[u]) if(v!=fa) {
        if(!dfn[v]) tarjan(v,u),low[u]=std::min(low[v],low[u]);
        else low[u]=std::min(low[u],dfn[v]);
    }
    if(low[u]!=dfn[u]) return;
    ++cnt;
    while(1) {
        int v=stk[--top];
        blg[v]=cnt;
        bcc[cnt].push_back(v);
        if(v==u) break;
    }
}
ll f[N<<2],h[N<<2];
int main() {
    scanf("%d%d",&n,&m);
    int mx=0;
    for(int i=1;i<=m;i++) {
        e[i].input();
        g[e[i].u].push_back(e[i].v);
        g[e[i].v].push_back(e[i].u);
        mx=std::max(mx,e[i].w);
    }
    for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i,i);
    int ans=0;
    int len=1;
    while(len<=mx) len<<=1;
    for(int i=1,u,v;i<=m;i++) {
        u=e[i].u;
        v=e[i].v;
        if(blg[u]!=blg[v]) ans^=e[i].w;
        else val[blg[u]].push_back(e[i].w);
    }
    f[ans]=1;
    for(int i=1;i<=cnt;i++) if(val[i].size()>1) {
        for(int j=0;j<len;j++) h[j]=0;
        int t=0;
        for(int v:val[i]) t^=v;
        for(int v:val[i]) h[t^v]=1;
        FWT(h,len);FWT(f,len);
        for(int j=0;j<len;j++) f[j]=f[j]*h[j]%mod;
        FWT(f,len,1);
        for(int j=0;j<len;j++) if(f[j]>0) f[j]=1;
    }
    int res=len;
    for(int j=0;j<len;j++) if(f[j]) {
        res=j;
        break;
    }
    for(int j=0;j<len;j++) f[j]=0;
    f[ans]++;
    FWT(f,len);
    for(int i=1;i<=cnt;i++) if(val[i].size()>1) {
        for(int j=0;j<len;j++) h[j]=0;
        int t=0;
        for(int v:val[i]) t^=v;
        for(int v:val[i]) h[t^v]++;
        FWT(h,len);
        for(int j=0;j<len;j++) f[j]=f[j]*h[j]%mod;
    }
    FWT(f,len,1);
    printf("%d %lld\n",res,f[res]);
    return 0;
}


#include <bits/stdc++.h>
#define endl '\n'

#define SZ(x) ((int)x.size())
#define ALL(V) V.begin(), V.end()
#define L_B lower_bound
#define U_B upper_bound
#define pb push_back

using namespace std;
template<class T, class T1> int chkmin(T &x, const T1 &y) { return x > y ? x = y, 1 : 0; }
template<class T, class T1> int chkmax(T &x, const T1 &y) { return x < y ? x = y, 1 : 0; }
const int MAXN = (1 << 20);

int n, m, Xor;
vector<pair<int, int> > adj[MAXN];

void read() {
	cin >> n >> m;
	for(int i = 0; i < m; i++) {
		int u, v, w;
		cin >> u >> v >> w;
		adj[u].pb({v, w});
		adj[v].pb({u, w});
		Xor ^= w;
	}
}

int par[MAXN], par_w[MAXN], d[MAXN];
bool visited[MAXN];
vector<vector<int> > c;

void dfs(int u, int pr) {
	visited[u] = true;
	for(auto e: adj[u]) {
		if(!visited[e.first]) {
			par[e.first] = u;
			par_w[e.first] = e.second;
			d[e.first] = 1 + d[u];
			dfs(e.first, u);
		} else if(pr != e.first && d[e.first] < d[u]) {
			int x = u;
			vector<int> cycle = {e.second};
			do {
				cycle.pb(par_w[x]);
				x = par[x];
			} while(x != e.first);
			c.pb(cycle);
		}
	}
}

const int mod = (int)1e9 + 7;
const int inv2 = (mod + 1) / 2;

void fft(int* a, int low, int high)
{
	if(high == low + 1)
		return;

	int len = (high - low) >> 1, mid = low + len;
	fft(a, low, mid);
	fft(a, mid, high);

	for(int i = low; i < mid; i++)
	{
		int x1 = a[i] % mod;
		int x2 = a[i + len] % mod;

		a[i] = (x1 - x2 + mod) % mod;
		a[i + len] = (x1 + x2) % mod;
	}
}

void inv_fft(int *a, int low, int high)
{
	if(high == low + 1)
		return;

	int len = (high - low) >> 1, mid = low + len;

	for(int i = low; i < mid; i++)
	{
		int y1 = a[i] % mod;
		int y2 = a[i + len] % mod;

		a[i] = ((y1 + y2) * 1ll * inv2) % mod;
		a[i + len] = ((y2 - y1 + mod) * 1ll * inv2) % mod;
	}

	inv_fft(a, low, mid);
	inv_fft(a, mid, high);
}

const int N = (1 << 17);
int ans[N], tmp[N];

void solve() {
	dfs(1, -1);
	ans[Xor] = 1;

	fft(ans, 0, N);
	for(int i = 0; i < SZ(c); i++) {
		memset(tmp, 0, sizeof(tmp));
		tmp[0] = 1;
		for(int v: c[i])
			++tmp[v];

		fft(tmp, 0, N);
		for(int i = 0; i < N; i++) {
			ans[i] = ans[i] * 1ll * tmp[i] % mod;
		}
	}

	inv_fft(ans, 0, N);

	for(int i = 0; i < N; i++) {
		if(ans[i]) {
			cout << i << " " << ans[i] << endl;
			return;
		}
	}
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	read();
	solve();
	return 0;
}


#include <bits/stdc++.h>
#define endl '\n'

#define SZ(x) ((int)x.size())
#define ALL(V) V.begin(), V.end()
#define L_B lower_bound
#define U_B upper_bound
#define pb push_back

using namespace std;
template<class T, class T1> int chkmin(T &x, const T1 &y) { return x > y ? x = y, 1 : 0; }
template<class T, class T1> int chkmax(T &x, const T1 &y) { return x < y ? x = y, 1 : 0; }
const int MAXN = (1 << 20);

int n, m, Xor;
vector<pair<int, int> > adj[MAXN];

void read() {
	cin >> n >> m;
	for(int i = 0; i < m; i++) {
		int u, v, w;
		cin >> u >> v >> w;
		adj[u].pb({v, w});
		adj[v].pb({u, w});
		Xor ^= w;
	}
}

int par[MAXN], par_w[MAXN], d[MAXN];
bool visited[MAXN];
vector<vector<int> > c;

void dfs(int u, int pr) {
	visited[u] = true;
	for(auto e: adj[u]) {
		if(!visited[e.first]) {
			par[e.first] = u;
			par_w[e.first] = e.second;
			d[e.first] = 1 + d[u];
			dfs(e.first, u);
		} else if(pr != e.first && d[e.first] < d[u]) {
			int x = u;
			vector<int> cycle = {e.second};
			do {
				cycle.pb(par_w[x]);
				x = par[x];
			} while(x != e.first);
			c.pb(cycle);
		}
	}
}

const int mod = (int)1e9 + 7;
const int inv2 = (mod + 1) / 2;

void fft(int* a, int low, int high)
{
	if(high == low + 1)
		return;

	int len = (high - low) >> 1, mid = low + len;
	fft(a, low, mid);
	fft(a, mid, high);

	for(int i = low; i < mid; i++)
	{
		int x1 = a[i] % mod;
		int x2 = a[i + len] % mod;

		a[i] = (x1 - x2 + mod) % mod;
		a[i + len] = (x1 + x2) % mod;
	}
}

void inv_fft(int *a, int low, int high)
{
	if(high == low + 1)
		return;

	int len = (high - low) >> 1, mid = low + len;

	for(int i = low; i < mid; i++)
	{
		int y1 = a[i] % mod;
		int y2 = a[i + len] % mod;

		a[i] = ((y1 + y2) * 1ll * inv2) % mod;
		a[i + len] = ((y2 - y1 + mod) * 1ll * inv2) % mod;
	}

	inv_fft(a, low, mid);
	inv_fft(a, mid, high);
}

const int N = (1 << 17);
int ans[N], tmp[N];
int ok[N];

void solve() {
	dfs(1, -1);
	ans[Xor] = 1;
	ok[Xor] = 1;

	fft(ans, 0, N);

	for(int i = 0; i < SZ(c); i++) {
		memset(tmp, 0, sizeof(tmp));
		tmp[0] = 1;
		for(int v: c[i])
			++tmp[v];

		fft(tmp, 0, N);
		fft(ok, 0, N);
		for(int i = 0; i < N; i++) {
			ans[i] = ans[i] * 1ll * tmp[i] % mod;
			ok[i] = ok[i] * 1ll * tmp[i] % mod;
		}

		inv_fft(ok, 0, N);
		for(int i = 0; i < N; i++)
			ok[i] = ok[i] != 0;
	}

	inv_fft(ans, 0, N);

	for(int i = 0; i < N; i++) {
		if(ok[i]) {
			cout << i << " " << ans[i] << endl;
			return;
		}
	}
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	read();
	solve();
	return 0;
}


#include <bits/stdc++.h>
#define endl '\n'

#define SZ(x) ((int)x.size())
#define ALL(V) V.begin(), V.end()
#define L_B lower_bound
#define U_B upper_bound
#define pb push_back

using namespace std;
template<class T, class T1> int chkmin(T &x, const T1 &y) { return x > y ? x = y, 1 : 0; }
template<class T, class T1> int chkmax(T &x, const T1 &y) { return x < y ? x = y, 1 : 0; }
const int MAXN = (1 << 20);

int n, m, Xor;
vector<pair<int, int> > adj[MAXN];

void read() {
	cin >> n >> m;
	for(int i = 0; i < m; i++) {
		int u, v, w;
		cin >> u >> v >> w;
		adj[u].pb({v, w});
		adj[v].pb({u, w});
		Xor ^= w;
	}
}

int par[MAXN], par_w[MAXN], d[MAXN];
bool visited[MAXN];
vector<vector<int> > c;
vector<vector<bool> > ok;

void dfs(int u, int pr) {
	visited[u] = true;
	for(auto e: adj[u]) {
		if(!visited[e.first]) {
			par[e.first] = u;
			par_w[e.first] = e.second;
			d[e.first] = 1 + d[u];
			dfs(e.first, u);
		} else if(pr != e.first && d[e.first] < d[u]) {
			int x = u;
			vector<int> cycle;
			do {
				cycle.pb(par_w[x]);
				x = par[x];
			} while(x != e.first);
			c.pb(cycle);
			ok.pb(vector<bool>(SZ(cycle), false));
		}
	}
}

const int mod = (int)1e9 + 7;
const int inv2 = (mod + 1) / 2;

void fft(int* a, int low, int high)
{
	if(high == low + 1)
		return;

	int len = (high - low) >> 1, mid = low + len;
	fft(a, low, mid);
	fft(a, mid, high);

	for(int i = low; i < mid; i++)
	{
		int x1 = a[i] % mod;
		int x2 = a[i + len] % mod;

		a[i] = (x1 - x2 + mod) % mod;
		a[i + len] = (x1 + x2) % mod;
	}
}

void inv_fft(int *a, int low, int high)
{
	if(high == low + 1)
		return;

	int len = (high - low) >> 1, mid = low + len;

	for(int i = low; i < mid; i++)
	{
		int y1 = a[i] % mod;
		int y2 = a[i + len] % mod;

		a[i] = ((y1 + y2) * 1ll * inv2) % mod;
		a[i + len] = ((y2 - y1 + mod) * 1ll * inv2) % mod;
	}

	inv_fft(a, low, mid);
	inv_fft(a, mid, high);
}

int N = (1 << 17);
int ans[MAXN], tmp[MAXN];

void solve() {
	dfs(1, -1);
	ans[Xor] = 1;
	fft(ans, 0, N);
	for(int i = 0; i < SZ(c); i++) {
		memset(tmp, 0, sizeof(tmp));
		tmp[0] = 1;
		for(int v: c[i])
			++tmp[v];

		fft(tmp, 0, N);
		for(int i = 0; i < N; i++) {
			ans[i] = ans[i] * 1ll * tmp[i] % mod;
		}
	}

	inv_fft(ans, 0, N);

	for(int i = 0; i < N; i++) {
		if(ans[i]) {
			cout << i << " " << ans[i] << endl;
			return;
		}
	}
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	read();
	solve();
	return 0;
}


#include <bits/stdc++.h>
#define endl '\n'

#define SZ(x) ((int)x.size())
#define ALL(V) V.begin(), V.end()
#define L_B lower_bound
#define U_B upper_bound
#define pb push_back

using namespace std;
template<class T, class T1> int chkmin(T &x, const T1 &y) { return x > y ? x = y, 1 : 0; }
template<class T, class T1> int chkmax(T &x, const T1 &y) { return x < y ? x = y, 1 : 0; }
const int MAXN = (1 << 20);

int n, m, Xor;
vector<pair<int, int> > adj[MAXN];

void read() {
	cin >> n >> m;
	for(int i = 0; i < m; i++) {
		int u, v, w;
		cin >> u >> v >> w;
		adj[u].pb({v, w});
		adj[v].pb({u, w});
		Xor ^= w;
	}
}

int par[MAXN], par_w[MAXN], d[MAXN];
bool visited[MAXN];
vector<vector<int> > c;

void dfs(int u, int pr) {
	visited[u] = true;
	for(auto e: adj[u]) {
		if(!visited[e.first]) {
			par[e.first] = u;
			par_w[e.first] = e.second;
			d[e.first] = 1 + d[u];
			dfs(e.first, u);
		} else if(pr != e.first && d[e.first] < d[u]) {
			int x = u;
			vector<int> cycle = {e.second};
			do {
				cycle.pb(par_w[x]);
				x = par[x];
			} while(x != e.first);
			c.pb(cycle);
		}
	}
}

const int mod = (int)1e9 + 7;
const int inv2 = (mod + 1) / 2;

void fft(int* a, int low, int high)
{
	if(high == low + 1)
		return;

	int len = (high - low) >> 1, mid = low + len;
	fft(a, low, mid);
	fft(a, mid, high);

	for(int i = low; i < mid; i++)
	{
		int x1 = a[i] % mod;
		int x2 = a[i + len] % mod;

		a[i] = (x1 - x2 + mod) % mod;
		a[i + len] = (x1 + x2) % mod;
	}
}

void inv_fft(int *a, int low, int high)
{
	if(high == low + 1)
		return;

	int len = (high - low) >> 1, mid = low + len;

	for(int i = low; i < mid; i++)
	{
		int y1 = a[i] % mod;
		int y2 = a[i + len] % mod;

		a[i] = ((y1 + y2) * 1ll * inv2) % mod;
		a[i + len] = ((y2 - y1 + mod) * 1ll * inv2) % mod;
	}

	inv_fft(a, low, mid);
	inv_fft(a, mid, high);
}

const int N = (1 << 17);
int ans[N], tmp[N];
int ok[N];

void solve() {
	dfs(1, -1);
	ans[Xor] = 1;
	ok[Xor] = 1;

	fft(ans, 0, N);

	for(int i = 0; i < SZ(c); i++) {
		memset(tmp, 0, sizeof(tmp));
		for(int v: c[i])
			++tmp[v];

		fft(tmp, 0, N);
		fft(ok, 0, N);
		for(int i = 0; i < N; i++) {
			ans[i] = ans[i] * 1ll * tmp[i] % mod;
			ok[i] = ok[i] * 1ll * tmp[i] % mod;
		}

		inv_fft(ok, 0, N);
		for(int i = 0; i < N; i++)
			ok[i] = ok[i] != 0;
	}

	inv_fft(ans, 0, N);

	for(int i = 0; i < N; i++) {
		if(ok[i]) {
			cout << i << " " << ans[i] << endl;
			return;
		}
	}
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	read();
	solve();
	return 0;
}


#include <bits/stdc++.h>
#define endl '\n'

#define SZ(x) ((int)x.size())
#define ALL(V) V.begin(), V.end()
#define L_B lower_bound
#define U_B upper_bound
#define pb push_back

using namespace std;
template<class T, class T1> int chkmin(T &x, const T1 &y) { return x > y ? x = y, 1 : 0; }
template<class T, class T1> int chkmax(T &x, const T1 &y) { return x < y ? x = y, 1 : 0; }
const int MAXN = (1 << 20);

int n, m, Xor;
vector<pair<int, int> > adj[MAXN];

void read() {
	cin >> n >> m;
	for(int i = 0; i < m; i++) {
		int u, v, w;
		cin >> u >> v >> w;
		adj[u].pb({v, w});
		adj[v].pb({u, w});
		Xor ^= w;
	}
}

int par[MAXN], par_w[MAXN], d[MAXN];
bool visited[MAXN];
vector<vector<int> > c;

void dfs(int u, int pr) {
	visited[u] = true;
	for(auto e: adj[u]) {
		if(!visited[e.first]) {
			par[e.first] = u;
			par_w[e.first] = e.second;
			d[e.first] = 1 + d[u];
			dfs(e.first, u);
		} else if(pr != e.first && d[e.first] < d[u]) {
			int x = u;
			vector<int> cycle;
			do {
				cycle.pb(par_w[x]);
				x = par[x];
			} while(x != e.first);
			c.pb(cycle);
		}
	}
}

const int mod = (int)1e9 + 7;
const int inv2 = (mod + 1) / 2;

void fft(int* a, int low, int high)
{
	if(high == low + 1)
		return;

	int len = (high - low) >> 1, mid = low + len;
	fft(a, low, mid);
	fft(a, mid, high);

	for(int i = low; i < mid; i++)
	{
		int x1 = a[i] % mod;
		int x2 = a[i + len] % mod;

		a[i] = (x1 - x2 + mod) % mod;
		a[i + len] = (x1 + x2) % mod;
	}
}

void inv_fft(int *a, int low, int high)
{
	if(high == low + 1)
		return;

	int len = (high - low) >> 1, mid = low + len;

	for(int i = low; i < mid; i++)
	{
		int y1 = a[i] % mod;
		int y2 = a[i + len] % mod;

		a[i] = ((y1 + y2) * 1ll * inv2) % mod;
		a[i + len] = ((y2 - y1 + mod) * 1ll * inv2) % mod;
	}

	inv_fft(a, low, mid);
	inv_fft(a, mid, high);
}

const int N = (1 << 17);
int ans[N], tmp[N];

void solve() {
	dfs(1, -1);
	ans[Xor] = 1;
	fft(ans, 0, N);
	for(int i = 0; i < SZ(c); i++) {
		memset(tmp, 0, sizeof(tmp));
		//tmp[0] = 1;
		for(int v: c[i])
			++tmp[v];

		fft(tmp, 0, N);
		for(int i = 0; i < N; i++) {
			ans[i] = ans[i] * 1ll * tmp[i] % mod;
		}
	}

	inv_fft(ans, 0, N);

	for(int i = 0; i < N; i++) {
		if(ans[i]) {
			cout << i << " " << ans[i] << endl;
			return;
		}
	}
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	read();
	solve();
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1<<17;
const int MOD = 1e9+7;
struct Edge{
    int u,v,w;
}e[N];
int fpow(int x,int p){
    int res=1;
    while(p){
        if(p&1) res=1LL*res*x%MOD;
        x=1LL*x*x%MOD; p>>=1;
    }
    return res;
}
void FWT_XOR(int *a,int n,int opt){
    int inv2 = fpow(2,MOD-2);
    for(int i=1;i<n;i<<=1){
        for(int j=0,p=(i<<1);j<n;j+=p){
            for(int k=0;k<i;++k){
                int X=a[j+k],Y=a[i+j+k];
                a[j+k]=(X+Y)%MOD;a[i+j+k]=(X+MOD-Y)%MOD;
                if(opt==-1)a[j+k]=1LL*a[j+k]*inv2%MOD,a[i+j+k]=1LL*a[i+j+k]*inv2%MOD;
            }
        }
    }
}
vector<int> g[N];
int vis[N],d[N]; bool used[N];
int a[N],b[N],c[N],n,m,p;
int dfs(int u){
    vis[u]=1; d[u]=p; int rs=-1;
    for(auto i:g[u]){
        if(used[i]) continue; used[i]=true;
        int v=e[i].u^e[i].v^u;
        if(vis[v]==0){
            rs=dfs(v);
            if(rs==-1) continue;
            c[e[i].w]++;
            if(rs==d[u]){
                FWT_XOR(c,1<<17,1);
                for(int i=0;i<(1<<17);++i){
                    a[i]=1LL*a[i]*c[i]%MOD;
                    b[i]=1LL*b[i]*c[i]%MOD;
                }
                FWT_XOR(b,1<<17,-1);
                for(int i=0;i<(1<<17);++i) b[i]=b[i]>0?1:0;
                FWT_XOR(b,1<<17,1); rs=-1;
            }
            break;
        }else if(vis[v]==1){
            memset(c,0,sizeof(c)); c[e[i].w]++;
            rs=d[v]; break;
        }else continue;
    }
    vis[u]=2; --p; return rs;
}

int main(){
    scanf("%d %d",&n,&m); int x=0;
    for(int i=1;i<=m;++i){
        scanf("%d %d %d",&e[i].u,&e[i].v,&e[i].w);
        g[e[i].u].push_back(i);
        g[e[i].v].push_back(i); x^=e[i].w;
    }
    a[x]++; FWT_XOR(a,1<<17,1);
    b[x]++; FWT_XOR(b,1<<17,1);
    for(int i=1;i<=n;++i){
        if(vis[i]) continue;
        p=0; dfs(i);
    }
    FWT_XOR(a,1<<17,-1); FWT_XOR(b,1<<17,1);
    for(int i=0;i<(1<<17);++i){
        if(b[i]){
            printf("%d %d\n",i,a[i]);
            break;
        }
    }
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1<<17;
const int MOD = 1e9+7;
struct Edge{
    int u,v,w;
}e[N];
int fpow(int x,int p){
    int rs=1;
    while(p){
        if(p&1) rs=1LL*rs*x%MOD;
        x=1LL*x*x%MOD; p>>=1;
    }
    return rs;
}
void FWT_XOR(int *a,int n,int opt){
    int inv2 = fpow(2,MOD-2);
    for(int i=1;i<n;i<<=1){
        for(int j=0,p=(i<<1);j<n;j+=p){
            for(int k=0;k<i;++k){
                int X=a[j+k],Y=a[i+j+k];
                a[j+k]=(X+Y)%MOD;a[i+j+k]=(X+MOD-Y)%MOD;
                if(opt==-1)a[j+k]=1LL*a[j+k]*inv2%MOD,a[i+j+k]=1LL*a[i+j+k]*inv2%MOD;
            }
        }
    }
}
vector<int> g[N];
int vis[N]; bool used[N];
int a[N],b[N],c[N],n,m;
int dfs(int u){
    int rs=-1; vis[u]=1;
    while(g[u].size()){
        int i=g[u][g[u].size()-1]; g[u].pop_back();
        if(used[i]) continue; used[i]=true;
        int v=e[i].u^e[i].v^u;
        if(!vis[v]){
            if((rs=dfs(v))==-1) continue;
            c[e[i].w]++;
            if(rs==u){
                FWT_XOR(c,1<<17,1);
                for(int i=0;i<(1<<17);++i){
                    a[i]=1LL*a[i]*c[i]%MOD;
                    b[i]=1LL*b[i]*c[i]%MOD;
                }
                FWT_XOR(b,1<<17,-1);
                for(int i=0;i<(1<<17);++i) b[i]=b[i]?1:0;
                FWT_XOR(b,1<<17,1); rs=-1;
            }else break;
        }else{
            memset(c,0,sizeof(c)); c[e[i].w]++;
            rs=v; break;
        }
    }
    vis[u]=0; return rs;
}

int main(){
    scanf("%d %d",&n,&m); int x=0;
    for(int i=1;i<=m;++i){
        scanf("%d %d %d",&e[i].u,&e[i].v,&e[i].w);
        g[e[i].u].push_back(i);
        g[e[i].v].push_back(i); x^=e[i].w;
    }
    a[x]++; FWT_XOR(a,1<<17,1);
    b[x]++; FWT_XOR(b,1<<17,1);
    for(int i=1;i<=n;++i) dfs(i);
    FWT_XOR(a,1<<17,-1); FWT_XOR(b,1<<17,1);
    for(int i=0;i<(1<<17);++i){
        if(b[i]){
            printf("%d %d\n",i,a[i]);
            break;
        }
    }
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1<<17;
const int MOD = 1e9+7;
struct Edge{
    int u,v,w;
}e[N];
int fpow(int x,int p){
    int rs=1;
    while(p){
        if(p&1) rs=1LL*rs*x%MOD;
        x=1LL*x*x%MOD; p>>=1;
    }
    return rs;
}
void FWT_XOR(int *a,int n,int opt){
    int inv2 = fpow(2,MOD-2);
    for(int i=1;i<n;i<<=1){
        for(int j=0,p=(i<<1);j<n;j+=p){
            for(int k=0;k<i;++k){
                int X=a[j+k],Y=a[i+j+k];
                a[j+k]=(X+Y)%MOD;a[i+j+k]=(X+MOD-Y)%MOD;
                if(opt==-1)a[j+k]=1LL*a[j+k]*inv2%MOD,a[i+j+k]=1LL*a[i+j+k]*inv2%MOD;
            }
        }
    }
}
vector<int> g[N];
int vis[N]; bool used[N];
int a[N],b[N],c[N],n,m;
int dfs(int u){
    vis[u]=1; int rs=-1;
    for(auto i:g[u]){
        if(used[i]) continue; used[i]=true;
        int v=e[i].u^e[i].v^u;
        if(vis[v]==0){
            if((rs=dfs(v))==-1) continue;
            c[e[i].w]++;
            if(rs==u){
                FWT_XOR(c,1<<17,1);
                for(int i=0;i<(1<<17);++i){
                    a[i]=1LL*a[i]*c[i]%MOD;
                    b[i]=1LL*b[i]*c[i]%MOD;
                }
                FWT_XOR(b,1<<17,-1);
                for(int i=0;i<(1<<17);++i) b[i]=b[i]?1:0;
                FWT_XOR(b,1<<17,1); rs=-1;
            }
        }else if(vis[v]==1){
            memset(c,0,sizeof(c)); c[e[i].w]++;
            rs=v; break;
        }
    }
    vis[u]=2; return rs;
}

int main(){
    scanf("%d %d",&n,&m); int x=0;
    for(int i=1;i<=m;++i){
        scanf("%d %d %d",&e[i].u,&e[i].v,&e[i].w);
        g[e[i].u].push_back(i);
        g[e[i].v].push_back(i); x^=e[i].w;
    }
    a[x]++; FWT_XOR(a,1<<17,1);
    b[x]++; FWT_XOR(b,1<<17,1);
    for(int i=1;i<=n;++i){
        if(vis[i]) continue; dfs(i);
    }
    FWT_XOR(a,1<<17,-1); FWT_XOR(b,1<<17,1);
    for(int i=0;i<(1<<17);++i){
        if(b[i]){
            printf("%d %d\n",i,a[i]);
            break;
        }
    }
}


#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using Vi = vector<int>;
using Pii = pair<int,int>;
#define pb push_back
#define x first
#define y second
#define rep(i,b,e) for(int i=(b); i<(e); i++)
#define each(a,x) for(auto& a : (x))
#define all(x) (x).begin(), (x).end()
#define sz(x) int((x).size())

#define tem template<class t,class u,class...w>
#define pri(x,y)tem auto operator<<(t& o, u a)->decltype(x,o) { o << y; return o; }
pri(a.print(),"{";a.print();o<<"}");
pri(a.y,"("<<a.x<<", "<<a.y<<")");
pri(all(a),"[";auto d="";for(auto i : a)(o << d << i, d=", "); o << "]");
void DD(...){}
tem void DD(t s, u a, w... k) {
	int b = 44;
	while (*s && *s != b) {
		b += (*s == 40 ? 50 : *s == 41 ? -50 : 0);
		cerr << *s++;
	}
	cerr << ": " << a << *s++; DD(s, k...);
}
tem vector<t> span(const t* a, u n) { return {a, a+n}; }
#ifdef LOC
#define deb(...) (DD("#, "#__VA_ARGS__, __LINE__, __VA_ARGS__), cerr << endl)
#else
#define deb(...)
#endif
#define DBP(...) void print() { DD(#__VA_ARGS__, __VA_ARGS__); }

constexpr int MOD = 1e9+7;
constexpr int MAX_W = 1<<17;

vector<vector<Pii>> G;
vector<Pii> par;
Vi depth;
vector<vector<ll>> options;

ll modInv(ll a, ll m) {
	if (a == 1) return 1;
	return ((a - modInv(m%a, a))*m + 1) / a;
}

void dfs(int v) {
	each(e, G[v]) {
		if (par[e.x].y == -1) {
			par[e.x] = {v, e.y};
			depth[e.x] = depth[v]+1;
			dfs(e.x);
		} else if (depth[e.x] > depth[v]+1) {
			options.emplace_back(MAX_W);
			auto& out = options.back();
			out[e.y]++;
			for (int u = e.x; u != v; u = par[u].x) {
				out[par[u].y]++;
			}
		}
	}
}

template<bool inv, bool doMod>
void fwht(vector<ll>& a) {
	for (int n = sz(a), step = 1; step < n; step *= 2) {
		for (int i = 0; i < n; i += 2*step) {
			rep(j, i, i+step) {
				ll &u = a[j], &v = a[j+step];
				tie(u, v) = pair<ll, ll>(u+v, u-v);
				if (doMod) {
					u %= MOD;
					v %= MOD;
				}
			}
		}
	}
	if (inv) {
		if (doMod) {
			ll mult = modInv(sz(a), MOD);
			each(x, a) x = x*mult % MOD;
		} else {
			each(x, a) x /= sz(a);
		}
	}
}

void convMod(vector<ll>& a, vector<ll>& b) {
	rep(i, 0, sz(a)) a[i] = a[i]*b[i] % MOD;
}

void convOnes(vector<ll>& a, vector<ll>& b) {
	each(x, a) x = (x != 0);
	fwht<0, 0>(a);
	rep(i, 0, sz(a)) a[i] = a[i]*b[i] % MOD;
	fwht<1, 0>(a);
}

void printUsed(vector<ll>& vec) {
	rep(i, 0, sz(vec)) {
		if (vec[i]) cout << i << ' ';
	}
	cout << '\n';
}

int main() {
	cin.sync_with_stdio(0); cin.tie(0);
	cout << fixed << setprecision(18);

	int n, m; cin >> n >> m;
	int full = 0;
	G.resize(n);

	rep(i, 0, m) {
		int u, v, w; cin >> u >> v >> w;
		u--; v--;
		G[u].pb({v, w});
		G[v].pb({u, w});
		full ^= w;
	}

	if (m == n-1) {
		cout << full << '\n';
		return 0;
	}

	par.resize(n, {-1,-1});
	depth.resize(n);
	par[0].y = 0;
	dfs(0);

	vector<ll> ones = options[0], kek = options[0];
	fwht<0, 1>(kek);

	rep(i, 1, sz(options)) {
		fwht<0, 0>(options[i]);
		convOnes(ones, options[i]);
		convMod(kek, options[i]);
	}

	each(x, ones) x = (x != 0);
	fwht<1, 1>(kek);
	ll bestCost = INT64_MAX, ways = 0;

	rep(i, 0, sz(ones)) {
		if (!ones[i]) continue;
		if ((i^full) < bestCost) {
			bestCost = i^full;
			ways = kek[i];
		}
	}

	ways %= MOD;
	if (ways < 0) ways += MOD;
	cout << bestCost << ' ' << ways << '\n';
}


#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using Vi = vector<int>;
using Pii = pair<int,int>;
#define pb push_back
#define x first
#define y second
#define rep(i,b,e) for(int i=(b); i<(e); i++)
#define each(a,x) for(auto& a : (x))
#define all(x) (x).begin(), (x).end()
#define sz(x) int((x).size())

#define tem template<class t,class u,class...w>
#define pri(x,y)tem auto operator<<(t& o, u a)->decltype(x,o) { o << y; return o; }
pri(a.print(),"{";a.print();o<<"}");
pri(a.y,"("<<a.x<<", "<<a.y<<")");
pri(all(a),"[";auto d="";for(auto i : a)(o << d << i, d=", "); o << "]");
void DD(...){}
tem void DD(t s, u a, w... k) {
	int b = 44;
	while (*s && *s != b) {
		b += (*s == 40 ? 50 : *s == 41 ? -50 : 0);
		cerr << *s++;
	}
	cerr << ": " << a << *s++; DD(s, k...);
}
tem vector<t> span(const t* a, u n) { return {a, a+n}; }
#ifdef LOC
#define deb(...) (DD("#, "#__VA_ARGS__, __LINE__, __VA_ARGS__), cerr << endl)
#else
#define deb(...)
#endif
#define DBP(...) void print() { DD(#__VA_ARGS__, __VA_ARGS__); }

constexpr int MOD = 1e9+7;
constexpr int MAX_W = 1<<17;

vector<vector<Pii>> G;
vector<Pii> par;
Vi depth;
vector<vector<ll>> options;

ll modInv(ll a, ll m) {
	if (a == 1) return 1;
	return ((a - modInv(m%a, a))*m + 1) / a;
}

void dfs(int v) {
	each(e, G[v]) {
		if (par[e.x].y == -1) {
			par[e.x] = {v, e.y};
			depth[e.x] = depth[v]+1;
			dfs(e.x);
		} else if (depth[e.x] > depth[v]+1) {
			options.emplace_back(MAX_W);
			auto& out = options.back();
			out[e.y]++;
			for (int u = e.x; u != v; u = par[u].x) {
				out[par[u].y]++;
			}
		}
	}
}

template<bool inv, bool doMod>
void fwht(vector<ll>& a) {
	for (int n = sz(a), step = 1; step < n; step *= 2) {
		for (int i = 0; i < n; i += 2*step) {
			rep(j, i, i+step) {
				ll &u = a[j], &v = a[j+step];
				tie(u, v) = pair<ll, ll>(u+v, u-v);
				if (doMod) {
					u %= MOD;
					v %= MOD;
				}
			}
		}
	}
	if (inv) {
		if (doMod) {
			ll mult = modInv(sz(a), MOD);
			each(x, a) x = x*mult % MOD;
		} else {
			each(x, a) x /= sz(a);
		}
	}
}

void convMod(vector<ll>& a, vector<ll> b) {
	fwht<0, 1>(a);
	fwht<0, 1>(b);
	rep(i, 0, sz(a)) a[i] = a[i]*b[i] % MOD;
	fwht<1, 1>(a);
}

void convOnes(vector<ll>& a, vector<ll> b) {
	each(x, a) x = (x != 0);
	each(x, b) x = (x != 0);
	fwht<0, 0>(a);
	fwht<0, 0>(b);
	rep(i, 0, sz(a)) a[i] = a[i]*b[i] % MOD;
	fwht<1, 0>(a);
}

void printUsed(vector<ll>& vec) {
	rep(i, 0, sz(vec)) {
		if (vec[i]) cout << i << ' ';
	}
	cout << '\n';
}

int main() {
	cin.sync_with_stdio(0); cin.tie(0);
	cout << fixed << setprecision(18);

	int n, m; cin >> n >> m;
	int full = 0;
	G.resize(n);

	rep(i, 0, m) {
		int u, v, w; cin >> u >> v >> w;
		u--; v--;
		G[u].pb({v, w});
		G[v].pb({u, w});
		full ^= w;
	}

	if (m == n-1) {
		cout << full << '\n';
		return 0;
	}

	par.resize(n, {-1,-1});
	depth.resize(n);
	par[0].y = 0;
	dfs(0);

	vector<ll> ones = options[0], kek = options[0];

	rep(i, 1, sz(options)) {
		convOnes(ones, options[i]);
		convMod(kek, options[i]);
	}

	ll bestCost = INT64_MAX, ways = 0;

	rep(i, 0, sz(ones)) {
		if (!ones[i]) continue;
		if ((i^full) < bestCost) {
			bestCost = i^full;
			ways = kek[i];
		}
	}

	ways %= MOD;
	if (ways < 0) ways += MOD;
	cout << bestCost << ' ' << ways << '\n';
}


#include <bits/stdc++.h>
using namespace std;

using ll = long long;
using pii = pair<int, int>;
#define x first
#define y second

const int N = 100005, SZ = 131072, L = 17;
ll M = ll(1e9) + 7, ISZ = 742744451;

int Rev(int x) {
    int i, r = 0;
    for (i = 0; i < L; i++) {
        r = r << 1 | x & 1;
        x >>= 1;
    }
    return r;
}

void FFT(ll *a, bool f) {
    int i, j, k, z;
    for (i = 0; i < SZ; i++) {
        j = Rev(i);
        if (i < j) {
            z = a[i];
            a[i] = a[j];
            a[j] = z;
        }
    }
    for (i = 1; i < SZ; i <<= 1) for (j = 0; j < SZ; j += i << 1) for (k = 0; k < i; k++) {
        z = a[i + j + k];
        a[i + j + k] = (a[j + k] - z + M) % M;
        (a[j + k] += z) %= M;
    }
    if (f) for (i = 0; i < SZ; i++) a[i] = a[i] * ISZ % M;
}

int n, m, p[N], tt;
vector<pii> e[N];
ll a[SZ], b[SZ], aa[SZ], bb[SZ];

int f(int x){
    if(x == p[x]) return x;
    return p[x] = f(p[x]);
}

int g(int x, int y, int z){
    if(x == z) return 1;
    for(pii &i : e[x]){
        if(i.x == y) continue;
        if(!g(i.x, x, z)) continue;
        b[i.y]++;
        return 1;
    }
    return 0;
}

void h(){
    FFT(b, 0);
    for(int i = 0; i < SZ; i++) (a[i] *= b[i]) %= M;
}

int main(){ ios_base::sync_with_stdio(0); cin.tie(0);
    cin >> n >> m;
    iota(p, p+n+1, 0);
    a[0] = aa[0] = 1;
    FFT(a, 0);
    for(int x, y, z; m--; ){
        cin >> x >> y >> z;
        tt ^= z;
        if(f(x) != f(y)){
            p[f(y)] = f(x);
            e[x].emplace_back(y, z);
            e[y].emplace_back(x, z);
        }
        else{
            memset(b, 0, sizeof(b));
            b[z]++;
            g(x, 0, y);
            h();
        }
    }
    memset(b, 0, sizeof(b));
    b[tt] = 1;
    h();
    FFT(a, 1);
    for(int i = 0; ; i++) if(a[i]){
        cout << i << ' ' << a[i] << '\n';
        return 0;
    }
}


#include <bits/stdc++.h>
using namespace std;

using ll = long long;
using pii = pair<int, int>;
#define x first
#define y second

const int N = 100005, SZ = 131072, L = 17;
ll M = ll(1e9) + 7, MM = 998244353, ISZ = 742744451, ISZZ = 998236737;

int Rev(int x) {
    int i, r = 0;
    for (i = 0; i < L; i++) {
        r = r << 1 | x & 1;
        x >>= 1;
    }
    return r;
}

void FFT(ll *a, bool f, ll M, ll ISZ) {
    int i, j, k, z;
    for (i = 0; i < SZ; i++) {
        j = Rev(i);
        if (i < j) {
            z = a[i];
            a[i] = a[j];
            a[j] = z;
        }
    }
    for (i = 1; i < SZ; i <<= 1) for (j = 0; j < SZ; j += i << 1) for (k = 0; k < i; k++) {
        z = a[i + j + k];
        a[i + j + k] = (a[j + k] - z + M) % M;
        (a[j + k] += z) %= M;
    }
    if (f) for (i = 0; i < SZ; i++) a[i] = a[i] * ISZ % M;
}

int n, m, p[N], tt;
vector<pii> e[N];
ll a[SZ], b[SZ], aa[SZ], bb[SZ];

int f(int x){
    if(x == p[x]) return x;
    return p[x] = f(p[x]);
}

int g(int x, int y, int z){
    if(x == z) return 1;
    for(pii &i : e[x]){
        if(i.x == y) continue;
        if(!g(i.x, x, z)) continue;
        b[i.y]++;
        return 1;
    }
    return 0;
}

void h(){
    memcpy(bb, b, sizeof(b));
    FFT(b, 0, M, ISZ);
    FFT(bb, 0, MM, ISZZ);
    for(int i = 0; i < SZ; i++) (a[i] *= b[i]) %= M;
    for(int i = 0; i < SZ; i++) (aa[i] *= bb[i]) %= MM;
}

int main(){ ios_base::sync_with_stdio(0); cin.tie(0);
    cin >> n >> m;
    iota(p, p+n+1, 0);
    a[0] = aa[0] = 1;
    FFT(a, 0, M, ISZ);
    FFT(aa, 0, MM, ISZZ);
    for(int x, y, z; m--; ){
        cin >> x >> y >> z;
        tt ^= z;
        if(f(x) != f(y)){
            p[f(y)] = f(x);
            e[x].emplace_back(y, z);
            e[y].emplace_back(x, z);
        }
        else{
            memset(b, 0, sizeof(b));
            b[z]++;
            g(x, 0, y);
            h();
        }
    }
    memset(b, 0, sizeof(b));
    b[tt] = 1;
    h();
    FFT(a, 1, M, ISZ);
    FFT(aa, 1, MM, ISZZ);
    for(int i = 0; ; i++) if(a[i] || aa[i]){
        cout << i << ' ' << a[i] << '\n';
        return 0;
    }
}


#include <bits/stdc++.h>
using namespace std;

using ll = long long;
using pii = pair<int, int>;
#define x first
#define y second

const int N = 100005, SZ = 131072, L = 17;
ll M = ll(1e9) + 7, ISZ = 742744451;

int Rev(int x) {
    int i, r = 0;
    for (i = 0; i < L; i++) {
        r = r << 1 | x & 1;
        x >>= 1;
    }
    return r;
}

void FFT(ll *a, bool f) {
    int i, j, k, z;
    for (i = 0; i < SZ; i++) {
        j = Rev(i);
        if (i < j) {
            z = a[i];
            a[i] = a[j];
            a[j] = z;
        }
    }
    for (i = 1; i < SZ; i <<= 1) for (j = 0; j < SZ; j += i << 1) for (k = 0; k < i; k++) {
        z = a[i + j + k];
        a[i + j + k] = a[j + k] - z;
        a[j + k] += z;
    }
    for(int i = 0; i < SZ; i++) a[i] = (a[i] % M + M) % M;
    if (f) for (i = 0; i < SZ; i++) a[i] = a[i] * ISZ % M;
}

void mult(ll *a, ll *b){
    FFT(a, 0);
    FFT(b, 0);
    for(int i = 0; i < SZ; i++) a[i] = (a[i] * b[i]) % M;
    FFT(a, 1);
    FFT(b, 1);
}

int n, m, p[N], tt;
vector<pii> e[N];
ll a[SZ], b[SZ], aa[SZ];

int f(int x){
    if(x == p[x]) return x;
    return p[x] = f(p[x]);
}

int g(int x, int y, int z){
    if(x == z) return 1;
    for(pii &i : e[x]){
        if(i.x == y) continue;
        if(!g(i.x, x, z)) continue;
        b[i.y]++;
        return 1;
    }
    return 0;
}

void h(){
    mult(a, b);
    mult(aa, b);
    for(int i = 0; i < SZ; i++) aa[i] = !!aa[i];
}

int main(){ ios_base::sync_with_stdio(0); cin.tie(0);
    cin >> n >> m;
    iota(p, p+n+1, 0);
    a[0] = aa[0] = 1;
    for(int x, y, z; m--; ){
        cin >> x >> y >> z;
        tt ^= z;
        if(f(x) != f(y)){
            p[f(y)] = f(x);
            e[x].emplace_back(y, z);
            e[y].emplace_back(x, z);
        }
        else{
            memset(b, 0, sizeof(b));
            b[z]++;
            g(x, 0, y);
            h();
        }
    }
    memset(b, 0, sizeof(b));
    b[tt] = 1;
    h();
    for(int i = 0; ; i++) if(aa[i]){
        cout << i << ' ' << a[i] << '\n';
        return 0;
    }
}


#include <bits/stdc++.h>
using namespace std;

using ll = long long;
using pii = pair<int, int>;
#define x first
#define y second

const int N = 100005, SZ = 131072, L = 17;
ll M = ll(1e9) + 7, ISZ = 742744451;

int Rev(int x) {
    int i, r = 0;
    for (i = 0; i < L; i++) {
        r = r << 1 | x & 1;
        x >>= 1;
    }
    return r;
}

void FFT(ll *a, bool f) {
    int i, j, k, z;
    for (i = 0; i < SZ; i++) {
        j = Rev(i);
        if (i < j) {
            z = a[i];
            a[i] = a[j];
            a[j] = z;
        }
    }
    for (i = 1; i < SZ; i <<= 1) for (j = 0; j < SZ; j += i << 1) for (k = 0; k < i; k++) {
        z = a[i + j + k];
        a[i + j + k] = a[j + k] - z;
        (a[j + k] += z) %= M;
    }
    for(i = 0; i < SZ; i++) a[i] = (a[i] % M + M) % M;
    if (f) for (i = 0; i < SZ; i++) a[i] = a[i] * ISZ % M;
}

void mult(ll *a, ll *b){
    FFT(a, 0);
    FFT(b, 0);
    for(int i = 0; i < SZ; i++) a[i] = (a[i] * b[i]) % M;
    FFT(a, 1);
    FFT(b, 1);
}

int n, m, p[N], tt;
vector<pii> e[N];
ll a[SZ], b[SZ], aa[SZ];

int f(int x){
    if(x == p[x]) return x;
    return p[x] = f(p[x]);
}

int g(int x, int y, int z){
    if(x == z) return 1;
    for(pii &i : e[x]){
        if(i.x == y) continue;
        if(!g(i.x, x, z)) continue;
        b[i.y]++;
        return 1;
    }
    return 0;
}

void h(){
    mult(a, b);
    mult(aa, b);
    for(int i = 0; i < SZ; i++) aa[i] = !!aa[i];
}

int main(){ ios_base::sync_with_stdio(0); cin.tie(0);
    cin >> n >> m;
    iota(p, p+n+1, 0);
    a[0] = aa[0] = 1;
    for(int x, y, z; m--; ){
        cin >> x >> y >> z;
        tt ^= z;
        if(f(x) != f(y)){
            p[f(y)] = f(x);
            e[x].emplace_back(y, z);
            e[y].emplace_back(x, z);
        }
        else{
            memset(b, 0, sizeof(b));
            b[z]++;
            g(x, 0, y);
            h();
        }
    }
    memset(b, 0, sizeof(b));
    b[tt] = 1;
    h();
    for(int i = 0; ; i++) if(aa[i]){
        cout << i << ' ' << a[i] << '\n';
        return 0;
    }
}


#include <bits/stdc++.h>
using namespace std;

using ll = long long;
using pii = pair<int, int>;
#define x first
#define y second

const int N = 100005, SZ = 131072, L = 17;
ll M = ll(1e9) + 7, ISZ = 742744451;

int Rev(int x) {
    int i, r = 0;
    for (i = 0; i < L; i++) {
        r = r << 1 | x & 1;
        x >>= 1;
    }
    return r;
}

void FFT(ll *a, bool f) {
    int i, j, k, z;
    for (i = 0; i < SZ; i++) {
        j = Rev(i);
        if (i < j) {
            z = a[i];
            a[i] = a[j];
            a[j] = z;
        }
    }
    for (i = 1; i < SZ; i <<= 1) for (j = 0; j < SZ; j += i << 1) for (k = 0; k < i; k++) {
        z = a[i + j + k];
        a[i + j + k] = (a[j + k] - z + M) % M;
        (a[j + k] += z) %= M;
    }
    if (f) for (i = 0; i < SZ; i++) a[i] = a[i] * ISZ % M;
}

int n, m, p[N], tt;
vector<pii> e[N];
ll a[SZ], b[SZ], aa[SZ], bb[SZ];

int f(int x){
    if(x == p[x]) return x;
    return p[x] = f(p[x]);
}

int g(int x, int y, int z){
    if(x == z) return 1;
    for(pii &i : e[x]){
        if(i.x == y) continue;
        if(!g(i.x, x, z)) continue;
        b[i.y]++;
        return 1;
    }
    return 0;
}

void h(){
    FFT(aa, 0);
    FFT(b, 0);
    for(int i = 0; i < SZ; i++) (a[i] *= b[i]) %= M;
    for(int i = 0; i < SZ; i++) (aa[i] *= b[i]) %= M;
    FFT(aa, 1);
    for(int i = 0; i < SZ; i++) aa[i] = !!aa[i];
}

int main(){ ios_base::sync_with_stdio(0); cin.tie(0);
    cin >> n >> m;
    iota(p, p+n+1, 0);
    a[0] = aa[0] = 1;
    FFT(a, 0);
    for(int x, y, z; m--; ){
        cin >> x >> y >> z;
        tt ^= z;
        if(f(x) != f(y)){
            p[f(y)] = f(x);
            e[x].emplace_back(y, z);
            e[y].emplace_back(x, z);
        }
        else{
            memset(b, 0, sizeof(b));
            b[z]++;
            g(x, 0, y);
            h();
        }
    }
    memset(b, 0, sizeof(b));
    b[tt] = 1;
    h();
    FFT(a, 1);
    for(int i = 0; ; i++) if(aa[i]){
        cout << i << ' ' << a[i] << '\n';
        return 0;
    }
}


#include <bits/stdc++.h>
using namespace std;

using ll = long long;
using pii = pair<int, int>;
#define x first
#define y second

const int N = 100005, SZ = 131072, L = 17;
ll M = ll(1e9) + 7, ISZ = 742744451;

int Rev(int x) {
    int i, r = 0;
    for (i = 0; i < L; i++) {
        r = r << 1 | x & 1;
        x >>= 1;
    }
    return r;
}

void FFT(ll *a, bool f) {
    int i, j, k, z;
    for (i = 0; i < SZ; i++) {
        j = Rev(i);
        if (i < j) {
            z = a[i];
            a[i] = a[j];
            a[j] = z;
        }
    }
    for (i = 1; i < SZ; i <<= 1) for (j = 0; j < SZ; j += i << 1) for (k = 0; k < i; k++) {
        z = a[i + j + k];
        a[i + j + k] = (a[j + k] - z + M) % M;
        (a[j + k] += z) %= M;
    }
    if (f) for (i = 0; i < SZ; i++) a[i] = a[i] * ISZ % M;
}

void mult(ll *a, ll *b){
    FFT(a, 0);
    FFT(b, 0);
    for(int i = 0; i < SZ; i++) a[i] = (a[i] * b[i]) % M;
    FFT(a, 1);
    FFT(b, 1);
}

int n, m, p[N], tt;
vector<pii> e[N];
ll a[SZ], b[SZ], aa[SZ];

int f(int x){
    if(x == p[x]) return x;
    return p[x] = f(p[x]);
}

int g(int x, int y, int z){
    if(x == z) return 1;
    for(pii &i : e[x]){
        if(i.x == y) continue;
        if(!g(i.x, x, z)) continue;
        b[i.y]++;
        return 1;
    }
    return 0;
}

void h(){
    mult(a, b);
    mult(aa, b);
    for(int i = 0; i < SZ; i++) aa[i] = !!aa[i];
}

int main(){ ios_base::sync_with_stdio(0); cin.tie(0);
    cin >> n >> m;
    iota(p, p+n+1, 0);
    a[0] = aa[0] = 1;
    for(int x, y, z; m--; ){
        cin >> x >> y >> z;
        tt ^= z;
        if(f(x) != f(y)){
            p[f(y)] = f(x);
            e[x].emplace_back(y, z);
            e[y].emplace_back(x, z);
        }
        else{
            memset(b, 0, sizeof(b));
            b[z]++;
            g(x, 0, y);
            h();
        }
    }
    memset(b, 0, sizeof(b));
    b[tt] = 1;
    h();
    for(int i = 0; ; i++) if(aa[i]){
        cout << i << ' ' << a[i] << '\n';
        return 0;
    }
}


#include<bits/stdc++.h>

using namespace std;

#define double long double

typedef pair<int,int> ii;
typedef pair<int,long long> il;
typedef pair<long long,long long> ll;
typedef pair<ll,int> lli;
typedef pair<long long,int> li;
typedef pair<double,double> dd;
typedef pair<ii,int> iii;
typedef pair<double,int> di;
typedef pair<int,ii> iii2;
typedef pair<ii,ii> iiii;

long long mod = 1000000007LL;
long long large = 2000000000000000000LL;

vector<int> per;
int f(int x){
	return x==per[x]?x:per[x] = f(per[x]);
}

vector<vector<ii> > adj;

int sz = 17;

vector<int> lv;
vector<ii> pa;
void dfs(int u,int parent,int lvl,int w){
	lv[u] = lvl;
	pa[u] = ii(parent,w);
	for(int j=0;j<(int)adj[u].size();j++){
		int v = adj[u][j].first;
		if(v!=parent) dfs(v,u,lvl+1,adj[u][j].second);
	}
}

void get(int u,int v,vector<long long>& a){
	if(lv[u]<lv[v]) swap(u,v);
	while(lv[u]>lv[v]){
		a[pa[u].second]++;
		u = pa[u].first;

	}
	while(u!=v){
		a[pa[u].second]++;
		a[pa[v].second]++;
		u = pa[u].first;
		v = pa[v].first;
	}

}

long long rev = (mod+1)/2;
void FWT(vector<long long> &a,int sz){
	int n = (1<<sz);
    for(int d=1;d<n;d<<=1)
        for(int m=d<<1,i=0;i<n;i+=m)
            for(int j=0;j<d;j++)
            {
                long long x=a[i+j],y=a[i+j+d];
                a[i+j]=(x+y)%mod,a[i+j+d]=(x-y+mod)%mod;
                //xor:a[i+j]=x+y,a[i+j+d]=(x-y+mod)%mod;
                //and:a[i+j]=x+y;
                //or:a[i+j+d]=x+y;
            }
}

void UFWT(vector<long long> &a,int sz){
	int n = (1<<sz);
    for(int d=1;d<n;d<<=1)
        for(int m=d<<1,i=0;i<n;i+=m)
            for(int j=0;j<d;j++)
            {
                long long x=a[i+j],y=a[i+j+d];
                a[i+j]=1LL*(x+y)*rev%mod,a[i+j+d]=(1LL*(x-y)*rev%mod+mod)%mod;
                //xor:a[i+j]=(x+y)/2,a[i+j+d]=(x-y)/2;
                //and:a[i+j]=x-y;
                //or:a[i+j+d]=y-x;
            }
}

int main(){

	ios::sync_with_stdio(false);

	int n,m;
	cin>>n>>m;
	adj.assign(n,vector<ii>());

	per.assign(n,-1);
	for(int i=0;i<n;i++) per[i] = i;

	vector<iii> e;

	int ans = 0;

	for(int i=0;i<m;i++){
		int x,y,w;
		cin>>x>>y>>w;
		x--;y--;
		ans^=w;

		if(f(x)!=f(y)){
			adj[x].push_back(ii(y,w));
			adj[y].push_back(ii(x,w));
			per[f(x)] = f(y);
		}else{
			e.push_back(iii(ii(x,y),w));
		}
	}
	lv.assign(n,-1);
	pa.assign(n,ii());
	dfs(0,-1,0,0);

//	cout<<"!"<<endl;

	vector<long long> t;
	vector<long long> p;

	vector<long long> a(1<<sz,0);
	for(int i=0;i<(int)e.size();i++){
		a.assign(1<<sz,0);
		get(e[i].first.first,e[i].first.second,a);
		a[e[i].second]++;
		FWT(a,sz);
		vector<long long> b = a;
		for(int i=0;i<(1<<sz);i++) if(a[i]) b[i] = 1;
		FWT(b,sz);
		if(t.size()==0) t = a;
		else{
			for(int j=0;j<(1<<sz);j++) t[j] = t[j]*a[j]%mod;
		}
		if(p.size()==0) p = b;
		else for(int j=0;j<(1<<sz);j++) p[j] = p[j]*b[j]%mod;
	}

	UFWT(t,sz);

	ii f = ii(1000000000,0);

//	for(int i=0;i<10;i++) cout<<i<<" "<<t[i]<<endl;

	for(int i=0;i<(1<<sz);i++){
		if(p[i]>0){
			f = min(f,ii(i^ans,t[i]));
		}
	}

	cout<<f.first<<" "<<f.second<<endl;

    return 0;
}


#include<bits/stdc++.h>

using namespace std;

#define double long double

typedef pair<int,int> ii;
typedef pair<int,long long> il;
typedef pair<long long,long long> ll;
typedef pair<ll,int> lli;
typedef pair<long long,int> li;
typedef pair<double,double> dd;
typedef pair<ii,int> iii;
typedef pair<double,int> di;
typedef pair<int,ii> iii2;
typedef pair<ii,ii> iiii;

long long mod = 1000000007LL;
long long large = 2000000000000000000LL;

vector<int> per;
int f(int x){
	return x==per[x]?x:per[x] = f(per[x]);
}

vector<vector<ii> > adj;

int sz = 20;

vector<int> lv;
vector<ii> pa;
void dfs(int u,int parent,int lvl,int w){
	lv[u] = lvl;
	pa[u] = ii(parent,w);
	for(int j=0;j<(int)adj[u].size();j++){
		int v = adj[u][j].first;
		if(v!=parent) dfs(v,u,lvl+1,adj[u][j].second);
	}
}

vector<long long> get(int u,int v){
	vector<long long> a((1<<sz),0);
	if(lv[u]<lv[v]) swap(u,v);
	while(lv[u]>lv[v]){
		a[pa[u].second]++;
		u = pa[u].first;

	}
	while(u!=v){
		a[pa[u].second]++;
		a[pa[v].second]++;
		u = pa[u].first;
		v = pa[v].first;
	}

	return a;
}

long long rev = (mod+1)/2;
void FWT(vector<long long> &a,int sz){
	int n = (1<<sz);
    for(int d=1;d<n;d<<=1)
        for(int m=d<<1,i=0;i<n;i+=m)
            for(int j=0;j<d;j++)
            {
                long long x=a[i+j],y=a[i+j+d];
                a[i+j]=(x+y)%mod,a[i+j+d]=(x-y+mod)%mod;
                //xor:a[i+j]=x+y,a[i+j+d]=(x-y+mod)%mod;
                //and:a[i+j]=x+y;
                //or:a[i+j+d]=x+y;
            }
}

void UFWT(vector<long long> &a,int sz){
	int n = (1<<sz);
    for(int d=1;d<n;d<<=1)
        for(int m=d<<1,i=0;i<n;i+=m)
            for(int j=0;j<d;j++)
            {
                long long x=a[i+j],y=a[i+j+d];
                a[i+j]=1LL*(x+y)*rev%mod,a[i+j+d]=(1LL*(x-y)*rev%mod+mod)%mod;
                //xor:a[i+j]=(x+y)/2,a[i+j+d]=(x-y)/2;
                //and:a[i+j]=x-y;
                //or:a[i+j+d]=y-x;
            }
}

int main(){

	ios::sync_with_stdio(false);

	int n,m;
	cin>>n>>m;
	adj.assign(n,vector<ii>());

	per.assign(n,-1);
	for(int i=0;i<n;i++) per[i] = i;

	vector<iii> e;

	int ans = 0;

	for(int i=0;i<m;i++){
		int x,y,w;
		cin>>x>>y>>w;
		x--;y--;
		ans^=w;

		if(f(x)!=f(y)){
			adj[x].push_back(ii(y,w));
			adj[y].push_back(ii(x,w));
			per[f(x)] = f(y);
		}else{
			e.push_back(iii(ii(x,y),w));
		}
	}
	lv.assign(n,-1);
	pa.assign(n,ii());
	dfs(0,-1,0,0);

//	cout<<"!"<<endl;

	vector<long long> t;

	for(int i=0;i<(int)e.size();i++){
		vector<long long> a = get(e[i].first.first,e[i].first.second);
		a[e[i].second]++;
		FWT(a,sz);
		if(t.size()==0) t = a;
		else{
			for(int j=0;j<(1<<sz);j++) t[j] = t[j]*a[j]%mod;
		}
	}

	UFWT(t,sz);

	ii f = ii(1000000000,0);

//	for(int i=0;i<10;i++) cout<<i<<" "<<t[i]<<endl;

	for(int i=0;i<(1<<sz);i++){
		if(t[i]>0){
			f = min(f,ii(i^ans,t[i]));
		}
	}

	cout<<f.first<<" "<<f.second<<endl;

    return 0;
}


#include<bits/stdc++.h>

using namespace std;

#define double long double

typedef pair<int,int> ii;
typedef pair<int,long long> il;
typedef pair<long long,long long> ll;
typedef pair<ll,int> lli;
typedef pair<long long,int> li;
typedef pair<double,double> dd;
typedef pair<ii,int> iii;
typedef pair<double,int> di;
typedef pair<int,ii> iii2;
typedef pair<ii,ii> iiii;

long long mod = 1000000007LL;
long long large = 2000000000000000000LL;

vector<int> per;
int f(int x){
	return x==per[x]?x:per[x] = f(per[x]);
}

vector<vector<ii> > adj;

int sz = 20;

vector<int> lv;
vector<ii> pa;
void dfs(int u,int parent,int lvl,int w){
	lv[u] = lvl;
	pa[u] = ii(parent,w);
	for(int j=0;j<(int)adj[u].size();j++){
		int v = adj[u][j].first;
		if(v!=parent) dfs(v,u,lvl+1,adj[u][j].second);
	}
}

vector<long long> get(int u,int v){
	vector<long long> a((1<<sz),0);
	if(lv[u]<lv[v]) swap(u,v);
	while(lv[u]>lv[v]){
		a[pa[u].second]++;
		u = pa[u].first;

	}
	while(u!=v){
		a[pa[u].second]++;
		a[pa[v].second]++;
		u = pa[u].first;
		v = pa[v].first;
	}

	return a;
}

long long rev = (mod+1)/2;
void FWT(vector<long long> &a,int sz){
	int n = (1<<sz);
    for(int d=1;d<n;d<<=1)
        for(int m=d<<1,i=0;i<n;i+=m)
            for(int j=0;j<d;j++)
            {
                long long x=a[i+j],y=a[i+j+d];
                a[i+j]=(x+y)%mod,a[i+j+d]=(x-y+mod)%mod;
                //xor:a[i+j]=x+y,a[i+j+d]=(x-y+mod)%mod;
                //and:a[i+j]=x+y;
                //or:a[i+j+d]=x+y;
            }
}

void UFWT(vector<long long> &a,int sz){
	int n = (1<<sz);
    for(int d=1;d<n;d<<=1)
        for(int m=d<<1,i=0;i<n;i+=m)
            for(int j=0;j<d;j++)
            {
                long long x=a[i+j],y=a[i+j+d];
                a[i+j]=1LL*(x+y)*rev%mod,a[i+j+d]=(1LL*(x-y)*rev%mod+mod)%mod;
                //xor:a[i+j]=(x+y)/2,a[i+j+d]=(x-y)/2;
                //and:a[i+j]=x-y;
                //or:a[i+j+d]=y-x;
            }
}

int main(){

	ios::sync_with_stdio(false);

	int n,m;
	cin>>n>>m;
	adj.assign(n,vector<ii>());

	per.assign(n,-1);
	for(int i=0;i<n;i++) per[i] = i;

	vector<iii> e;

	int ans = 0;

	for(int i=0;i<m;i++){
		int x,y,w;
		cin>>x>>y>>w;
		x--;y--;
		ans^=w;

		if(f(x)!=f(y)){
			adj[x].push_back(ii(y,w));
			adj[y].push_back(ii(x,w));
			per[f(x)] = f(y);
		}else{
			e.push_back(iii(ii(x,y),w));
		}
	}
	lv.assign(n,-1);
	pa.assign(n,ii());
	dfs(0,-1,0,0);

//	cout<<"!"<<endl;

	vector<long long> t;

	for(int i=0;i<(int)e.size();i++){
		vector<long long> a = get(e[i].first.first,e[i].first.second);
		a[e[i].second]++;
		FWT(a,sz);
		if(t.size()==0) t = a;
		else{
			for(int j=0;j<(1<sz);j++) t[j] = t[j]*a[j]%mod;
		}
	}

	UFWT(t,sz);

	ii f = ii(1000000000,0);

//	for(int i=0;i<10;i++) cout<<i<<" "<<t[i]<<endl;

	for(int i=0;i<(1<<sz);i++){
		if(t[i]>0){
			f = min(f,ii(i^ans,t[i]));
		}
	}

	cout<<f.first<<" "<<f.second<<endl;

    return 0;
}


#include<bits/stdc++.h>

using namespace std;

#define double long double

typedef pair<int,int> ii;
typedef pair<int,long long> il;
typedef pair<long long,long long> ll;
typedef pair<ll,int> lli;
typedef pair<long long,int> li;
typedef pair<double,double> dd;
typedef pair<ii,int> iii;
typedef pair<double,int> di;
typedef pair<int,ii> iii2;
typedef pair<ii,ii> iiii;

long long mod = 1000000007LL;
long long large = 2000000000000000000LL;

vector<int> per;
int f(int x){
	return x==per[x]?x:per[x] = f(per[x]);
}

vector<vector<ii> > adj;

int sz = 20;

vector<int> lv;
vector<ii> pa;
void dfs(int u,int parent,int lvl,int w){
	lv[u] = lvl;
	pa[u] = ii(parent,w);
	for(int j=0;j<(int)adj[u].size();j++){
		int v = adj[u][j].first;
		if(v!=parent) dfs(v,u,lvl+1,adj[u][j].second);
	}
}

void get(int u,int v,vector<long long>& a){
	if(lv[u]<lv[v]) swap(u,v);
	while(lv[u]>lv[v]){
		a[pa[u].second]++;
		u = pa[u].first;

	}
	while(u!=v){
		a[pa[u].second]++;
		a[pa[v].second]++;
		u = pa[u].first;
		v = pa[v].first;
	}

}

long long rev = (mod+1)/2;
void FWT(vector<long long> &a,int sz){
	int n = (1<<sz);
    for(int d=1;d<n;d<<=1)
        for(int m=d<<1,i=0;i<n;i+=m)
            for(int j=0;j<d;j++)
            {
                long long x=a[i+j],y=a[i+j+d];
                a[i+j]=(x+y)%mod,a[i+j+d]=(x-y+mod)%mod;
                //xor:a[i+j]=x+y,a[i+j+d]=(x-y+mod)%mod;
                //and:a[i+j]=x+y;
                //or:a[i+j+d]=x+y;
            }
}

void UFWT(vector<long long> &a,int sz){
	int n = (1<<sz);
    for(int d=1;d<n;d<<=1)
        for(int m=d<<1,i=0;i<n;i+=m)
            for(int j=0;j<d;j++)
            {
                long long x=a[i+j],y=a[i+j+d];
                a[i+j]=1LL*(x+y)*rev%mod,a[i+j+d]=(1LL*(x-y)*rev%mod+mod)%mod;
                //xor:a[i+j]=(x+y)/2,a[i+j+d]=(x-y)/2;
                //and:a[i+j]=x-y;
                //or:a[i+j+d]=y-x;
            }
}

int main(){

	ios::sync_with_stdio(false);

	int n,m;
	cin>>n>>m;
	adj.assign(n,vector<ii>());

	per.assign(n,-1);
	for(int i=0;i<n;i++) per[i] = i;

	vector<iii> e;

	int ans = 0;

	for(int i=0;i<m;i++){
		int x,y,w;
		cin>>x>>y>>w;
		x--;y--;
		ans^=w;

		if(f(x)!=f(y)){
			adj[x].push_back(ii(y,w));
			adj[y].push_back(ii(x,w));
			per[f(x)] = f(y);
		}else{
			e.push_back(iii(ii(x,y),w));
		}
	}
	lv.assign(n,-1);
	pa.assign(n,ii());
	dfs(0,-1,0,0);

//	cout<<"!"<<endl;

	vector<long long> t;

	vector<long long> a(1<<sz,0);
	for(int i=0;i<(int)e.size();i++){
		a.assign(1<<sz,0);
		get(e[i].first.first,e[i].first.second,a);
		a[e[i].second]++;
		FWT(a,sz);
		if(t.size()==0) t = a;
		else{
			for(int j=0;j<(1<<sz);j++) t[j] = t[j]*a[j]%mod;
		}
	}

	UFWT(t,sz);

	ii f = ii(1000000000,0);

//	for(int i=0;i<10;i++) cout<<i<<" "<<t[i]<<endl;

	for(int i=0;i<(1<<sz);i++){
		if(t[i]>0){
			f = min(f,ii(i^ans,t[i]));
		}
	}

	cout<<f.first<<" "<<f.second<<endl;

    return 0;
}


#include<bits/stdc++.h>

using namespace std;

#define double long double

typedef pair<int,int> ii;
typedef pair<int,long long> il;
typedef pair<long long,long long> ll;
typedef pair<ll,int> lli;
typedef pair<long long,int> li;
typedef pair<double,double> dd;
typedef pair<ii,int> iii;
typedef pair<double,int> di;
typedef pair<int,ii> iii2;
typedef pair<ii,ii> iiii;

long long mod = 1000000007LL;
long long large = 2000000000000000000LL;

vector<int> per;
int f(int x){
	return x==per[x]?x:per[x] = f(per[x]);
}

vector<vector<ii> > adj;

int sz = 17;

vector<int> lv;
vector<ii> pa;
void dfs(int u,int parent,int lvl,int w){
	lv[u] = lvl;
	pa[u] = ii(parent,w);
	for(int j=0;j<(int)adj[u].size();j++){
		int v = adj[u][j].first;
		if(v!=parent) dfs(v,u,lvl+1,adj[u][j].second);
	}
}

void get(int u,int v,vector<long long>& a){
	if(lv[u]<lv[v]) swap(u,v);
	while(lv[u]>lv[v]){
		a[pa[u].second]++;
		u = pa[u].first;

	}
	while(u!=v){
		a[pa[u].second]++;
		a[pa[v].second]++;
		u = pa[u].first;
		v = pa[v].first;
	}

}

long long rev = (mod+1)/2;
void FWT(vector<long long> &a,int sz){
	int n = (1<<sz);
    for(int d=1;d<n;d<<=1)
        for(int m=d<<1,i=0;i<n;i+=m)
            for(int j=0;j<d;j++)
            {
                long long x=a[i+j],y=a[i+j+d];
                a[i+j]=(x+y)%mod,a[i+j+d]=(x-y+mod)%mod;
                //xor:a[i+j]=x+y,a[i+j+d]=(x-y+mod)%mod;
                //and:a[i+j]=x+y;
                //or:a[i+j+d]=x+y;
            }
}

void UFWT(vector<long long> &a,int sz){
	int n = (1<<sz);
    for(int d=1;d<n;d<<=1)
        for(int m=d<<1,i=0;i<n;i+=m)
            for(int j=0;j<d;j++)
            {
                long long x=a[i+j],y=a[i+j+d];
                a[i+j]=1LL*(x+y)*rev%mod,a[i+j+d]=(1LL*(x-y)*rev%mod+mod)%mod;
                //xor:a[i+j]=(x+y)/2,a[i+j+d]=(x-y)/2;
                //and:a[i+j]=x-y;
                //or:a[i+j+d]=y-x;
            }
}

int main(){

	ios::sync_with_stdio(false);

	int n,m;
	cin>>n>>m;
	adj.assign(n,vector<ii>());

	per.assign(n,-1);
	for(int i=0;i<n;i++) per[i] = i;

	vector<iii> e;

	int ans = 0;

	for(int i=0;i<m;i++){
		int x,y,w;
		cin>>x>>y>>w;
		x--;y--;
		ans^=w;

		if(f(x)!=f(y)){
			adj[x].push_back(ii(y,w));
			adj[y].push_back(ii(x,w));
			per[f(x)] = f(y);
		}else{
			e.push_back(iii(ii(x,y),w));
		}
	}
	lv.assign(n,-1);
	pa.assign(n,ii());
	dfs(0,-1,0,0);

//	cout<<"!"<<endl;

	vector<long long> t;

	vector<long long> a(1<<sz,0);
	for(int i=0;i<(int)e.size();i++){
		a.assign(1<<sz,0);
		get(e[i].first.first,e[i].first.second,a);
		a[e[i].second]++;
		FWT(a,sz);
		if(t.size()==0) t = a;
		else{
			for(int j=0;j<(1<<sz);j++) t[j] = t[j]*a[j]%mod;
		}
	}

	UFWT(t,sz);

	ii f = ii(1000000000,0);

//	for(int i=0;i<10;i++) cout<<i<<" "<<t[i]<<endl;

	for(int i=0;i<(1<<sz);i++){
		if(t[i]>0){
			f = min(f,ii(i^ans,t[i]));
		}
	}

	cout<<f.first<<" "<<f.second<<endl;

    return 0;
}


#include<bits/stdc++.h>

using namespace std;

#define double long double

typedef pair<int,int> ii;
typedef pair<int,long long> il;
typedef pair<long long,long long> ll;
typedef pair<ll,int> lli;
typedef pair<long long,int> li;
typedef pair<double,double> dd;
typedef pair<ii,int> iii;
typedef pair<double,int> di;
typedef pair<int,ii> iii2;
typedef pair<ii,ii> iiii;

long long mod = 1000000007LL;
long long large = 2000000000000000000LL;

vector<int> per;
int f(int x){
	return x==per[x]?x:per[x] = f(per[x]);
}

vector<vector<ii> > adj;

int sz = 17;

vector<int> lv;
vector<ii> pa;
void dfs(int u,int parent,int lvl,int w){
	lv[u] = lvl;
	pa[u] = ii(parent,w);
	for(int j=0;j<(int)adj[u].size();j++){
		int v = adj[u][j].first;
		if(v!=parent) dfs(v,u,lvl+1,adj[u][j].second);
	}
}

void get(int u,int v,vector<long long>& a){
	if(lv[u]<lv[v]) swap(u,v);
	while(lv[u]>lv[v]){
		a[pa[u].second]++;
		u = pa[u].first;

	}
	while(u!=v){
		a[pa[u].second]++;
		a[pa[v].second]++;
		u = pa[u].first;
		v = pa[v].first;
	}

}

long long rev = (mod+1)/2;
void FWT(vector<long long> &a,int sz){
	int n = (1<<sz);
    for(int d=1;d<n;d<<=1)
        for(int m=d<<1,i=0;i<n;i+=m)
            for(int j=0;j<d;j++)
            {
                long long x=a[i+j],y=a[i+j+d];
                a[i+j]=(x+y)%mod,a[i+j+d]=(x-y+mod)%mod;
                //xor:a[i+j]=x+y,a[i+j+d]=(x-y+mod)%mod;
                //and:a[i+j]=x+y;
                //or:a[i+j+d]=x+y;
            }
}

void UFWT(vector<long long> &a,int sz){
	int n = (1<<sz);
    for(int d=1;d<n;d<<=1)
        for(int m=d<<1,i=0;i<n;i+=m)
            for(int j=0;j<d;j++)
            {
                long long x=a[i+j],y=a[i+j+d];
                a[i+j]=1LL*(x+y)*rev%mod,a[i+j+d]=(1LL*(x-y)*rev%mod+mod)%mod;
                //xor:a[i+j]=(x+y)/2,a[i+j+d]=(x-y)/2;
                //and:a[i+j]=x-y;
                //or:a[i+j+d]=y-x;
            }
}

int main(){

	ios::sync_with_stdio(false);

	int n,m;
	cin>>n>>m;
	adj.assign(n,vector<ii>());

	per.assign(n,-1);
	for(int i=0;i<n;i++) per[i] = i;

	vector<iii> e;

	int ans = 0;

	for(int i=0;i<m;i++){
		int x,y,w;
		cin>>x>>y>>w;
		x--;y--;
		ans^=w;

		if(f(x)!=f(y)){
			adj[x].push_back(ii(y,w));
			adj[y].push_back(ii(x,w));
			per[f(x)] = f(y);
		}else{
			e.push_back(iii(ii(x,y),w));
		}
	}
	lv.assign(n,-1);
	pa.assign(n,ii());
	dfs(0,-1,0,0);

//	cout<<"!"<<endl;

	vector<long long> t;
	vector<long long> p;

	vector<long long> a(1<<sz,0);
	for(int i=0;i<(int)e.size();i++){
		a.assign(1<<sz,0);
		get(e[i].first.first,e[i].first.second,a);
		a[e[i].second]++;
		vector<long long> b = a;
		for(int j=0;j<(1<<sz);j++) if(a[j]) b[j] = 1;

		FWT(a,sz);
		FWT(b,sz);
		if(t.size()==0) t = a;
		else{
			for(int j=0;j<(1<<sz);j++) t[j] = t[j]*a[j]%mod;
		}
		if(p.size()==0) p = b;
		else for(int j=0;j<(1<<sz);j++) p[j] = p[j]*b[j]%mod;
	}

	UFWT(t,sz);
	UFWT(p,sz);
	ii f = ii(1000000000,0);

//	for(int i=0;i<10;i++) cout<<i<<" "<<t[i]<<endl;

	for(int i=0;i<(1<<sz);i++){
		if(p[i]>0){
			f = min(f,ii(i^ans,t[i]));
		}
	}

	cout<<f.first<<" "<<f.second<<endl;

    return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <array>
constexpr int P = 1'000'000'007, INV = 742'744'451, C = 131'072;
int n, m, tot, dfn;
std::vector<std::vector<std::pair<int, int>>> e;
std::vector<int> in, parent, weight;
std::array<int, C> cnt, ex;
void dft(std::array<int, C> &a) {
    for (int i = 1; i < C; i *= 2) {
        for (int j = 0; j < C; j += 2 * i) {
            for (int k = 0; k < i; ++k) {
                int u = a[j + k];
                int v = a[i + j + k];
                a[j + k] = (u + v) % P;
                a[i + j + k] = (u - v + P) % P;
            }
        }
    }
}
void idft(std::array<int, C> &a) {
    dft(a);
    for (int i = 0; i < C; ++i)
        a[i] = 1LL * a[i] * INV % P;
}
auto operator*(std::array<int, C> lhs, std::array<int, C> rhs) {
    dft(lhs);
    dft(rhs);
    for (int i = 0; i < int(lhs.size()); ++i)
        lhs[i] = 1LL * lhs[i] * rhs[i] % P;
    idft(lhs);
    return lhs;
}
void dfs(int u) {
    in[u] = dfn++;
    for (auto [v, w] : e[u]) {
        if (v == parent[u])
            continue;
        if (in[v] == -1) {
            parent[v] = u;
            weight[v] = w;
            dfs(v);
        } else if (in[v] < in[u]) {
            std::array<int, C> now{};
            for (int i = u; i != v; i = parent[i])
                ++now[weight[i]];
            ++now[w];
            cnt = cnt * now;
            ex = ex * now;
            for (int i = 0; i < C; ++i)
                ex[i] = std::min(ex[i], 1);
        }
    }
}
int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cin >> n >> m;
    e.resize(n);
    parent.resize(n);
    weight.resize(n);
    in.assign(n, -1);
    for (int i = 0; i < m; ++i) {
        int u, v, w;
        std::cin >> u >> v >> w;
        --u;
        --v;
        e[u].emplace_back(v, w);
        e[v].emplace_back(u, w);
        tot ^= w;
    }
    cnt[0] = ex[0] = 1;
    parent[0] = -1;
    dfs(0);
    for (int i = 0; ; ++i) {
        if (ex[i ^ tot] == 1) {
            std::cout << i << " " << cnt[i ^ tot] << "\n";
            return 0;
        }
    }
    return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
constexpr int P = 1'000'000'007, INV = 742'744'451, C = 131'072;
int n, m, tot, dfn;
std::vector<std::vector<std::pair<int, int>>> e;
std::vector<int> in, parent, weight, cnt(C), ex(C);
void dft(std::vector<int> &a) {
    for (int i = 1; i < C; i *= 2) {
        for (int j = 0; j < C; j += 2 * i) {
            for (int k = 0; k < i; ++k) {
                int u = a[j + k];
                int v = a[i + j + k];
                a[j + k] = (u + v) % P;
                a[i + j + k] = (u - v + P) % P;
            }
        }
    }
}
void idft(std::vector<int> &a) {
    dft(a);
    for (int i = 0; i < C; ++i)
        a[i] = 1LL * a[i] * INV % P;
}
auto operator*(std::vector<int> lhs, std::vector<int> rhs) {
    dft(lhs);
    dft(rhs);
    for (int i = 0; i < int(lhs.size()); ++i)
        lhs[i] = 1LL * lhs[i] * rhs[i] % P;
    idft(lhs);
    return lhs;
}
void dfs(int u) {
    in[u] = dfn++;
    for (auto [v, w] : e[u]) {
        if (v == parent[u])
            continue;
        if (in[v] == -1) {
            parent[v] = u;
            weight[v] = w;
            dfs(v);
        } else if (in[v] < in[u]) {
            std::vector<int> now(C);
            for (int i = u; i != v; i = parent[i])
                ++now[weight[i]];
            ++now[w];
            cnt = cnt * now;
            ex = ex * now;
            for (int i = 0; i < C; ++i)
                ex[i] = std::min(ex[i], 1);
        }
    }
}
int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cin >> n >> m;
    e.resize(n);
    parent.resize(n);
    weight.resize(n);
    in.assign(n, -1);
    for (int i = 0; i < m; ++i) {
        int u, v, w;
        std::cin >> u >> v >> w;
        --u;
        --v;
        e[u].emplace_back(v, w);
        e[v].emplace_back(u, w);
        tot ^= w;
    }
    cnt[0] = ex[0] = 1;
    parent[0] = -1;
    dfs(0);
    for (int i = 0; ; ++i) {
        if (ex[i ^ tot] == 1) {
            std::cout << i << " " << cnt[i ^ tot] << "\n";
            return 0;
        }
    }
    return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <array>
constexpr int P = 1'000'000'007, INV = 742'744'451, C = 131'072;
int n, m, tot, dfn;
std::vector<std::vector<std::pair<int, int>>> e;
std::vector<int> in, parent, weight;
std::array<int, C> cnt, ex;
void dft(std::array<int, C> &a) {
    for (int i = 1; i < C; i *= 2) {
        for (int j = 0; j < C; j += 2 * i) {
            for (int k = 0; k < i; ++k) {
                int u = a[j + k];
                int v = a[i + j + k];
                a[j + k] = (u + v) % P;
                a[i + j + k] = (u - v + P) % P;
            }
        }
    }
}
void idft(std::array<int, C> &a) {
    dft(a);
    for (int i = 0; i < C; ++i)
        a[i] = 1LL * a[i] * INV % P;
}
auto operator*(std::array<int, C> lhs, std::array<int, C> rhs) {
    dft(lhs);
    dft(rhs);
    for (int i = 0; i < int(lhs.size()); ++i)
        lhs[i] = 1LL * lhs[i] * rhs[i] % P;
    idft(lhs);
    return lhs;
}
void dfs(int u) {
    in[u] = dfn++;
    for (auto [v, w] : e[u]) {
        if (v == parent[u])
            continue;
        if (in[v] == -1) {
            parent[v] = u;
            weight[v] = w;
            dfs(v);
        } else if (in[v] < in[u]) {
            std::array<int, C> now{};
            for (int i = u; i != v; i = parent[i])
                ++now[weight[i]];
            ++now[w];
            cnt = cnt * now;
            ex = ex * now;
            for (int i = 0; i < C; ++i)
                ex[i] = std::min(ex[i], 1);
        }
    }
}
int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cin >> n >> m;
    e.resize(n);
    parent.resize(n);
    weight.resize(n);
    in.assign(n, -1);
    for (int i = 0; i < n; ++i) {
        int u, v, w;
        std::cin >> u >> v >> w;
        --u;
        --v;
        e[u].emplace_back(v, w);
        e[v].emplace_back(u, w);
        tot ^= w;
    }
    cnt[0] = ex[0] = 1;
    parent[0] = -1;
    dfs(0);
    for (int i = 0; ; ++i) {
        if (ex[i ^ tot] == 1) {
            std::cout << i << " " << cnt[i ^ tot] << "\n";
            return 0;
        }
    }
    return 0;
}


//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
const int inf_int = 1e9 + 100;
const ll inf_ll = 1e18;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double dbl;
#define pb push_back
#define eb emplace_back
const double pi = 3.1415926535898;
#define dout if(debug) cout
#define fi first
#define se second
#define sp setprecision
#define sz(a) (int(a.size()))
#define mp make_pair
#define all(a) a.begin(),a.end()
bool debug = 0;
const int MAXN = 100 + 100;
const int LOG = 21;
const int mod = 998244353;
const int MX = 1e3 + 100;
typedef long long li;
const li MOD = 1000000000949747713ll;

template<class T1, class T2>
std::ostream &operator<<(std::ostream &out, const std::pair<T1, T2> &rhs) {
    out << "( " << rhs.first << " , " << rhs.second << " )";
    return out;
}

ll bin_pow(ll a, int n) {
    ll res = 1;
    while (n) {
        if (n & 1) {
            res = (res * a) % mod;
        }
        a = (a * a) % mod;
        n >>= 1;
    }
    return res;
}

ll reverse(ll a) {
    return bin_pow(a, mod - 2);
}

vector<int> FWHT(vector<int> &P, bool inverse) {
    int u, v;
    int deg = P.size();
    int i;
    for (int len = 1; 2 * len <= deg; len <<= 1) {
        for (i = 0; i < deg; i += 2 * len) {
            for (int j = 0; j < len; j++) {
                u = P[i + j];
                v = P[i + len + j];
                P[i + j] = u + v;
                if (P[i + j] >= mod)
                    P[i + j] -= mod;
                P[i + len + j] = u - v;
                if (P[i + len + j] < 0)
                    P[i + len + j] += mod;
            }
        }
    }

    if (inverse) {
        ll mul = reverse(deg);
        for (i = 0; i < deg; i++) {
            P[i] = (P[i] * mul) % mod;
        }
    }
    return P;
}

vector<pii> g[MAXN];
bool used[MAXN];
int timer, tin[MAXN], fup[MAXN];

int used_bridge[MAXN];

void dfs(int v, int p = -1) {
    used[v] = true;
    tin[v] = fup[v] = timer++;
    for (size_t i = 0; i < g[v].size(); ++i) {
        int to = g[v][i].fi;
        int id = g[v][i].se;
        if (to == p) continue;
        if (used[to])
            fup[v] = min(fup[v], tin[to]);
        else {
            dfs(to, v);
            fup[v] = min(fup[v], fup[to]);
            if (fup[to] > tin[v]) {
                used_bridge[id] = 1;
            }
        }
    }
}

int n, m;

void find_bridges() {
    timer = 0;
    for (int i = 1; i <= n; ++i)
        used[i] = false;
    for (int i = 1; i <= n; ++i)
        if (!used[i])
            dfs(i);
}

int x[MAXN], y[MAXN], c[MAXN];

vector<int> ids;

void dfs2(int v) {
    used[v] = true;
    for (pii x:g[v]) {
        int to = x.fi;
        int id = x.se;
        if (!used_bridge[id]) {
            used_bridge[id] = 1;
            ids.pb(id);
        }
        if (!used[to]) {
            dfs2(to);
        }
    }
}

void solve() {

    cin >> n >> m;
    for (int i = 1; i <= m; ++i) {
        int a, b;
        cin >> a >> b;
        g[a].pb({b, i});
        g[b].pb({a, i});
        x[i] = a;
        y[i] = b;
        cin >> c[i];
    }
    find_bridges();

    for (int i = 1; i <= n; ++i) {
        g[i].clear();
        used[i] = false;
    }
    int val = 0;
    for (int i = 1; i <= m; ++i) {
        if (used_bridge[i]) {
     //       dout << "bridge " << i << " " << c[i] << endl;
            val = val ^ c[i];
        } else {
            g[x[i]].pb({y[i], i});
            g[y[i]].pb({x[i], i});
        }
    }
    const int MX_C = 1 << 17;

    vector<int> res(MX_C);
   // dout << "val " << val << endl;
    res[val] = 1;

    FWHT(res, false);

    for (int i = 1; i <= n; ++i) {
        if (!used[i]) {
            ids.clear();
            dfs2(i);
            if (sz(ids) > 0) {
                vector<int> cur(MX_C);
                int all = 0;
                for (int v:ids) {
                    all ^= c[v];
                }
            /*    dout << "HERE v ; ";
                for (int v:ids) {
                    dout << v << " ";
                }
                dout << endl;*/

                cur[all] = 1;
                for (int v:ids) {
                    cur[all ^ c[v]]++;
                }

                FWHT(cur, false);

                for (int i = 0; i < MX_C; ++i) {
                    res[i] = (1ll * res[i] * cur[i]) % mod;
                }

            }
        }
    }

    FWHT(res, true);
    for (int i = 0; i < MX_C; ++i) {
        if (res[i] != 0) {
            cout << i << " " << res[i] << "\n";
            return;
        }
    }
    cout << "NO";

}

signed main() {
#ifdef zxc
    debug = 1;
    freopen("../input.txt", "r", stdin);
    // freopen("../output.txt", "w", stdout);
#else

#endif //zxc
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cout.setf(ios::fixed);
    cout.precision(20);

    int t = 1;
    while (t--)
        solve();
    if (debug)
        cerr << endl << "time : " << (1.0 * clock() / CLOCKS_PER_SEC) << endl;
}


//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
const int inf_int = 1e9 + 100;
const ll inf_ll = 1e18;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double dbl;
#define pb push_back
#define eb emplace_back
const double pi = 3.1415926535898;
#define dout if(debug) cout
#define fi first
#define se second
#define sp setprecision
#define sz(a) (int(a.size()))
#define mp make_pair
#define all(a) a.begin(),a.end()
bool debug = 0;
const int MAXN = 2e5 + 100;
const int LOG = 21;
const int mod = 1000000007;
const int MX = 1e3 + 100;
typedef long long li;
const li MOD = 1000000007;

template<class T1, class T2>
std::ostream &operator<<(std::ostream &out, const std::pair<T1, T2> &rhs) {
    out << "( " << rhs.first << " , " << rhs.second << " )";
    return out;
}

#define int ll

ll bin_pow(ll a, int n) {
    ll res = 1;
    while (n) {
        if (n & 1) {
            res = (res * a) % mod;
        }
        a = (a * a) % mod;
        n >>= 1;
    }
    return res;
}

ll reverse(ll a) {
    return bin_pow(a, mod - 2);
}

vector<int> FWHT(vector<int> &P, bool inverse) {
    int u, v;
    int deg = P.size();
    int i;
    for (int len = 1; 2 * len <= deg; len <<= 1) {
        for (i = 0; i < deg; i += 2 * len) {
            for (int j = 0; j < len; j++) {
                u = P[i + j];
                v = P[i + len + j];
                P[i + j] = u + v;
                if (P[i + j] >= mod)
                    P[i + j] -= mod;
                P[i + len + j] = u - v;
                if (P[i + len + j] < 0)
                    P[i + len + j] += mod;
            }
        }
    }

    if (inverse) {
        ll mul = reverse(deg);
        for (i = 0; i < deg; i++) {
            P[i] = (P[i] * mul) % mod;
        }
    }
    return P;
}

vector<int> FWHT2(vector<int> &P, bool inverse) {
    int u, v;
    int deg = P.size();
    int i;
    for (int len = 1; 2 * len <= deg; len <<= 1) {
        for (i = 0; i < deg; i += 2 * len) {
            for (int j = 0; j < len; j++) {
                u = P[i + j];
                v = P[i + len + j];
                P[i + j] = u + v;
                P[i + len + j] = u - v;
            }
        }
    }

    return P;
}

vector<pii> g[MAXN];
bool used[MAXN];
int timer, tin[MAXN], fup[MAXN];

int used_bridge[MAXN];

void dfs(int v, int p = -1) {
    used[v] = true;
    tin[v] = fup[v] = timer++;
    for (size_t i = 0; i < g[v].size(); ++i) {
        int to = g[v][i].fi;
        int id = g[v][i].se;
        if (to == p) continue;
        if (used[to])
            fup[v] = min(fup[v], tin[to]);
        else {
            dfs(to, v);
            fup[v] = min(fup[v], fup[to]);
            if (fup[to] > tin[v]) {
                used_bridge[id] = 1;
            }
        }
    }
}

int n, m;

void find_bridges() {
    timer = 0;
    for (int i = 1; i <= n; ++i)
        used[i] = false;
    for (int i = 1; i <= n; ++i)
        if (!used[i])
            dfs(i);
}

int x[MAXN], y[MAXN], c[MAXN];

vector<int> ids;

void dfs2(int v) {
    used[v] = true;
    for (pii x:g[v]) {
        int to = x.fi;
        int id = x.se;
        if (!used_bridge[id]) {
            used_bridge[id] = 1;
            ids.pb(id);
        }
        if (!used[to]) {
            dfs2(to);
        }
    }
}

void solve() {

    cin >> n >> m;
    for (int i = 1; i <= m; ++i) {
        int a, b;
        cin >> a >> b;
        g[a].pb({b, i});
        g[b].pb({a, i});
        x[i] = a;
        y[i] = b;
        cin >> c[i];
    }
    find_bridges();

    for (int i = 1; i <= n; ++i) {
        g[i].clear();
        used[i] = false;
    }
    int val = 0;
    for (int i = 1; i <= m; ++i) {
        if (used_bridge[i]) {
            val = val ^ c[i];
        } else {
            g[x[i]].pb({y[i], i});
            g[y[i]].pb({x[i], i});
        }
    }
    const int MX_C = 1 << 18;

    vector<int> res(MX_C);
    vector<int> res2(MX_C);
    res[val] = 1;
    res2[val] = 1;

    FWHT(res, false);
    FWHT2(res2, false);

    for (int i = 1; i <= n; ++i) {
        if (!used[i]) {
            ids.clear();
            dfs2(i);
            if (sz(ids) > 0) {
                vector<int> cur(MX_C);
                int all = 0;
                for (int v:ids) {
                    all ^= c[v];
                }
                for (int v:ids) {
                    cur[all ^ c[v]]++;
                }

                vector<int> cur2 = cur;

                FWHT(cur, false);
                FWHT2(cur2, false);

                for (int i = 0; i < MX_C; ++i) {
                    res[i] = (1ll * res[i] * cur[i]) % mod;

                    res2[i] = res2[i] * cur2[i];
                }

            }
        }
    }

    FWHT(res, true);
    FWHT2(res2, true);
    for (int i = 0; i < MX_C; ++i) {
        if (res2[i] !=0 || res[i] != 0) {
            cout << i << " " << (res[i] % mod) << "\n";
            return;
        }
    }
    cout << "NO";

}

signed main() {
#ifdef zxc
    debug = 1;
    freopen("../input.txt", "r", stdin);
    // freopen("../output.txt", "w", stdout);
#else

#endif //zxc
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cout.setf(ios::fixed);
    cout.precision(20);

    int t = 1;
    while (t--)
        solve();
    if (debug)
        cerr << endl << "time : " << (1.0 * clock() / CLOCKS_PER_SEC) << endl;
}


//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
const int inf_int = 1e9 + 100;
const ll inf_ll = 1e18;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double dbl;
#define pb push_back
#define eb emplace_back
const double pi = 3.1415926535898;
#define dout if(debug) cout
#define fi first
#define se second
#define sp setprecision
#define sz(a) (int(a.size()))
#define mp make_pair
#define all(a) a.begin(),a.end()
bool debug = 0;
const int MAXN = 1e5 + 100;
const int LOG = 21;
const int mod = 1000000007;
const int MX = 1e3 + 100;
typedef long long li;
const li MOD = 1000000007;

template<class T1, class T2>
std::ostream &operator<<(std::ostream &out, const std::pair<T1, T2> &rhs) {
    out << "( " << rhs.first << " , " << rhs.second << " )";
    return out;
}

ll bin_pow(ll a, int n) {
    ll res = 1;
    while (n) {
        if (n & 1) {
            res = (res * a) % mod;
        }
        a = (a * a) % mod;
        n >>= 1;
    }
    return res;
}

ll reverse(ll a) {
    return bin_pow(a, mod - 2);
}

vector<int> FWHT(vector<int> &P, bool inverse) {
    int u, v;
    int deg = P.size();
    int i;
    for (int len = 1; 2 * len <= deg; len <<= 1) {
        for (i = 0; i < deg; i += 2 * len) {
            for (int j = 0; j < len; j++) {
                u = P[i + j];
                v = P[i + len + j];
                P[i + j] = u + v;
                if (P[i + j] >= mod)
                    P[i + j] -= mod;
                P[i + len + j] = u - v;
                if (P[i + len + j] < 0)
                    P[i + len + j] += mod;
            }
        }
    }

    if (inverse) {
        ll mul = reverse(deg);
        for (i = 0; i < deg; i++) {
            P[i] = (P[i] * mul) % mod;
        }
    }
    return P;
}

vector<pii> g[MAXN];
bool used[MAXN];
int timer, tin[MAXN], fup[MAXN];

int used_bridge[MAXN];

void dfs(int v, int p = -1) {
    used[v] = true;
    tin[v] = fup[v] = timer++;
    for (size_t i = 0; i < g[v].size(); ++i) {
        int to = g[v][i].fi;
        int id = g[v][i].se;
        if (to == p) continue;
        if (used[to])
            fup[v] = min(fup[v], tin[to]);
        else {
            dfs(to, v);
            fup[v] = min(fup[v], fup[to]);
            if (fup[to] > tin[v]) {
                used_bridge[id] = 1;
            }
        }
    }
}

int n, m;

void find_bridges() {
    timer = 0;
    for (int i = 1; i <= n; ++i)
        used[i] = false;
    for (int i = 1; i <= n; ++i)
        if (!used[i])
            dfs(i);
}

int x[MAXN], y[MAXN], c[MAXN];

vector<int> ids;

void dfs2(int v) {
    used[v] = true;
    for (pii x:g[v]) {
        int to = x.fi;
        int id = x.se;
        if (!used_bridge[id]) {
            used_bridge[id] = 1;
            ids.pb(id);
        }
        if (!used[to]) {
            dfs2(to);
        }
    }
}

void solve() {

    cin >> n >> m;
    for (int i = 1; i <= m; ++i) {
        int a, b;
        cin >> a >> b;
        g[a].pb({b, i});
        g[b].pb({a, i});
        x[i] = a;
        y[i] = b;
        cin >> c[i];
    }
    find_bridges();

    for (int i = 1; i <= n; ++i) {
        g[i].clear();
        used[i] = false;
    }
    int val = 0;
    for (int i = 1; i <= m; ++i) {
        if (used_bridge[i]) {
     //       dout << "bridge " << i << " " << c[i] << endl;
            val = val ^ c[i];
        } else {
            g[x[i]].pb({y[i], i});
            g[y[i]].pb({x[i], i});
        }
    }
    const int MX_C = 1 << 17;

    vector<int> res(MX_C);
   // dout << "val " << val << endl;
    res[val] = 1;

    FWHT(res, false);

    for (int i = 1; i <= n; ++i) {
        if (!used[i]) {
            ids.clear();
            dfs2(i);
            if (sz(ids) > 0) {
                vector<int> cur(MX_C);
                int all = 0;
                for (int v:ids) {
                    all ^= c[v];
                }

                for (int v:ids) {
                    cur[all ^ c[v]]++;
                }

                FWHT(cur, false);

                for (int i = 0; i < MX_C; ++i) {
                    res[i] = (1ll * res[i] * cur[i]) % mod;
                }

            }
        }
    }

    FWHT(res, true);
    for (int i = 0; i < MX_C; ++i) {
        if (res[i] != 0) {
            cout << i << " " << res[i] << "\n";
            return;
        }
    }
    cout << "NO";

}

signed main() {
#ifdef zxc
    debug = 1;
    freopen("../input.txt", "r", stdin);
    // freopen("../output.txt", "w", stdout);
#else

#endif //zxc
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cout.setf(ios::fixed);
    cout.precision(20);

    int t = 1;
    while (t--)
        solve();
    if (debug)
        cerr << endl << "time : " << (1.0 * clock() / CLOCKS_PER_SEC) << endl;
}


//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
const int inf_int = 1e9 + 100;
const ll inf_ll = 1e18;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double dbl;
#define pb push_back
#define eb emplace_back
const double pi = 3.1415926535898;
#define dout if(debug) cout
#define fi first
#define se second
#define sp setprecision
#define sz(a) (int(a.size()))
#define mp make_pair
#define all(a) a.begin(),a.end()
bool debug = 0;
const int MAXN = 2e5 + 100;
const int LOG = 21;
const int mod = 1000000007;
const int MX = 1e3 + 100;
typedef long long li;
const li MOD = 1000000007;

template<class T1, class T2>
std::ostream &operator<<(std::ostream &out, const std::pair<T1, T2> &rhs) {
    out << "( " << rhs.first << " , " << rhs.second << " )";
    return out;
}

#define int ll

ll bin_pow(ll a, int n) {
    ll res = 1;
    while (n) {
        if (n & 1) {
            res = (res * a) % mod;
        }
        a = (a * a) % mod;
        n >>= 1;
    }
    return res;
}

ll reverse(ll a) {
    return bin_pow(a, mod - 2);
}

vector<int> FWHT(vector<int> &P, bool inverse) {
    int u, v;
    int deg = P.size();
    int i;
    for (int len = 1; 2 * len <= deg; len <<= 1) {
        for (i = 0; i < deg; i += 2 * len) {
            for (int j = 0; j < len; j++) {
                u = P[i + j];
                v = P[i + len + j];
                P[i + j] = u + v;
                if (P[i + j] >= mod)
                    P[i + j] -= mod;
                P[i + len + j] = u - v;
                if (P[i + len + j] < 0)
                    P[i + len + j] += mod;
            }
        }
    }

    if (inverse) {
        ll mul = reverse(deg);
        for (i = 0; i < deg; i++) {
            P[i] = (P[i] * mul) % mod;
        }
    }
    return P;
}

vector<int> FWHT2(vector<int> &P, bool inverse) {
    int u, v;
    int deg = P.size();
    int i;
    for (int len = 1; 2 * len <= deg; len <<= 1) {
        for (i = 0; i < deg; i += 2 * len) {
            for (int j = 0; j < len; j++) {
                u = P[i + j];
                v = P[i + len + j];
                P[i + j] = u + v;
                P[i + len + j] = u - v;
            }
        }
    }

    return P;
}

vector<pii> g[MAXN];
bool used[MAXN];
int timer, tin[MAXN], fup[MAXN];

int used_bridge[MAXN];

void dfs(int v, int p = -1) {
    used[v] = true;
    tin[v] = fup[v] = timer++;
    for (size_t i = 0; i < g[v].size(); ++i) {
        int to = g[v][i].fi;
        int id = g[v][i].se;
        if (to == p) continue;
        if (used[to])
            fup[v] = min(fup[v], tin[to]);
        else {
            dfs(to, v);
            fup[v] = min(fup[v], fup[to]);
            if (fup[to] > tin[v]) {
                used_bridge[id] = 1;
            }
        }
    }
}

int n, m;

void find_bridges() {
    timer = 0;
    for (int i = 1; i <= n; ++i)
        used[i] = false;
    for (int i = 1; i <= n; ++i)
        if (!used[i])
            dfs(i);
}

int x[MAXN], y[MAXN], c[MAXN];

vector<int> ids;

void dfs2(int v) {
    used[v] = true;
    for (pii x:g[v]) {
        int to = x.fi;
        int id = x.se;
        if (!used_bridge[id]) {
            used_bridge[id] = 1;
            ids.pb(id);
        }
        if (!used[to]) {
            dfs2(to);
        }
    }
}

void solve() {

    cin >> n >> m;
    for (int i = 1; i <= m; ++i) {
        int a, b;
        cin >> a >> b;
        g[a].pb({b, i});
        g[b].pb({a, i});
        x[i] = a;
        y[i] = b;
        cin >> c[i];
    }
    find_bridges();

    for (int i = 1; i <= n; ++i) {
        g[i].clear();
        used[i] = false;
    }
    int val = 0;
    for (int i = 1; i <= m; ++i) {
        if (used_bridge[i]) {
            val = val ^ c[i];
        } else {
            g[x[i]].pb({y[i], i});
            g[y[i]].pb({x[i], i});
        }
    }
    const int MX_C = 1 << 18;

    vector<int> res(MX_C);
    vector<int> res2(MX_C);
    res[val] = 1;
    res2[val] = 1;

    FWHT(res, false);
    FWHT2(res2, false);

    for (int i = 1; i <= n; ++i) {
        if (!used[i]) {
            ids.clear();
            dfs2(i);
            if (sz(ids) > 0) {
                vector<int> cur(MX_C);
                int all = 0;
                for (int v:ids) {
                    all ^= c[v];
                }
                for (int v:ids) {
                    cur[all ^ c[v]]++;
                }

                vector<int> cur2 = cur;

                FWHT(cur, false);
                FWHT2(cur2, false);

                for (int i = 0; i < MX_C; ++i) {
                    res[i] = (1ll * res[i] * cur[i]) % mod;

                    res2[i] = res2[i] * cur[i];
                }

            }
        }
    }

    FWHT(res, true);
    FWHT2(res2, true);
    for (int i = 0; i < MX_C; ++i) {
        if (res2[i] !=0 || res[i] != 0) {
            cout << i << " " << (res[i] % mod) << "\n";
            return;
        }
    }
    cout << "NO";

}

signed main() {
#ifdef zxc
    debug = 1;
    freopen("../input.txt", "r", stdin);
    // freopen("../output.txt", "w", stdout);
#else

#endif //zxc
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cout.setf(ios::fixed);
    cout.precision(20);

    int t = 1;
    while (t--)
        solve();
    if (debug)
        cerr << endl << "time : " << (1.0 * clock() / CLOCKS_PER_SEC) << endl;
}


//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
const int inf_int = 1e9 + 100;
const ll inf_ll = 1e18;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double dbl;
#define pb push_back
#define eb emplace_back
const double pi = 3.1415926535898;
#define dout if(debug) cout
#define fi first
#define se second
#define sp setprecision
#define sz(a) (int(a.size()))
#define mp make_pair
#define all(a) a.begin(),a.end()
bool debug = 0;
const int MAXN = 1e5 + 100;
const int LOG = 21;
const int mod = 998244353;
const int MX = 1e3 + 100;
typedef long long li;
const li MOD = 1000000000949747713ll;

template<class T1, class T2>
std::ostream &operator<<(std::ostream &out, const std::pair<T1, T2> &rhs) {
    out << "( " << rhs.first << " , " << rhs.second << " )";
    return out;
}

ll bin_pow(ll a, int n) {
    ll res = 1;
    while (n) {
        if (n & 1) {
            res = (res * a) % mod;
        }
        a = (a * a) % mod;
        n >>= 1;
    }
    return res;
}

ll reverse(ll a) {
    return bin_pow(a, mod - 2);
}

vector<int> FWHT(vector<int> &P, bool inverse) {
    int u, v;
    int deg = P.size();
    int i;
    for (int len = 1; 2 * len <= deg; len <<= 1) {
        for (i = 0; i < deg; i += 2 * len) {
            for (int j = 0; j < len; j++) {
                u = P[i + j];
                v = P[i + len + j];
                P[i + j] = u + v;
                if (P[i + j] >= mod)
                    P[i + j] -= mod;
                P[i + len + j] = u - v;
                if (P[i + len + j] < 0)
                    P[i + len + j] += mod;
            }
        }
    }

    if (inverse) {
        ll mul = reverse(deg);
        for (i = 0; i < deg; i++) {
            P[i] = (P[i] * mul) % mod;
        }
    }
    return P;
}

vector<pii> g[MAXN];
bool used[MAXN];
int timer, tin[MAXN], fup[MAXN];

int used_bridge[MAXN];

void dfs(int v, int p = -1) {
    used[v] = true;
    tin[v] = fup[v] = timer++;
    for (size_t i = 0; i < g[v].size(); ++i) {
        int to = g[v][i].fi;
        int id = g[v][i].se;
        if (to == p) continue;
        if (used[to])
            fup[v] = min(fup[v], tin[to]);
        else {
            dfs(to, v);
            fup[v] = min(fup[v], fup[to]);
            if (fup[to] > tin[v]) {
                used_bridge[id] = 1;
            }
        }
    }
}

int n, m;

void find_bridges() {
    timer = 0;
    for (int i = 1; i <= n; ++i)
        used[i] = false;
    for (int i = 1; i <= n; ++i)
        if (!used[i])
            dfs(i);
}

int x[MAXN], y[MAXN], c[MAXN];

vector<int> ids;

void dfs2(int v) {
    used[v] = true;
    for (pii x:g[v]) {
        int to = x.fi;
        int id = x.se;
        if (!used_bridge[id]) {
            used_bridge[id] = 1;
            ids.pb(id);
        }
        if (!used[to]) {
            dfs2(to);
        }
    }
}

void solve() {

    cin >> n >> m;
    for (int i = 1; i <= m; ++i) {
        int a, b;
        cin >> a >> b;
        g[a].pb({b, i});
        g[b].pb({a, i});
        x[i] = a;
        y[i] = b;
        cin >> c[i];
    }
    find_bridges();

    for (int i = 1; i <= n; ++i) {
        g[i].clear();
        used[i] = false;
    }
    int val = 0;
    for (int i = 1; i <= m; ++i) {
        if (used_bridge[i]) {
     //       dout << "bridge " << i << " " << c[i] << endl;
            val = val ^ c[i];
        } else {
            g[x[i]].pb({y[i], i});
            g[y[i]].pb({x[i], i});
        }
    }
    const int MX_C = 1 << 17;

    vector<int> res(MX_C);
   // dout << "val " << val << endl;
    res[val] = 1;

    FWHT(res, false);

    for (int i = 1; i <= n; ++i) {
        if (!used[i]) {
            ids.clear();
            dfs2(i);
            if (sz(ids) > 0) {
                vector<int> cur(MX_C);
                int all = 0;
                for (int v:ids) {
                    all ^= c[v];
                }
            /*    dout << "HERE v ; ";
                for (int v:ids) {
                    dout << v << " ";
                }
                dout << endl;*/

                cur[all] = 1;
                for (int v:ids) {
                    cur[all ^ c[v]]++;
                }

                FWHT(cur, false);

                for (int i = 0; i < MX_C; ++i) {
                    res[i] = (1ll * res[i] * cur[i]) % mod;
                }

            }
        }
    }

    FWHT(res, true);
    for (int i = 0; i < MX_C; ++i) {
        if (res[i] != 0) {
            cout << i << " " << res[i] << "\n";
            return;
        }
    }
    cout << "NO";

}

signed main() {
#ifdef zxc
    debug = 1;
    freopen("../input.txt", "r", stdin);
    // freopen("../output.txt", "w", stdout);
#else

#endif //zxc
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cout.setf(ios::fixed);
    cout.precision(20);

    int t = 1;
    while (t--)
        solve();
    if (debug)
        cerr << endl << "time : " << (1.0 * clock() / CLOCKS_PER_SEC) << endl;
}


//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
const int inf_int = 1e9 + 100;
const ll inf_ll = 1e18;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double dbl;
#define pb push_back
#define eb emplace_back
const double pi = 3.1415926535898;
#define dout if(debug) cout
#define fi first
#define se second
#define sp setprecision
#define sz(a) (int(a.size()))
#define mp make_pair
#define all(a) a.begin(),a.end()
bool debug = 0;
const int MAXN = 2e5 + 100;
const int LOG = 21;
const int mod = 1000000007;
const int MX = 1e3 + 100;
typedef long long li;
const li MOD = 1000000007;

template<class T1, class T2>
std::ostream &operator<<(std::ostream &out, const std::pair<T1, T2> &rhs) {
    out << "( " << rhs.first << " , " << rhs.second << " )";
    return out;
}

#define int ll
ll bin_pow(ll a, int n) {
    ll res = 1;
    while (n) {
        if (n & 1) {
            res = (res * a) % mod;
        }
        a = (a * a) % mod;
        n >>= 1;
    }
    return res;
}

ll reverse(ll a) {
    return bin_pow(a, mod - 2);
}

vector<int> FWHT(vector<int> &P, bool inverse) {
    int u, v;
    int deg = P.size();
    int i;
    for (int len = 1; 2 * len <= deg; len <<= 1) {
        for (i = 0; i < deg; i += 2 * len) {
            for (int j = 0; j < len; j++) {
                u = P[i + j];
                v = P[i + len + j];
                P[i + j] = u + v;
                if (P[i + j] >= mod)
                    P[i + j] -= mod;
                P[i + len + j] = u - v;
                if (P[i + len + j] < 0)
                    P[i + len + j] += mod;
            }
        }
    }

    if (inverse) {
        ll mul = reverse(deg);
        for (i = 0; i < deg; i++) {
            P[i] = (P[i] * mul) % mod;
        }
    }
    return P;
}

vector<pii> g[MAXN];
bool used[MAXN];
int timer, tin[MAXN], fup[MAXN];

int used_bridge[MAXN];

void dfs(int v, int p = -1) {
    used[v] = true;
    tin[v] = fup[v] = timer++;
    for (size_t i = 0; i < g[v].size(); ++i) {
        int to = g[v][i].fi;
        int id = g[v][i].se;
        if (to == p) continue;
        if (used[to])
            fup[v] = min(fup[v], tin[to]);
        else {
            dfs(to, v);
            fup[v] = min(fup[v], fup[to]);
            if (fup[to] > tin[v]) {
                used_bridge[id] = 1;
            }
        }
    }
}

int n, m;

void find_bridges() {
    timer = 0;
    for (int i = 1; i <= n; ++i)
        used[i] = false;
    for (int i = 1; i <= n; ++i)
        if (!used[i])
            dfs(i);
}

int x[MAXN], y[MAXN], c[MAXN];

vector<int> ids;

void dfs2(int v) {
    used[v] = true;
    for (pii x:g[v]) {
        int to = x.fi;
        int id = x.se;
        if (!used_bridge[id]) {
            used_bridge[id] = 1;
            ids.pb(id);
        }
        if (!used[to]) {
            dfs2(to);
        }
    }
}

void solve() {

    cin >> n >> m;
    for (int i = 1; i <= m; ++i) {
        int a, b;
        cin >> a >> b;
        g[a].pb({b, i});
        g[b].pb({a, i});
        x[i] = a;
        y[i] = b;
        cin >> c[i];
    }
    find_bridges();

    for (int i = 1; i <= n; ++i) {
        g[i].clear();
        used[i] = false;
    }
    int val = 0;
    for (int i = 1; i <= m; ++i) {
        if (used_bridge[i]) {
            val = val ^ c[i];
        } else {
            g[x[i]].pb({y[i], i});
            g[y[i]].pb({x[i], i});
        }
    }
    const int MX_C = 1 << 18;

    vector<int> res(MX_C);
    res[val] = 1;

    FWHT(res, false);

    for (int i = 1; i <= n; ++i) {
        if (!used[i]) {
            ids.clear();
            dfs2(i);
            if (sz(ids) > 0) {
                vector<int> cur(MX_C);
                int all = 0;
                for (int v:ids) {
                    all ^= c[v];
                }
                for (int v:ids) {
                    cur[all ^ c[v]]++;
                }

                FWHT(cur, false);

                for (int i = 0; i < MX_C; ++i) {
                    res[i] = (1ll * res[i] * cur[i]) % mod;
                }

            }
        }
    }

    FWHT(res, true);
    for (int i = 0; i < MX_C; ++i) {
        if (res[i] != 0) {
            cout << i << " " << (res[i]%mod) << "\n";
            return;
        }
    }
    cout << "NO";

}

signed main() {
#ifdef zxc
    debug = 1;
    freopen("../input.txt", "r", stdin);
    // freopen("../output.txt", "w", stdout);
#else

#endif //zxc
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cout.setf(ios::fixed);
    cout.precision(20);

    int t = 1;
    while (t--)
        solve();
    if (debug)
        cerr << endl << "time : " << (1.0 * clock() / CLOCKS_PER_SEC) << endl;
}