// FIRST THINK THEN CODE.

#include<iostream>
#include <bits/stdc++.h>

using namespace std;

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;

#define ll long long
#define ld long double
#define pll pair<ll,ll>
#define cld complex<ld>
#define vl vector<ll>
#define vvl vector<vector<ll>>
#define vld vector<ld>
#define vvld vector<vector<ld>>
#define vpll vector<pll>
#define vcld vector<cld>
#define ff first
#define ss second
#define pb push_back
#define mp make_pair
#define lb lower_bound
#define ub upper_bound
#define eb emplace_back
#define PI acos(-1)
#define endl "\n"
#define fix(f,n) fixed<<setprecision(n)<<f
#define all(x) x.begin(),x.end()
#define rev(p) reverse(p.begin(),p.end());
#define mset(a,val) memset(a,val,sizeof(a));
#define IOS ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define popcount(x) __builtin_popcountll(x)
#define sz(x) ((ll)x.size())
#define FOR(i,a,b)  for(ll i=a;i<=b;i++)
#define FORR(i,a,b)  for(ll i=a;i>=b;i--)
const ll M = 1000000007;
const ll MM = 998244353;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

#define ordered_set tree<pll, null_type,less<>, rb_tree_tag,tree_order_statistics_node_update>

ll begtime = clock();
#define end_routine() cerr << "\n\nTime elapsed: " << (clock() - begtime)*1000/CLOCKS_PER_SEC << " ms\n\n";

template<typename T, typename F>
void chmax( T &a, F b) {
	if (b > a)a = b;
}

template<typename T, typename F>
void chmin( T &a, F b) {
	if (b < a)a = b;
}

const ll N = 2e5 + 5;

ll mulmod(ll a, ll b, ll c) {

	ll ans = 0;
	ll y = a % c;
	while (b) {
		if (b & 1) {
			(ans += y) %= c;
		}
		y = y * 2 % c;
		b >>= 1;
	}
	return ans;

}




ll powMbig(ll a, ll b, ll m)
{
	if (a <= 0)return 0;
	a %= m;

	ll ans = 1LL;
	while (b)
	{
		if (b & 1)//ans = ans * a % m;
			ans = mulmod(ans, a, m);
		//a = a * a % m;
		a = mulmod(a, a, m);
		b >>= 1;
	}

	return ans;
}

ll powM(ll a, ll b, ll m)
{
	if (a <= 0)return 0;
	a %= m;

	ll ans = 1LL;
	while (b)
	{
		if (b & 1)ans = ans * a % m;
		//ans = mulmod(ans, a, m);
		a = a * a % m;
		//a = mulmod(a, a, m);
		b >>= 1;
	}

	return ans;
}



ll poww(ll a, ll b)
{

	ll ans = 1;
	while (b)
	{
		if (b & 1)ans = ans * a;
		a = a * a;
		b >>= 1;
	}

	return ans;

}
vpll arr[N];

vector<vvl> cnt(N, vvl(2, vl(62)));
vl foo(60);
void dfs(ll node, ll par) {
	FOR(iter, 0, 59)cnt[node][0][iter] = 1;
	for (auto to : arr[node]) {
		//	vvl lol(2);
		ll child = to.ff;
		if (child == par)continue;
		dfs(child, node);
		ll weight = to.ss;
		for (ll iter = 0; iter < 60; iter++) {
			ll we = 0;
			if (1ll << iter & weight)we = 1;
			(foo[iter] += cnt[node][we][iter] * cnt[child][1][iter]) %= M;
			(foo[iter] += cnt[node][1 ^ we][iter] * cnt[child][0][iter]) %= M;
			(cnt[node][0][iter] += cnt[child][0 ^ we][iter]) %= M;
			(cnt[node][1][iter] += cnt[child][1 ^ we][iter]) %= M;
			// if (cnt[node][0][iter] > M * M)cnt[node][0][iter] %= M;
			// if (cnt[node][1][iter] > M * M)cnt[node][1][iter] %= M;
			// if (foo[iter] > M * M)foo[iter] %= M;
		}
		//	foo += cnt[node][0] * cnt[node][1];
		//	cnt[node]=lol;
	}
	// FOR(iter, 0, 59) {
	// 	if (cnt[node][0][iter] > M * M)cnt[node][0][iter] %= M;
	// 	if (cnt[node][1][iter] > M * M)cnt[node][1][iter] %= M;
	// }
}


void OJ() {


#ifndef ONLINE_JUDGE

	freopen("input1.txt", "r", stdin);
	freopen("output1.txt", "w", stdout);

#endif

}

int main() {

	IOS;

	OJ();



	ll n; cin >> n;

	vl u(n), v(n), w(n);

	FOR(i, 0, n - 1) {
		cin >> u[i] >> v[i] >> w[i];
		arr[u[i]].pb({v[i], w[i]});
		arr[v[i]].pb({u[i], w[i]});
	}
	ll ans = 0;

	dfs(1, -1);

	for (ll i = 0; i < 60; i++) {
		ans = (ans + foo[i] * powM(2, i, M)) % M;
	}


	cout << ans;



	return 0;


}


//12252024832524
#include <cstdio>
#include <cstring>
#include <algorithm>
#define TT template<typename T>
using namespace std; 

typedef long long LL;
const int MAXN = 200005;
const int MOD = 1e9 + 7;
int n;
LL ans;

LL Read()
{
	LL x = 0,f = 1;char c = getchar();
	while(c > '9' || c < '0'){if(c == '-')f = -1;c = getchar();}
	while(c >= '0' && c <= '9'){x = (x*10) + (c^48);c = getchar();}
	return x * f;
}
TT void Put1(T x)
{
	if(x > 9) Put1(x/10);
	putchar(x%10^48);
}
TT void Put(T x,char c = -1)
{
	if(x < 0) putchar('-'),x = -x;
	Put1(x); if(c >= 0) putchar(c);
}
TT T Max(T x,T y){return x > y ? x : y;}
TT T Min(T x,T y){return x < y ? x : y;}
TT T Abs(T x){return x < 0 ? -x : x;}

int head[MAXN],tot;
struct edge
{
	int v,nxt;
	LL w;
}e[MAXN << 1];
void Add(LL x){ans = (ans + x) % MOD;}
void Add_Edge(int x,int y,LL z)
{
	e[++tot].v = y;
	e[tot].w = z;
	e[tot].nxt = head[x];
	head[x] = tot;
}
void Add_Double_Edge(int x,int y,LL z)
{
	Add_Edge(x,y,z);
	Add_Edge(y,x,z);
}

LL dp[MAXN][2];
void dfs(int x,int fa,int o)
{
	dp[x][0] = 0; dp[x][1] = 0;
	for(int i = head[x]; i ;i = e[i].nxt)
	{
		int v = e[i].v,w = (e[i].w >> o) & 1;
		if(v == fa) continue;
		dfs(v,x,o);
		if(!w)
		{
			Add(dp[x][0] * dp[v][1] % MOD * ((1ll << o) % MOD));
			Add(dp[x][1] * (dp[v][0]+1) % MOD * ((1ll << o) % MOD));
			dp[x][0] += dp[v][0]+1;
			dp[x][1] += dp[v][1];
		}
		else 
		{
			Add(dp[x][0] * (dp[v][0]+1) % MOD * ((1ll << o) % MOD));
			Add(dp[x][1] * dp[v][1] % MOD * ((1ll << o) % MOD));
			dp[x][0] += dp[v][1];
			dp[x][1] += dp[v][0]+1;
		}
	}
	Add(dp[x][1] * ((1ll << o) % MOD));
}

int main()
{
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	n = Read();
	for(int i = 1;i < n;++ i)
	{
		int u = Read(),v = Read();
		Add_Double_Edge(u,v,Read());
	}
	for(int i = 0;i <= 60;++ i) dfs(1,0,i);
	Put(ans);
	return 0;
}