#include <bits/stdc++.h>
using namespace std;
#define e1 first
#define e2 second
#define pb push_back
#define mp make_pair
#define boost ios_base::sync_with_stdio(false)
#define eb emplace_back
#define OUT(x) {cout << x; exit(0); }
#define FOR(i, a, b) for(int i=(a); i<=(b); ++i)
typedef long long ll;
typedef unsigned long long ull;
typedef pair <int, int> PII;
typedef pair <ll, ll> PLL;
typedef pair <PLL, PLL> PP;
typedef unsigned int ui;
const int inf = 1e9+9;
const ll MOD = 1e9+696969;
const ll INF = 1e18;
#define maxn 510
int dp[maxn][maxn], odp[maxn][maxn], n, m, mod;

int ile[maxn];
char s[maxn][maxn];
int bin2[maxn], ilo[maxn][maxn];
;

int main()
{
	scanf("%d%d%d", &n, &m, &mod);
	FOR(i, 0, 500) bin2[i] = i * (i-1)/2;
	FOR(i, 0, 500)
	  FOR(j, 0, 500) ilo[i][j] = i * j;

	FOR(i, 1, m) scanf("%s", s[i] + 1);
	FOR(i, 1, m)
	  FOR(j, 1, n) ile[j] += s[i][j] - '0';

	FOR(i, 1, n)
	  if (ile[i] > 2) OUT(0);

	int id = 0, ij = 0;
	FOR(i, 1, n)
	{
	  	if (ile[i] == 0) ++id;
	  	if (ile[i] == 1) ++ij;
	}
	//cout << id << ' ' << ij << endl;
	odp[id][ij] = 1;
	FOR(steps, m+1, n)
	{
		FOR(i, 0, id)
		  FOR(j, 0, n)
		  {
		  		ll val = odp[i][j+2];
		  		val = (val * bin2[j+2])%mod;
		  		dp[i][j] = val;

		  		val = odp[i+1][j];
		  		val = (val * ilo[i+1][j])%mod;
		  		dp[i][j] += val;
		  		while (dp[i][j] >= mod) dp[i][j] -= mod;

		  		if (j - 2 >= 0)
				{
					val = odp[i+2][j-2];
		  			val = (val * bin2[i+2])%mod;
		  			dp[i][j] += val;
		  			while (dp[i][j] >= mod) dp[i][j] -= mod;
		  		}

		  		//if (dp[i][j] > 0) cout << dp[i][j] << " WSK : " << i << ' ' << j << endl;
		  }
		FOR(i, 0, id)
		  FOR(j, 0, n) odp[i][j] = dp[i][j];
	//	cout << "ENDSTEP\n";
	}

	cout << odp[0][0];
}


#include <bits/stdc++.h>
using namespace std;
#define e1 first
#define e2 second
#define pb push_back
#define mp make_pair
#define boost ios_base::sync_with_stdio(false)
#define eb emplace_back
#define OUT(x) {cout << x; exit(0); }
#define FOR(i, a, b) for(int i=(a); i<=(b); ++i)
typedef long long ll;
typedef unsigned long long ull;
typedef pair <int, int> PII;
typedef pair <ll, ll> PLL;
typedef pair <PLL, PLL> PP;
typedef unsigned int ui;
const int inf = 1e9+9;
const ll MOD = 1e9+696969;
const ll INF = 1e18;
#define maxn 510
int dp[maxn][maxn], odp[maxn][maxn], n, m, mod;

int ile[maxn];
char s[maxn][maxn];
int bin2[maxn], ilo[maxn][maxn];
;

int main()
{
	scanf("%d%d%d", &n, &m, &mod);
	FOR(i, 0, 500) bin2[i] = i * (i-1)/2;
	FOR(i, 0, 500)
	  FOR(j, 0, 500) ilo[i][j] = i * j;

	FOR(i, 1, m) scanf("%s", s[i] + 1);
	FOR(i, 1, m)
	  FOR(j, 1, n) ile[j] += s[i][j] - '0';

	FOR(i, 1, n)
	  if (ile[i] > 2) OUT(0);

	int id = 0, ij = 0;
	FOR(i, 1, n)
	{
	  	if (ile[i] == 0) ++id;
	  	if (ile[i] == 1) ++ij;
	}
	//cout << id << ' ' << ij << endl;
	odp[ij][id] = 1;
	int CST = 2 * id + ij;
	FOR(steps, m+1, n)
	{
		FOR(i, 0, id)
		  FOR(j, 0, n)
		  {
		  		if (2 * i + j + 2 * (steps - m) != CST) continue;
		  		ll W = 0;
				ll val = odp[j+2][i];
		  		val = (val * bin2[j+2]);
		  		W += val;

		  		val = odp[j][i+1];
		  		val = (val * ilo[i+1][j]);
		  		W += val;

		  		if (j - 2 >= 0)
				{
					val = odp[j-2][i+2];
		  			val = (val * bin2[i+2]);
		  			W += val;
		  		}
		  		dp[j][i] = (W % mod);
		  		//if (dp[i][j] > 0) cout << dp[i][j] << " WSK : " << i << ' ' << j << endl;
		  }
		FOR(i, 0, id)
		  FOR(j, 0, n) odp[j][i] = dp[j][i];
	//	cout << "ENDSTEP\n";
	}

	cout << odp[0][0];
}


#include <bits/stdc++.h>
using namespace std;
#define e1 first
#define e2 second
#define pb push_back
#define mp make_pair
#define boost ios_base::sync_with_stdio(false)
#define eb emplace_back
#define OUT(x) {cout << x; exit(0); }
#define FOR(i, a, b) for(int i=(a); i<=(b); ++i)
typedef long long ll;
typedef unsigned long long ull;
typedef pair <int, int> PII;
typedef pair <ll, ll> PLL;
typedef pair <PLL, PLL> PP;
typedef unsigned int ui;
const int inf = 1e9+9;
const ll MOD = 1e9+696969;
const ll INF = 1e18;
#define maxn 510
int dp[maxn][maxn], n, m, mod;

int ile[maxn];
char s[maxn][maxn];

int main()
{
	scanf("%d%d%d", &n, &m, &mod);
	FOR(i, 1, m) scanf("%s", s[i] + 1);
	FOR(i, 1, m)
	  FOR(j, 1, n) ile[j] += s[i][j] - '0';

	FOR(i, 1, n)
	  if (ile[i] > 2) OUT(0);

	int id = 0, ij = 0;
	FOR(i, 1, n)
	{
	  	if (ile[i] == 0) ++id;
	  	if (ile[i] == 1) ++ij;
	}

	cout << id << ' ' << ij << endl;
	dp[id][ij] = 1;
	FOR(steps, m+1, n)
	{
		FOR(i, 0, id)
		  FOR(j, 0, ij)
		  {
		  		int bin = (j + 2) * (j + 1) / 2;
		  		ll val = dp[i][j+2];
		  		val = (val * bin)%mod;
		  		dp[i][j] = val;
		  		val = dp[i+1][j];
		  		val = (val * (i+1) * j)%mod;
		  		dp[i][j] += val;
		  		while (dp[i][j] >= mod) dp[i][j] -= mod;

		  		//if (dp[i][j] > 0) cout << dp[i][j] << " WSK : " << i << ' ' << j << endl;
		  }
		//cout << "ENDSTEP\n";
	}

	cout << dp[0][0];
}


#include <bits/stdc++.h>
using namespace std;
#define e1 first
#define e2 second
#define pb push_back
#define mp make_pair
#define boost ios_base::sync_with_stdio(false)
#define eb emplace_back
#define OUT(x) {cout << x; exit(0); }
#define FOR(i, a, b) for(int i=(a); i<=(b); ++i)
typedef long long ll;
typedef unsigned long long ull;
typedef pair <int, int> PII;
typedef pair <ll, ll> PLL;
typedef pair <PLL, PLL> PP;
typedef unsigned int ui;
const int inf = 1e9+9;
const ll MOD = 1e9+696969;
const ll INF = 1e18;
#define maxn 510
int dp[maxn][maxn], odp[maxn][maxn], n, m, mod;

int ile[maxn];
char s[maxn][maxn];
int bin2[maxn], ilo[maxn][maxn];
;

int main()
{
	scanf("%d%d%d", &n, &m, &mod);
	FOR(i, 0, 500) bin2[i] = i * (i-1)/2;
	FOR(i, 0, 500)
	  FOR(j, 0, 500) ilo[i][j] = i * j;

	FOR(i, 1, m) scanf("%s", s[i] + 1);
	FOR(i, 1, m)
	  FOR(j, 1, n) ile[j] += s[i][j] - '0';

	FOR(i, 1, n)
	  if (ile[i] > 2) OUT(0);

	int id = 0, ij = 0;
	FOR(i, 1, n)
	{
	  	if (ile[i] == 0) ++id;
	  	if (ile[i] == 1) ++ij;
	}
	//cout << id << ' ' << ij << endl;
	odp[ij][id] = 1;
	FOR(steps, m+1, n)
	{
		FOR(i, 0, id)
		  FOR(j, 0, n)
		  {
		  		ll W = 0;
				ll val = odp[j+2][i];
		  		val = (val * bin2[j+2]);
		  		W += val;

		  		val = odp[j][i+1];
		  		val = (val * ilo[i+1][j]);
		  		W += val;

		  		if (j - 2 >= 0)
				{
					val = odp[j-2][i+2];
		  			val = (val * bin2[i+2]);
		  			W += val;
		  		}
		  		dp[j][i] = (W % mod);
		  		//if (dp[i][j] > 0) cout << dp[i][j] << " WSK : " << i << ' ' << j << endl;
		  }
		FOR(i, 0, id)
		  FOR(j, 0, n) odp[j][i] = dp[j][i];
	//	cout << "ENDSTEP\n";
	}

	cout << odp[0][0];
}


#include <bits/stdc++.h>
using namespace std;
#define e1 first
#define e2 second
#define pb push_back
#define mp make_pair
#define boost ios_base::sync_with_stdio(false)
#define eb emplace_back
#define OUT(x) {cout << x; exit(0); }
#define FOR(i, a, b) for(int i=(a); i<=(b); ++i)
typedef long long ll;
typedef unsigned long long ull;
typedef pair <int, int> PII;
typedef pair <ll, ll> PLL;
typedef pair <PLL, PLL> PP;
typedef unsigned int ui;
const int inf = 1e9+9;
const ll MOD = 1e9+696969;
const ll INF = 1e18;
#define maxn 510
int dp[maxn][maxn], n, m, mod;

int ile[maxn];
char s[maxn][maxn];

int main()
{
	scanf("%d%d%d", &n, &m, &mod);
	FOR(i, 1, m) scanf("%s", s[i] + 1);
	FOR(i, 1, m)
	  FOR(j, 1, n) ile[j] += s[i][j] - '0';

	FOR(i, 1, n)
	  if (ile[i] > 2) OUT(0);

	int id = 0, ij = 0;
	FOR(i, 1, n)
	{
	  	if (ile[i] == 0) ++id;
	  	if (ile[i] == 1) ++ij;
	}

	dp[id][ij] = 1;
	FOR(steps, m+1, n)
	{
		FOR(i, 0, id)
		  FOR(j, 0, ij)
		  {
		  		int bin = (j + 2) * (j + 1) / 2;
		  		ll val = dp[i][j+2];
		  		val = (val * bin)%mod;
		  		dp[i][j] = val;
		  		val = dp[i+1][j];
		  		val = (val * (i+1) * j)%mod;
		  		dp[i][j] += val;
		  		while (dp[i][j] >= mod) dp[i][j] -= mod;

		  		//if (dp[i][j] > 0) cout << dp[i][j] << " WSK : " << i << ' ' << j << endl;
		  }
		//cout << "ENDSTEP\n";
	}

	cout << dp[0][0];
}


#include <bits/stdc++.h>
#define ll long long
#define pb push_back
#define pll pair<ll,ll>
#define P push
#define R return
#define C continue
#define MEM(dp,i) memset(dp,i,sizeof(dp))
#define SI size()
#define F first
#define S second
#define W while
using namespace std;
long long MOD=1e9+7;
long long INF=1e17+7;
ll dp[3][503][503];
ll n;
ll c[503];
int main()
{
    ll m;
    cin>>n>>m>>MOD;
//    n=500,m=0;
    for(int i=0;i<m;i++){
        ll s=0;
        char cc[502];
        scanf("%s",&cc);
        for(int j=0;j<n;j++){
            char x=cc[j];
            s+=(x=='1');
            c[j]+=(x=='1');
        }
        if(s!=2){
            cout<<0;
            R 0;
        }
    }
    ll x=0,y=0;
    for(int i=0;i<n;i++){
        if(c[i]>2){
            cout<<0;
            R 0;
        }
        if(c[i]==1)x++;
        if(c[i]==0)y++;
    }
    ll cur=0;
    dp[0][0][0]=1;
    for(int i=n;i>m;i--){
        for(int j=0;j<=<=min(n,(n-i+1)*2);j++){
            for(int k=0;k<=min(n,(n-i+1)*2);k++){
                if(j+k>n)break;
                ll &ret=dp[cur^1][j][k];
                ret=0;
                if(j>=2)
                    ret+=j*(j-1)/2*dp[cur][j-2][k+2];
                if(k>=2)
                    ret+=k*(k-1)/2*dp[cur][j][k-2];
                ret+=j*k*dp[cur][j-1][k];
                ret%=MOD;
            }
        }
        cur^=1;
    }
    cout<<dp[cur][y][x];
    return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define pb push_back
#define pll pair<ll,ll>
#define P push
#define R return
#define C continue
#define MEM(dp,i) memset(dp,i,sizeof(dp))
#define SI size()
#define F first
#define S second
#define W while
using namespace std;
long long MOD=1e9+7;
long long INF=1e17+7;
ll dp[3][503][503];
ll n;
ll c[503];
int main()
{
    ll m;
    cin>>n>>m>>MOD;
    for(int i=0;i<m;i++){
        ll s=0;
        for(int j=0;j<n;j++){
            char x;
            cin>>x;
            s+=(x=='1');
            c[j]+=(x=='1');
        }
        if(s!=2){
            cout<<0;
            R 0;
        }
    }
    ll x=0,y=0;
    for(int i=0;i<n;i++){
        if(c[i]>2){
            cout<<0;
            R 0;
        }
        if(c[i]==1)x++;
        if(c[i]==0)y++;
    }
    ll cur=0;
    dp[0][0][0]=1;
    for(int i=n;i>m;i--){
        for(int j=0;j<=n;j++){
            for(int k=0;k<=n;k++){
                if(j+k>n)break;
                ll &ret=dp[cur^1][j][k];
                if(j>=2){
                    ret+=j*(j-1)/2*dp[cur][j-2][k+2];
                }
                if(k>=2){
                    ret+=k*(k-1)/2*dp[cur][j][k-2];
                }
                if(j>0&&k>0){
                    ret+=j*k*dp[cur][j-1][k];
                }
            }
        }
        MEM(dp[cur],0);
        cur^=1;
    }
    cout<<dp[cur][y][x];
    return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>

#define N 300000
#define lgN 22
#define LL long long int
using namespace std;

vector <int> g[N];
LL ans[lgN][N][2],tmp[lgN][2],res=0;
int V[N];

void dfs(int node,int prnt) {
	int i;
	LL curr=V[node];
	for (i=0;i<lgN;i++) ans[node][i][1]=((V[node]&(1<<i))>0);
	for (i=0;i<lgN;i++) ans[node][i][0]=1-ans[node][i][1];
	for (auto it:g[node]) {
		if (it==prnt) continue;
		dfs(it,node);

		for (i=0;i<lgN;i++) {
			curr+=(ans[node][i][0]*ans[it][i][1]+ans[node][i][1]*ans[it][i][0])*(1<<i);
			if (V[node]&(1<<i)) {
				ans[node][i][1] += ans[it][i][0];
				ans[node][i][0] += ans[it][i][1];
			}
			else {
				ans[node][i][0] += ans[it][i][0];
				ans[node][i][1] += ans[it][i][1];
			}
		}
 	}
 	res+=curr;
}

int main() {
	int n,i,u,v;
	cin >> n;
	for (i=0;i<n;i++) cin >> V[i];
	for (i=0;i<n-1;i++) {
		cin >> u >> v;
		g[u-1].push_back(v-1);
		g[v-1].push_back(u-1);
	}
	dfs(0,0);
	cout << res << '\n';

	return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5,M = 1e9 + 7;;
vector<vector<int>>g;
int col[N],dp[N][21][2];
long long ans;
void dfs(int u,int p){
	for(int i = 0;i < 21;i++)dp[u][i][!!(col[u]&(1<<i))] = 1;
	for(auto i : g[u]){
		if(i == p)continue;
		dfs(i,u);
		for(int j = 0;j < 21;j++){
			ans+=(1<<j)*dp[u][j][1]*1LL*dp[i][j][0];
			ans+=(1<<j)*dp[u][j][0]*1LL*dp[i][j][1];
		}
		for(int j = 0;j < 21;j++){
			dp[u][j][(!!((col[u]&(1<<j)))^1)]+=dp[i][j][1];
			dp[u][j][!!(col[u]&(1<<j))]+=dp[i][j][0];
		}
	}
}
int main(){
// 	freopen("readin.txt","r",stdin);
	int n;
	scanf("%d",&n);
	g.resize(n);
	for(int i = 0;i < n;i++)scanf("%d",col + i),ans+=col[i];
	for(int i = 1,a,b;i < n;i++){
		scanf("%d%d",&a,&b);
		g[--a].push_back(--b);
		g[b].push_back(a);
	}
	dfs(0,-1);
	printf("%lld\n",ans);
}


#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5,M = 1e9 + 7;;
vector<vector<int>>g;
int col[N],dp[N][21][2];
long long ans;
void dfs(int u,int p){
	for(int i = 0;i < 21;i++)dp[u][i][!!(col[u]&(1<<i))] = 1;
	for(auto i : g[u]){
		if(i == p)continue;
		dfs(i,u);
		for(int j = 0;j < 21;j++){
			ans+=(1<<j)*1LL*dp[u][j][1]*dp[i][j][0];
			ans+=(1<<j)*1LL*dp[u][j][0]*dp[i][j][1];
		}
		for(int j = 0;j < 21;j++){
			dp[u][j][(!!((col[u]&(1<<j)))^1)]+=dp[i][j][1];
			dp[u][j][!!(col[u]&(1<<j))]+=dp[i][j][0];
		}
	}
}
int main(){
// 	freopen("readin.txt","r",stdin);
	int n;
	scanf("%d",&n);
	g.resize(n);
	for(int i = 0;i < n;i++)scanf("%d",col + i),ans+=col[i];
	for(int i = 1,a,b;i < n;i++){
		scanf("%d%d",&a,&b);
		g[--a].push_back(--b);
		g[b].push_back(a);
	}
	dfs(0,-1);
	printf("%lld\n",ans);
}


#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5,M = 1e9 + 7;;
vector<vector<int>>g;
int col[N],dp[N][21][2];
long long ans;
void dfs(int u,int p){
	for(int i = 0;i < 21;i++)dp[u][i][!!(col[u]&(1<<i))] = 1;
	for(auto i : g[u]){
		if(i == p)continue;
		dfs(i,u);
		for(int j = 0;j < 21;j++){
			ans+=(1<<j)*dp[u][j][1]*1LL*dp[i][j][0];
			ans+=(1<<j)*dp[u][j][0]*1LL*dp[i][j][1];
		}
		for(int j = 0;j < 21;j++){
			dp[u][j][(!!((col[u]&(1<<j)))^1)]+=dp[i][j][1];
			dp[u][j][!!(col[u]&(1<<j))]+=dp[i][j][0];
		}
	}
}
int main(){
// 	freopen("readin.txt","r",stdin);
	int n;
	scanf("%d",&n);
	g.resize(n);
	for(int i = 0;i < n;i++)scanf("%d",col + i),ans+=col[i];
	for(int i = 1,a,b;i < n;i++){
		scanf("%d%d",&a,&b);
		g[--a].push_back(--b);
		g[b].push_back(a);
	}
	dfs(0,-1);
	printf("%d\n",ans);
}


#include<bits/stdc++.h>

#define x first
#define y second
#define y0 hi1
#define y1 hi2
#define ll long long
#define mp make_pair
#define pb push_back
#define sqr(a) (a)*(a)
#define ld long double
#define all(a) (a).begin(), (a).end()

using namespace std;

const int inf = 2000000000;
const int N = 1e5;
const int M = 10;

int a[N];
vector<int> g[N];

ll ans = 0;
int b[N][M];
ll cur[M][2], dp[N][M][2], dep[N][M][2];

void dfscalc(int v, int pr = -1){
    for(int i = 0; i < M; i++){
        int bt = ((a[v] & (1 << i)) > 0);
        b[v][i] = bt;
        dep[v][i][bt] = 1;
    }

    for(int i = 0; i < g[v].size(); i++){
        int to = g[v][i];
        if(to == pr){
            continue;
        }

        dfscalc(to, v);

        for(int j = 0; j < M; j++){
            for(int x = 0; x < 2; x++){
                dep[v][j][x ^ b[v][j]] += dep[to][j][x];
            }
        }
    }
}

void dfs(int v, int pr = -1){
    for(int i = 0; i < M; i++){
        //cout << v << " " << (1 << i) << " " << dep[v][i][1] << " " << cur[i][1] << "\n";
        ans += (dep[v][i][1] + (pr == -1 ? 0 : cur[i][1])) * (1 << i);
    }
    //cout << v << " " << ans << "\n";

    for(int i = 0; i < M; i++){
        cur[i][b[v][i]]++;
    }

    for(int i = 0; i < g[v].size(); i++){
        int to = g[v][i];
        if(to == pr){
            continue;
        }

        for(int j = 0; j < M; j++){
            for(int x = 0; x < 2; x++){
                cur[j][x ^ b[v][j]] += dep[to][j][x];
            }
        }
    }

    for(int i = 0; i < g[v].size(); i++){
        int to = g[v][i];
        if(to == pr){
            continue;
        }

        int cur1[M][2], cur2[M][2];
        for(int j = 0; j < M; j++){
            for(int x = 0; x < 2; x++){
                cur1[j][x] = cur[j][x];
                cur2[j][x] = 0;
            }
        }

        for(int j = 0; j < M; j++){
            for(int x = 0; x < 2; x++){
                cur[j][x ^ b[v][j]] -= dep[to][j][x];
            }
        }

        for(int j = 0; j < M; j++){
            for(int x = 0; x < 2; x++){
                cur2[j][x ^ b[to][j]] += cur[j][x];
            }
        }
        for(int j = 0; j < M; j++){
            for(int x = 0; x < 2; x++){
                cur[j][x] = cur2[j][x];
            }
        }

        dfs(to, v);

        for(int j = 0; j < M; j++){
            for(int x = 0; x < 2; x++){
                cur[j][x] = cur1[j][x];
            }
        }
    }

    for(int i = 0; i < M; i++){
        cur[i][b[v][i]]--;
    }
}

int main(){
    cin.tie(0);
    ios_base::sync_with_stdio(0);
    int n;
    cin >> n;
    ll sum = 0;
    for(int i = 0; i < n; i++){
        cin >> a[i];
        sum += a[i];
    }

    for(int i = 0; i < n - 1; i++){
        int q, w;
        cin >> q >> w;
        q--; w--;
        g[q].pb(w);
        g[w].pb(q);
    }

    dfscalc(0);
    dfs(0);

    cout << (ans + sum) / 2;
}


#include<bits/stdc++.h>

#define x first
#define y second
#define y0 hi1
#define y1 hi2
#define ll long long
#define mp make_pair
#define pb push_back
#define sqr(a) (a)*(a)
#define ld long double
#define all(a) (a).begin(), (a).end()

using namespace std;

const int inf = 2000000000;
const int N = 1e5;
const int M = 25;

int a[N];
vector<int> g[N];

ll ans = 0;
int b[N][M];
ll cur[M][2], dp[N][M][2], dep[N][M][2];

void dfscalc(int v, int pr = -1){
    for(int i = 0; i < M; i++){
        int bt = ((a[v] & (1 << i)) > 0);
        b[v][i] = bt;
        dep[v][i][bt] = 1;
    }

    for(int i = 0; i < g[v].size(); i++){
        int to = g[v][i];
        if(to == pr){
            continue;
        }

        dfscalc(to, v);

        for(int j = 0; j < M; j++){
            for(int x = 0; x < 2; x++){
                dep[v][j][x ^ b[v][j]] += dep[to][j][x];
            }
        }
    }
}

void dfs(int v, int pr = -1){
    for(int i = 0; i < M; i++){
        //cout << v << " " << (1 << i) << " " << dep[v][i][1] << " " << cur[i][1] << "\n";
        ans += (dep[v][i][1] + (pr == -1 ? 0 : cur[i][1])) * (1 << i);
    }
    //cout << v << " " << ans << "\n";

    for(int i = 0; i < M; i++){
        cur[i][b[v][i]]++;
    }

    for(int i = 0; i < g[v].size(); i++){
        int to = g[v][i];
        if(to == pr){
            continue;
        }

        for(int j = 0; j < M; j++){
            for(int x = 0; x < 2; x++){
                cur[j][x ^ b[v][j]] += dep[to][j][x];
            }
        }
    }

    for(int i = 0; i < g[v].size(); i++){
        int to = g[v][i];
        if(to == pr){
            continue;
        }

        int cur1[M][2], cur2[M][2];
        for(int j = 0; j < M; j++){
            for(int x = 0; x < 2; x++){
                cur1[j][x] = cur[j][x];
                cur2[j][x] = 0;
            }
        }

        for(int j = 0; j < M; j++){
            for(int x = 0; x < 2; x++){
                cur[j][x ^ b[v][j]] -= dep[to][j][x];
            }
        }

        for(int j = 0; j < M; j++){
            for(int x = 0; x < 2; x++){
                cur2[j][x ^ b[to][j]] += cur[j][x];
            }
        }
        for(int j = 0; j < M; j++){
            for(int x = 0; x < 2; x++){
                cur[j][x] = cur2[j][x];
            }
        }

        dfs(to, v);

        for(int j = 0; j < M; j++){
            for(int x = 0; x < 2; x++){
                cur[j][x] = cur1[j][x];
            }
        }
    }

    for(int i = 0; i < M; i++){
        cur[i][b[v][i]]--;
    }
}

int main(){
    cin.tie(0);
    ios_base::sync_with_stdio(0);
    int n;
    cin >> n;
    ll sum = 0;
    for(int i = 0; i < n; i++){
        cin >> a[i];
        sum += a[i];
    }

    for(int i = 0; i < n - 1; i++){
        int q, w;
        cin >> q >> w;
        q--; w--;
        g[q].pb(w);
        g[w].pb(q);
    }

    dfscalc(0);
    dfs(0);

    cout << (ans + sum) / 2;
}


#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double K;
typedef pair<int, int> pii;

#define x first
#define y second
#define mp make_pair
#define pb push_back
#define all(a) (a).begin(), (a).end()

const int inf = 2000000000;
const int N = 1e5 + 5;
const int M = 22;

int n, k;
vector<int> g[N];
int a[N], level[N], parent[N];

ll ans = 0;

int dfs(int v, int size, int &center, int p = -1){
    int sum = 1;
    for(int i = 0; i < g[v].size(); i++){
        int to = g[v][i];
        if(to != p && level[to] == -1){
            sum += dfs(to, size, center, v);
        }
    }
    if(center == -1 && sum >= size / 2){
        center = v;
    }
    return sum;
}

void upds(int v, int pr, int s[M][2], int cur = 0){
    cur ^= a[v];
    for(int i = 0; i < M; i++){
        if(cur & (1 << i)){
            s[i][1]++;
        } else {
            s[i][0]++;
        }
    }

    for(int i = 0; i < g[v].size(); i++){
        int to = g[v][i];
        if(to != pr && level[to] == -1){
            upds(to, v, s, cur);
        }
    }
}

void updans(int v, int pr, int s[M][2], int cur = 0){
    cur ^= a[v];
    for(int i = 0; i < M; i++){
        if(cur & (1 << i)){
            ans += 1ll * (1 << i) * s[i][0];
        } else {
            ans += 1ll * (1 << i) * s[i][1];
        }
    }

    for(int i = 0; i < g[v].size(); i++){
        int to = g[v][i];
        if(to != pr && level[to] == -1){
            updans(to, v, s, cur);
        }
    }
}

void calc(int v){
    int s[M][2];
    for(int i = 0; i < M; i++){
        if(a[v] & (1 << i)){
            ans += (1 << i);
            s[i][1] = 1, s[i][0] = 0;
        } else {
            s[i][0] = 1, s[i][1] = 0;
        }
    }

    for(int i = 0; i < g[v].size(); i++){
        int to = g[v][i];
        if(level[to] == -1){
            ll oldans = ans;
            updans(to, v, s);
            upds(to, v, s, a[v]);
        }
    }
}

void build(int v, int depth, int last){
    int center = -1, tmp = 0;

    dfs(v, dfs(v, 0, tmp), center);
    level[center] = depth;
    parent[center] = last;

    calc(center);

    for(int i = 0; i < g[center].size(); i++){
        int to = g[center][i];
        if(level[to] == -1){
            build(to, depth + 1, center);
        }
    }
}

main(){
    cin.tie(0);
    ios_base::sync_with_stdio(0);

    memset(level, -1, sizeof(level));

    cin >> n;
    for(int i = 1; i <= n; i++){
        cin >> a[i];
    }

    for(int i = 1; i < n; i++){
        int q, w;
        cin >> q >> w;
        g[q].pb(w);
        g[w].pb(q);
    }

    int root = 1;
    build(root, 0, -1);

    cout << ans << "\n";
}


//new.cpp
/*
Author : Hocky Yudhiono
Sen 22 Apr 2019 12:17:42  WIB
Current Local Time : 12:17:42

getchar_unlocked > getchar > cin without sync > scanf > cin with sync
bool operator<(const MyStruct& rhs) const

On how to print Long Double to 5 decimal places :
printf("%.5Lf",ans);

On how to get random numbers :
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); //For int
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count()); //For LL
cout << rng() << endl;
shuffle(isi.begin(),isi.end(),rng);

__gcd(a,b)
__builtin_ffs(a) first on bit
__builtin_clz(a) count leading zero
__builtin_ctz(a) count trailing zero
__builtin_popcount(a) numbers of on bits

*/

#include <unordered_map>
//#include <unordered_set>

//#include <random>
//#include <chrono>

//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cassert>
#include <cstring>
#include <iomanip>
#include <cstdio>
#include <limits>
#include <string>
#include <vector>
#include <cmath>
#include <deque>
#include <queue>
#include <stack>
#include <map>
#include <set>

//using namespace __gnu_pbds;
using namespace std;

#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC optimize(3)
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#pragma GCC target("sse3","sse2","sse")
#pragma GCC target("avx","sse4","sse4.1","sse4.2","ssse3")
#pragma GCC target("f16c")
#pragma GCC optimize("inline","fast-math","unroll-loops","no-stack-protector")
// #pragma GCC diagnostic error "-fwhole-program"
// #pragma GCC diagnostic error "-fcse-skip-blocks"
// #pragma GCC diagnostic error "-funsafe-loop-optimizations"
// #pragma GCC diagnostic error "-std=c++14"
// #pragma GCC target ("string"...)
#pragma GCC push_options
#pragma GCC pop_options
#pragma GCC reset_options
#pragma GCC optimize ("O3")

typedef long long LL;
typedef long double LD;
typedef unsigned long long ULL;
// typedef tree<long long, null_type, less<long long>, rb_tree_tag, tree_order_statistics_node_update> pbds;
//If the time limit is strict, try not to use long double

#define fbo find_by_order
#define ook order_of_key
#define mp make_pair
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define remove erase
//Remember to undefine if the problem is interactive
#define endl '\n'
#define DEBUG(X) cout << ">>> DEBUG(" << __LINE__ << ") " << #X << " = " << (X) << endl

const double eps = 1e-9;
const int INFMEM = 63;
const int INF = 1061109567;
const LL LINF = 4557430888798830399LL;
const double DINF = numeric_limits<double>::infinity();
const LL MOD = 1000000007;
const int dx[8] = {1,0,-1,0,1,1,-1,-1};
const int dy[8] = {0,1,0,-1,1,-1,1,-1};
const double PI = 3.141592653589793;

#ifdef _WIN32
#define getchar_unlocked getchar
#endif
#define GETCHAR getchar_unlocked
inline void fastll(LL &input_number)
{
    input_number = 0;
    int ch = GETCHAR();
    int sign = 1;
    while(ch < '0' || ch > '9'){
        if(ch == '-') sign=-1;
        ch = GETCHAR();
    }
    while(ch >= '0' && ch <= '9'){
        input_number = (input_number << 3)+(input_number << 1) + ch-'0';
        ch = GETCHAR();
    }
    input_number *= sign;
}

inline void open(string a){
    freopen((a+".in").c_str(),"r",stdin);
    freopen((a+".out").c_str(),"w",stdout);
}

inline void fasterios(){
    //Do not use if interactive
    ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
}

LL k;
LL logn = 20;
LL logN = 16;
LL sz[100005];
LL isi[100005];
LL pref[100005];
LL depth[100005];
LL subsz[100005];
bool done[100005];
LL n,m,curroot,root;
LL sparset[100005][25];
LL centroidpar[100005];
vector <LL> edge[100005];
LL centree[100005][25][2];
LL mergecnt[100005][25][2];
//LCA

void dfs(LL pos, LL par){
	for(int i = 0;i < edge[pos].size();i++){
		LL nx = edge[pos][i];
		if(nx == par) continue;
		sparset[nx][0] = pos;
		depth[nx] = depth[pos]+1;
		pref[nx] = pref[pos]^isi[nx];
		dfs(nx,pos);
	}
	return;
}

LL lca(LL a, LL b){
	if(depth[a] > depth[b]) swap(a,b);
	for(int i = logN;i >= 0;i--){
		if(depth[b]-(1LL<<i) < depth[a]) continue;
		b = sparset[b][i];
	}
	if(a == b) return a;
	for(int i = logN;i >= 0;i--){
		if(sparset[a][i] == sparset[b][i]) continue;
		a = sparset[a][i];
		b = sparset[b][i];
	}
	return sparset[a][0];
}

LL dist(LL a, LL b){
	LL curlca = lca(a,b);
	return (pref[a]^pref[b]^isi[curlca]);
}

//centroid decomposition

void dfssz(LL pos, LL par){
	subsz[pos] = 1;
	for(int i = 0;i < edge[pos].size();i++){
		LL nx = edge[pos][i];
		if(nx == par || done[nx]) continue;
		dfssz(nx,pos);
		subsz[pos] += subsz[nx];
	}
	return;
}

LL getcent(LL pos, LL par){
	for(int i = 0;i < edge[pos].size();i++){
		LL nx = edge[pos][i];
		if(nx == par || done[nx]) continue;
		if(subsz[nx] > subsz[curroot]/2) return getcent(nx,pos);
	}
	return pos;
}

LL decompose(LL pos){
	curroot = pos;
	dfssz(pos,-1);
	pos = getcent(pos,-1);
	done[pos] = 1;
	for(int i = 0;i < edge[pos].size();i++){
		LL nx = edge[pos][i];
		if(done[nx]) continue;
		LL nxcent = decompose(nx);
		centroidpar[nxcent] = pos;
	}
	return pos;
}

int main(){
	LL ans = 0;
	fastll(n);
	for(int i = 1;i <= n;i++) fastll(isi[i]);
	pref[1] = isi[1];
    for(int i = 1;i < n;i++){
    	LL u,v; fastll(u); fastll(v);
    	edge[u].pb(v);
    	edge[v].pb(u);
    }
    memset(sparset,-1,sizeof(sparset));
    depth[1] = 1;
    dfs(1,-1);
    for(int i = 0;i < logN;i++){
    	for(int j = 1;j <= n;j++){
    		if(sparset[j][i] == -1) continue;
    		sparset[j][i+1] = sparset[sparset[j][i]][i];
    	}
    }
    for(int i = 1;i <= n;i++) centroidpar[i] = -1;
    root = decompose(1);
	for(int i = 1;i <= n;i++){
		ans += isi[i];
		LL pos = i;
		LL ori = i;
		LL pre = -1;
		while(pos != -1){
			LL mask = (dist(ori,pos)^isi[pos]);
			for(int j = 0;j <= logn;j++){
				bool cari = (((1LL<<j)&mask) == 0);
				LL tmp = mergecnt[pos][j][cari];
				if(pre != -1) tmp -= centree[pre][j][cari];
				ans += (1LL<<j)*(tmp);
			}
			pre = pos;
			pos = centroidpar[pos];
		}
		pos = i;
		ori = i;
		for(int j = 0;j <= logn;j++){
			bool taroh = (((1LL<<j)&isi[pos]) != 0);
			mergecnt[pos][j][taroh]++;
		}
		while(centroidpar[pos] != -1){
			LL mask = dist(ori,centroidpar[pos]);
			for(int j = 0;j <= logn;j++){
				bool taroh = ((mask&(1LL<<j)) != 0);
				centree[pos][j][taroh]++;
				mergecnt[centroidpar[pos]][j][taroh]++;
			}
			pos = centroidpar[pos];
		}
	}
	printf("%lld\n",ans);
    return 0;
}


#include <unordered_map>
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cassert>
#include <cstring>
#include <iomanip>
#include <cstdio>
#include <limits>
#include <string>
#include <vector>
#include <cmath>
#include <deque>
#include <queue>
#include <stack>
#include <map>
#include <set>

#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC optimize(3)
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#pragma GCC target("sse3","sse2","sse")
#pragma GCC target("avx","sse4","sse4.1","sse4.2","ssse3")
#pragma GCC target("f16c")
#pragma GCC optimize("inline","fast-math","unroll-loops","no-stack-protector")
#pragma GCC push_options
#pragma GCC pop_options
#pragma GCC reset_options
#pragma GCC optimize ("O3")

using namespace std;

typedef long long LL;
typedef long double LD;
typedef unsigned long long ULL;

#define fbo find_by_order
#define ook order_of_key
#define mp make_pair
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define remove erase
//Remember to undefine if the problem is interactive
#define endl '\n'
#define DEBUG(X) cout << ">>> DEBUG(" << __LINE__ << ") " << #X << " = " << (X) << endl

const double eps = 1e-9;
const int INFMEM = 63;
const int INF = 1061109567;
const LL LINF = 4557430888798830399LL;
const double DINF = numeric_limits<double>::infinity();
const LL MOD = 1000000007;
const int dx[8] = {1,0,-1,0,1,1,-1,-1};
const int dy[8] = {0,1,0,-1,1,-1,1,-1};
const double PI = 3.141592653589793;

#ifdef _WIN32
#define getchar_unlocked getchar
#endif
#define GETCHAR getchar_unlocked
inline void fastll(LL &input_number)
{
    input_number = 0;
    int ch = GETCHAR();
    int sign = 1;
    while(ch < '0' || ch > '9'){
        if(ch == '-') sign=-1;
        ch = GETCHAR();
    }
    while(ch >= '0' && ch <= '9'){
        input_number = (input_number << 3)+(input_number << 1) + ch-'0';
        ch = GETCHAR();
    }
    input_number *= sign;
}

inline void fasterios(){
    //Do not use if interactive
    ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
}

LL logN = 15;
LL subsz[20005];
LL depth[20005];
bool done[20005];
LL n,q,curroot,root;
LL sparset[20005][20];
LL centroidpar[20005];
vector <LL> edge[20005];
unordered_map <LL,LL> centree[20005][2];
unordered_map <LL,LL> centidx[20005][2];

LL dfs(LL pos, LL par){
	for(int i = 0;i < edge[pos].size();i++){
		LL nx = edge[pos][i];
		if(par == nx) continue;
		sparset[nx][0] = pos;
		depth[nx] = depth[pos]+1;
		dfs(nx,pos);
	}
}

LL lca(LL a, LL b){
	if(depth[a] > depth[b]) swap(a,b);
	for(int i = logN;i >= 0;i--){
		if(depth[b]-(1LL<<i) < depth[a]) continue;
		b = sparset[b][i];
	}
	if(a == b) return a;
	for(int i = logN;i >= 0;i--){
		if(sparset[a][i] == sparset[b][i]) continue;
		a = sparset[a][i];
		b = sparset[b][i];
	}
	return sparset[a][0];
}

LL dist(LL a, LL b){
	LL curlca = lca(a,b);
	return depth[a]+depth[b]-(2*depth[curlca]);
}

//Centroid decomposition
//Be careful, god bless you

void dfssz(LL pos, LL par){
	subsz[pos] = 1;
	for(int i = 0;i < edge[pos].size();i++){
		LL nx = edge[pos][i];
		if(par == nx || done[nx]) continue;
		dfssz(nx,pos);
		subsz[pos] += subsz[nx];
	}
	return;
}

LL nxcent(LL pos, LL par){
	for(int i = 0;i < edge[pos].size();i++){
		LL nx = edge[pos][i];
		if(par == nx || done[nx]) continue;
		if(subsz[nx] > subsz[curroot]/2) return nxcent(nx,pos);
	}
	return pos;
}

LL decompose(LL pos){
	curroot = pos;
	dfssz(pos,-1);
	pos = nxcent(pos,-1);
	done[pos] = 1;
	for(int i = 0;i < edge[pos].size();i++){
		LL nx = edge[pos][i];
		if(done[nx]) continue;
		LL nxcent = decompose(nx);
		centroidpar[nxcent] = pos;
	}
	return pos;
}

int main(){
	fasterios();
	cin >> n >> q;
	for(int i = 1;i < n;i++){
		LL u,v; cin >> u >> v;
		edge[u].pb(v);
		edge[v].pb(u);
	}
	depth[1] = 1;
	memset(sparset,-1,sizeof(sparset));
	dfs(1,-1);
    for(int i = 0;i < logN;i++){
    	for(int j = 1;j <= n;j++){
			if(sparset[j][i] == -1) continue;
			sparset[j][i+1] = sparset[sparset[j][i]][i];
		}
    }
	for(int i = 1;i <= n;i++) centroidpar[i] = -1;
	root = decompose(1);
	for(int i = 1;i <= n;i++){
		LL ori = i;
		LL pos = i;
		centree[pos][0][0] = ori;
		centree[pos][1][0] = ori;
		centidx[pos][0][0] = 0;
		centidx[pos][1][0] = 0;
//		cout << "Adding pos to the centroid " << pos << endl;
		while(centroidpar[pos] != -1){
			LL curdist = dist(ori,centroidpar[pos]);
//			cout << ori << " " << centroidpar[pos] << " has distance " << curdist << " at pos " << pos << endl;
			if(!centree[centroidpar[pos]][0].count(curdist)){
				centree[centroidpar[pos]][0][curdist] = ori;
				centidx[centroidpar[pos]][0][curdist] = pos;
			}else if(!centree[centroidpar[pos]][1].count(curdist) && centidx[centroidpar[pos]][0][curdist] != pos){
				centree[centroidpar[pos]][1][curdist] = ori;
				centidx[centroidpar[pos]][1][curdist] = pos;
			}
			pos = centroidpar[pos];
		}
	}
	while(q--){
		LL ori,pos,d;
		cin >> pos >> d;
		ori = pos;
		LL ans = 0;
		LL pre = -1;
		while(pos != -1){
			LL curdist = d-dist(ori,pos);
//			cout << curdist << " " << ori << " " << pos << endl;
			if(curdist >= 0){
				if(centree[pos][0].count(curdist) && centidx[pos][0][curdist] != pre){
					ans = centree[pos][0][curdist];
					break;
				}else if(centree[pos][1].count(curdist) && centidx[pos][1][curdist] != pre){
					ans = centree[pos][1][curdist];
					break;
				}
//				cout << "here" << endl;
			}
			pre = pos;
			pos = centroidpar[pos];
		}
		cout << ans << endl;
	}
	return 0;
}


//new.cpp
/*
Author : Hocky Yudhiono
Sen 22 Apr 2019 12:17:42  WIB
Current Local Time : 12:17:42

getchar_unlocked > getchar > cin without sync > scanf > cin with sync
bool operator<(const MyStruct& rhs) const

On how to print Long Double to 5 decimal places :
printf("%.5Lf",ans);

On how to get random numbers :
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); //For int
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count()); //For LL
cout << rng() << endl;
shuffle(isi.begin(),isi.end(),rng);

__gcd(a,b)
__builtin_ffs(a) first on bit
__builtin_clz(a) count leading zero
__builtin_ctz(a) count trailing zero
__builtin_popcount(a) numbers of on bits

*/

#include <unordered_map>
//#include <unordered_set>

//#include <random>
//#include <chrono>

//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cassert>
#include <cstring>
#include <iomanip>
#include <cstdio>
#include <limits>
#include <string>
#include <vector>
#include <cmath>
#include <deque>
#include <queue>
#include <stack>
#include <map>
#include <set>

//using namespace __gnu_pbds;
using namespace std;

#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC optimize(3)
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#pragma GCC target("sse3","sse2","sse")
#pragma GCC target("avx","sse4","sse4.1","sse4.2","ssse3")
#pragma GCC target("f16c")
#pragma GCC optimize("inline","fast-math","unroll-loops","no-stack-protector")
// #pragma GCC diagnostic error "-fwhole-program"
// #pragma GCC diagnostic error "-fcse-skip-blocks"
// #pragma GCC diagnostic error "-funsafe-loop-optimizations"
// #pragma GCC diagnostic error "-std=c++14"
// #pragma GCC target ("string"...)
#pragma GCC push_options
#pragma GCC pop_options
#pragma GCC reset_options
#pragma GCC optimize ("O3")

typedef long long LL;
typedef long double LD;
typedef unsigned long long ULL;
// typedef tree<long long, null_type, less<long long>, rb_tree_tag, tree_order_statistics_node_update> pbds;
//If the time limit is strict, try not to use long double

#define fbo find_by_order
#define ook order_of_key
#define mp make_pair
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define remove erase
//Remember to undefine if the problem is interactive
#define endl '\n'
#define DEBUG(X) cout << ">>> DEBUG(" << __LINE__ << ") " << #X << " = " << (X) << endl

const double eps = 1e-9;
const int INFMEM = 63;
const int INF = 1061109567;
const LL LINF = 4557430888798830399LL;
const double DINF = numeric_limits<double>::infinity();
const LL MOD = 1000000007;
const int dx[8] = {1,0,-1,0,1,1,-1,-1};
const int dy[8] = {0,1,0,-1,1,-1,1,-1};
const double PI = 3.141592653589793;

#ifdef _WIN32
#define getchar_unlocked getchar
#endif
#define GETCHAR getchar_unlocked
inline void fastll(LL &input_number)
{
    input_number = 0;
    int ch = GETCHAR();
    int sign = 1;
    while(ch < '0' || ch > '9'){
        if(ch == '-') sign=-1;
        ch = GETCHAR();
    }
    while(ch >= '0' && ch <= '9'){
        input_number = (input_number << 3)+(input_number << 1) + ch-'0';
        ch = GETCHAR();
    }
    input_number *= sign;
}

inline void open(string a){
    freopen((a+".in").c_str(),"r",stdin);
    freopen((a+".out").c_str(),"w",stdout);
}

inline void fasterios(){
    //Do not use if interactive
    ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
}

LL k;
LL logn = 21;
LL logN = 16;
LL sz[100005];
LL isi[100005];
LL pref[100005];
LL depth[100005];
LL subsz[100005];
bool done[100005];
LL n,m,curroot,root;
LL sparset[100005][20];
LL centroidpar[100005];
vector <LL> edge[100005];
LL centree[100005][23][2];
LL mergecnt[100005][23][2];
//LCA

void dfs(LL pos, LL par){
	for(int i = 0;i < edge[pos].size();i++){
		LL nx = edge[pos][i];
		if(nx == par) continue;
		sparset[nx][0] = pos;
		depth[nx] = depth[pos]+1;
		pref[nx] = pref[pos]^isi[nx];
		dfs(nx,pos);
	}
	return;
}

LL lca(LL a, LL b){
	if(depth[a] > depth[b]) swap(a,b);
	for(int i = logN;i >= 0;i--){
		if(depth[b]-(1LL<<i) < depth[a]) continue;
		b = sparset[b][i];
	}
	if(a == b) return a;
	for(int i = logN;i >= 0;i--){
		if(sparset[a][i] == sparset[b][i]) continue;
		a = sparset[a][i];
		b = sparset[b][i];
	}
	return sparset[a][0];
}

LL dist(LL a, LL b){
	LL curlca = lca(a,b);
	return (pref[a]^pref[b]^isi[curlca]);
}

//centroid decomposition

void dfssz(LL pos, LL par){
	subsz[pos] = 1;
	for(int i = 0;i < edge[pos].size();i++){
		LL nx = edge[pos][i];
		if(nx == par || done[nx]) continue;
		dfssz(nx,pos);
		subsz[pos] += subsz[nx];
	}
	return;
}

LL getcent(LL pos, LL par){
	for(int i = 0;i < edge[pos].size();i++){
		LL nx = edge[pos][i];
		if(nx == par || done[nx]) continue;
		if(subsz[nx] > subsz[curroot]/2) return getcent(nx,pos);
	}
	return pos;
}

LL decompose(LL pos){
	curroot = pos;
	dfssz(pos,-1);
	pos = getcent(pos,-1);
	done[pos] = 1;
	for(int i = 0;i < edge[pos].size();i++){
		LL nx = edge[pos][i];
		if(done[nx]) continue;
		LL nxcent = decompose(nx);
		centroidpar[nxcent] = pos;
	}
	return pos;
}

int main(){
	LL ans = 0;
	fastll(n);
	for(int i = 1;i <= n;i++){
		fastll(isi[i]);
	}
	pref[1] = isi[1];
    for(int i = 1;i < n;i++){
    	LL u,v; fastll(u); fastll(v);
    	edge[u].pb(v);
    	edge[v].pb(u);
    }
    memset(sparset,-1,sizeof(sparset));
    depth[1] = 1;
    dfs(1,-1);
    for(int i = 0;i < logN;i++){
    	for(int j = 1;j <= n;j++){
    		if(sparset[j][i] == -1) continue;
    		sparset[j][i+1] = sparset[sparset[j][i]][i];
    	}
    }
    for(int i = 1;i <= n;i++) centroidpar[i] = -1;
    root = decompose(1);
	for(int i = 1;i <= n;i++){
		//query here
		LL pos = i;
		LL ori = i;

		//Query here
//		cout << "Currently Querying " << i << endl;
		for(int j = 0;j <= logn;j++){
			ans += (1LL<<j)*(mergecnt[pos][j][1]);
		}
//		cout << "Current single answer " << ans << endl;
		LL pre = -1;
		while(pos != -1){
//			cout << "Dist " << dist(ori,centroidpar[pos]) << endl;
//			cout << "Current mask " << mask << endl;
			if(pre != -1){
				LL mask = (dist(ori,pre));
				for(int j = 0;j <= logn;j++){
					bool cari = ((mask&(1LL<<j)) == 0);
//					cout << "querying  " << j << " " << cari << " " << mergecnt[pos][j][cari] << endl;
					ans += (1LL<<j)*(mergecnt[pos][j][cari]-centree[pre][j][cari]);
				}
			}
//			cout << ans << endl;
			pre = pos;
			pos = centroidpar[pos];
		}
//		cout << "Current answer is " << ans << endl;
		//update here
		pos = i;
		ori = i;
		for(int j = 0;j <= logn;j++){
			bool taroh = (((1LL<<j)&isi[pos]) != 0);
			mergecnt[pos][j][taroh]++;
		}
//		cout << "Currently updating " << pos << endl;
		while(centroidpar[pos] != -1){
			LL mask = dist(ori,centroidpar[pos]);
//			cout << ori << " " << centroidpar[pos] << " " << mask << " " << pos << endl;
			for(int j = 0;j <= logn;j++){
				bool taroh = ((mask&(1LL<<j)) != 0);
				centree[pos][j][taroh]++;
				mergecnt[centroidpar[pos]][j][taroh]++;
			}
			pos = centroidpar[pos];
		}
	}
	for(int i = 1;i <= n;i++) ans += isi[i];
	printf("%lld\n",ans);
    return 0;
}


// Solution seen ;

#include<bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define fastread ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
#define openfile ifstream cin; ofstream cout; cin.open("input.txt"); cout.open("output.txt");
#define f(i, x, y) for(int i = x; i < y; i++)
#define all(X) X.begin(), X.end()
#define int long long
#define key pair<int, int>
#define keyd pair<double, double>
#define ff first
#define ss second
#define double long double
int mod = 1e9+7;
const int inf = 2e18;
using namespace std;

vector<int> g[100001];
int ans[20], size[100001], val[100001], idx = 0;

struct node
{
    key a; int i;
};

void findSize(int s, int p)
{
    size[s] = 0;
    for(int i : g[s])
        if(i != p)
            size[s] += size[i];
    size[s]++;
}

key dfs(int s, int p)
{
    vector<node> v;
    for(int i : g[s])
    {
        if(i == p) continue;
        v.pb({dfs(i, s), i});
        int t = v.size()-1;
//        cout<<"a"<<s<<" "<<i<<" "<<v[t].a.ff<<" "<<v[t].a.ss<<" "<<(val[s] & (1<<idx))<<" "<<val[s]<<"a";
        if(val[s] & (1<<idx)) ans[idx] += v[t].a.ss;
        else ans[idx] += v[t].a.ff;
//        cout<<ans[idx]<<"\n";
    }
    int m = 0;
    for(node i : v) m = max(m, size[i.i]);
    f(i, 0, v.size())
        if(size[v[i].i] == m)
        {
            swap(v[i], v[v.size()-1]); break;
        }
    int sum1 = 0, sum2 = 0;
    for(node i : v)
    {
        sum1 += i.a.ff;  sum2 += i.a.ss;
    }
    int t1 = sum1, t2 = sum2;;
    if(val[s] & (1<<idx)) swap(sum1, sum2);

//    for(node i : v) cout<<i.a.ff<<" "<<i.a.ss<<"   ";
    f(i, 0, (int)v.size() - 1)
    {
        if(val[s] & (1<<idx)){ sum1 -= v[i].a.ss; sum2 -= v[i].a.ff; }
        else { sum1 -= v[i].a.ff; sum2 -= v[i].a.ss; }
//        cout<<s<<" "<<v[i].i<<" "<<i<<"\n";
    //    cout<<"  "<<sum1<<" "<<sum2<<"    ";
        if(sum1 != 0 || sum2 != 0)
        {

            ans[idx] += v[i].a.ff * sum2;
            ans[idx] += v[i].a.ss * sum1;
        }
    }
    if(val[s] & (1<<idx)) ans[idx]++;
//    cout<<ans[idx]<<" "<<(val[s] & (1<<idx))<<"\n";
    if(g[s].size() == 1 && p != -1) return {(bool)(val[s] & (1<<idx)), (bool)!((val[s] & (1<<idx)))};
    if(val[s] & (1<<idx)) return {t2+1, t1} ;
    else return {t1, t2+1};
}

main()
{
    //fastread;
    memset(ans, 0, sizeof(ans));
	int n; scanf("%lld", &n);
	f(i, 1, n+1) scanf("%lld", &val[i]);
	f(i, 1, n)
	{
	    int s, d; scanf("%lld %lld", &s, &d); g[s].pb(d); g[d].pb(s);
	}
	findSize(1, -1);
    f(i, 0, 20)
    {
        idx = i;
        dfs(1, -1);
    }
    int res = 0;
//    f(i, 0, 20) cout<<ans[i]<<" "; cout<<"\n";
    f(i, 0, 20) res += ans[i] * (1<<i);
    printf("%lld", res);
    //cout<<ans;
	return 0;
}


// Solution seen ;

#include<bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define fastread ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
#define openfile ifstream cin; ofstream cout; cin.open("input.txt"); cout.open("output.txt");
#define f(i, x, y) for(int i = x; i < y; i++)
#define all(X) X.begin(), X.end()
#define int long long
#define key pair<int, int>
#define keyd pair<double, double>
#define ff first
#define ss second
#define double long double
int mod = 1e9+7;
const int inf = 2e18;
using namespace std;

vector<int> g[100001];
int ans[20], size[100001], val[100001], idx = 0;

struct node
{
    key a; int i;
};

bool cmp(node a, node b)
{
    return size[a.i] < size[b.i];
}

void findSize(int s, int p)
{
    size[s] = 0;
    for(int i : g[s])
        if(i != p)
            size[s] += size[i];
    size[s]++;
}

void dfs1(int s, int p, int x1, int x2)
{
    if(val[s] & (1<<idx)) ans[idx] += x2;
    else ans[idx] += x1;

    for(int i : g[s])
        if(i != p)
        {
            if(val[s] & (1<<idx))   dfs1(i, s, x2, x1);
            else dfs1(i, s, x1, x2);
        }
}

key dfs(int s, int p)
{
    vector<node> v;
    for(int i : g[s])
    {
        if(i == p) continue;
        v.pb({dfs(i, s), i});
        int t = v.size()-1;
//        cout<<"a"<<s<<" "<<i<<" "<<v[t].a.ff<<" "<<v[t].a.ss<<" "<<(val[s] & (1<<idx))<<" "<<val[s]<<"a";
        if(val[s] & (1<<idx)) ans[idx] += v[t].a.ss;
        else ans[idx] += v[t].a.ff;
//        cout<<ans[idx]<<"\n";
    }
    sort(all(v), cmp);
    int sum1 = 0, sum2 = 0;
    for(node i : v)
    {
        sum1 += i.a.ff;  sum2 += i.a.ss;
    }
    int t1 = sum1, t2 = sum2;;
//    for(node i : v) cout<<i.a.ff<<" "<<i.a.ss<<"   ";
    f(i, 0, (int)v.size() - 1)
    {
        sum1 -= v[i].a.ff; sum2 -= v[i].a.ss;
    //    cout<<"  "<<sum1<<" "<<sum2<<"    ";
        if(sum1 != 0 || sum2 != 0)
        {
            if((val[s] & (1<<idx)))  dfs1(v[i].i, s, sum2, sum1);
            else dfs1(v[i].i, s, sum1, sum2);
        }
    }
    if(val[s] & (1<<idx)) ans[idx]++;
//    cout<<ans[idx]<<" "<<(val[s] & (1<<idx))<<"\n";
    if(g[s].size() == 1 && p != -1) return {(bool)(val[s] & (1<<idx)), (bool)!((val[s] & (1<<idx)))};
    if(val[s] & (1<<idx)) return {t2+1, t1} ;
    else return {t1, t2+1};
}

main()
{
    fastread;
    memset(ans, 0, sizeof(ans));
	int n; cin>>n;
	f(i, 1, n+1) cin>>val[i];
	f(i, 1, n)
	{
	    int s, d; cin>>s>>d; g[s].pb(d); g[d].pb(s);
	}
	findSize(1, -1);
    f(i, 0, 20)
    {
        idx = i;
        dfs(1, -1);
    }
    int res = 0;
//    f(i, 0, 20) cout<<ans[i]<<" "; cout<<"\n";
    f(i, 0, 20) res += ans[i] * (1<<i);
    cout<<res;
    //cout<<ans;
	return 0;
}


#include<bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define fastread ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
#define openfile ifstream cin; ofstream cout; cin.open("input.txt"); cout.open("output.txt");
#define f(i, x, y) for(int i = x; i < y; i++)
#define all(X) X.begin(), X.end()
#define int long long
#define key pair<int, int>
#define keyd pair<double, double>
#define ff first
#define ss second
#define double long double
int mod = 1e9+7;
const int inf = 2e18;
using namespace std;

vector<int> g[100001];
int ans = 0, size[100001], val[100001];

bool cmp(key a, key b)
{
    return size[a.ss] < size[b.ss];
}

void findSize(int s, int p)
{
    size[s] = 0;
    for(int i : g[s])
        if(i != p)
            size[s] += size[i];
    size[s]++;
}

void dfs1(int s, int p, int x)
{
    ans += x ^ val[s];
    for(int i : g[s])
        if(i != p)
            dfs1(i, s, x ^ val[s]);
}

int dfs(int s, int p)
{
    vector<key> v;
    for(int i : g[s])
    {
        if(i == p) continue;
        v.pb({dfs(i, s), i});
        ans += v[v.size()-1].ff ^ val[s];
    }
    sort(all(v), cmp);
    int sum = 0;
    for(key i : v) sum += i.ff;
    int t = sum;
//    for(key i : v) cout<<i.ff<<" "<<i.ss<<"   ";
    cout<<s<<" "<<t<<" "<<(t^val[s])<<" "<<val[s]<<" "<<ans<<"\n";
    f(i, 0, (int)v.size() - 1)
    {
        sum -= v[i].ff;
        if(sum != 0)
            dfs1(v[i].ss, s, sum ^ val[s]);
    }
    ans += val[s];
    if(g[s].size() == 1 && p != -1) return val[s];
    return ((t ^ val[s]) + val[s]);
}
11
main()
{
	int n; cin>>n;
	f(i, 1, n+1) cin>>val[i];
	f(i, 1, n)
	{
	    int s, d; cin>>s>>d; g[s].pb(d); g[d].pb(s);
	}
	findSize(1, -1);
    dfs(1, -1);
    cout<<ans;
	return 0;
}


// Solution seen ;

#include<bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define fastread ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
#define openfile ifstream cin; ofstream cout; cin.open("input.txt"); cout.open("output.txt");
#define f(i, x, y) for(int i = x; i < y; i++)
#define all(X) X.begin(), X.end()
#define int long long
#define key pair<int, int>
#define keyd pair<double, double>
#define ff first
#define ss second
#define double long double
int mod = 1e9+7;
const int inf = 2e18;
using namespace std;

vector<int> g[100001];
int ans[20], size[100001], val[100001], idx = 0;

struct node
{
    key a; int i;
};

void findSize(int s, int p)
{
    size[s] = 0;
    for(int i : g[s])
        if(i != p)
            size[s] += size[i];
    size[s]++;
}

void dfs1(int s, int p, int x1, int x2)
{
    if(val[s] & (1<<idx)) ans[idx] += x2;
    else ans[idx] += x1;

    for(int i : g[s])
        if(i != p)
        {
            if(val[s] & (1<<idx))   dfs1(i, s, x2, x1);
            else dfs1(i, s, x1, x2);
        }
}

key dfs(int s, int p)
{
    vector<node> v;
    for(int i : g[s])
    {
        if(i == p) continue;
        v.pb({dfs(i, s), i});
        int t = v.size()-1;
//        cout<<"a"<<s<<" "<<i<<" "<<v[t].a.ff<<" "<<v[t].a.ss<<" "<<(val[s] & (1<<idx))<<" "<<val[s]<<"a";
        if(val[s] & (1<<idx)) ans[idx] += v[t].a.ss;
        else ans[idx] += v[t].a.ff;
//        cout<<ans[idx]<<"\n";
    }
    int m = 0;
    for(node i : v) m = max(m, size[i.i]);
    f(i, 0, v.size())
        if(size[v[i].i] == m)
        {
            swap(v[i], v[v.size()-1]); break;
        }
    int sum1 = 0, sum2 = 0;
    for(node i : v)
    {
        sum1 += i.a.ff;  sum2 += i.a.ss;
    }
    int t1 = sum1, t2 = sum2;;
//    for(node i : v) cout<<i.a.ff<<" "<<i.a.ss<<"   ";
    f(i, 0, (int)v.size() - 1)
    {
        sum1 -= v[i].a.ff; sum2 -= v[i].a.ss;
//        cout<<s<<" "<<v[i].i<<" "<<i<<"\n";
    //    cout<<"  "<<sum1<<" "<<sum2<<"    ";
        if(sum1 != 0 || sum2 != 0)
        {
            if((val[s] & (1<<idx)))  dfs1(v[i].i, s, sum2, sum1);
            else dfs1(v[i].i, s, sum1, sum2);
        }
    }
    if(val[s] & (1<<idx)) ans[idx]++;
//    cout<<ans[idx]<<" "<<(val[s] & (1<<idx))<<"\n";
    if(g[s].size() == 1 && p != -1) return {(bool)(val[s] & (1<<idx)), (bool)!((val[s] & (1<<idx)))};
    if(val[s] & (1<<idx)) return {t2+1, t1} ;
    else return {t1, t2+1};
}

main()
{
    //fastread;
    memset(ans, 0, sizeof(ans));
	int n; scanf("%lld", &n);
	f(i, 1, n+1) scanf("%lld", &val[i]);
	f(i, 1, n)
	{
	    int s, d; scanf("%lld %lld", &s, &d); g[s].pb(d); g[d].pb(s);
	}
	findSize(1, -1);
    f(i, 0, 20)
    {
        idx = i;
        dfs(1, -1);
    }
    int res = 0;
//    f(i, 0, 20) cout<<ans[i]<<" "; cout<<"\n";
    f(i, 0, 20) res += ans[i] * (1<<i);
    printf("%lld", res);
    //cout<<ans;
	return 0;
}


// Solution seen ;

#include<bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define fastread ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
#define openfile ifstream cin; ofstream cout; cin.open("input.txt"); cout.open("output.txt");
#define f(i, x, y) for(int i = x; i < y; i++)
#define all(X) X.begin(), X.end()
#define int long long
#define key pair<int, int>
#define keyd pair<double, double>
#define ff first
#define ss second
#define double long double
int mod = 1e9+7;
const int inf = 2e18;
using namespace std;

vector<int> g[100001];
int ans[20], size[100001], val[100001], idx = 0;

struct node
{
    key a; int i;
};

void findSize(int s, int p)
{
    size[s] = 0;
    for(int i : g[s])
        if(i != p)
            size[s] += size[i];
    size[s]++;
}

void dfs1(int s, int p, int x1, int x2)
{
    if(val[s] & (1<<idx)) ans[idx] += x2;
    else ans[idx] += x1;

    for(int i : g[s])
        if(i != p)
        {
            if(val[s] & (1<<idx))   dfs1(i, s, x2, x1);
            else dfs1(i, s, x1, x2);
        }
}

key dfs(int s, int p)
{
    vector<node> v;
    for(int i : g[s])
    {
        if(i == p) continue;
        v.pb({dfs(i, s), i});
        int t = v.size()-1;
//        cout<<"a"<<s<<" "<<i<<" "<<v[t].a.ff<<" "<<v[t].a.ss<<" "<<(val[s] & (1<<idx))<<" "<<val[s]<<"a";
        if(val[s] & (1<<idx)) ans[idx] += v[t].a.ss;
        else ans[idx] += v[t].a.ff;
//        cout<<ans[idx]<<"\n";
    }
    int m = 0;
    for(node i : v) m = max(m, size[i.i]);
    f(i, 0, v.size())
        if(size[v[i].i] == m)
        {
            swap(v[i], v[v.size()-1]); break;
        }
    int sum1 = 0, sum2 = 0;
    for(node i : v)
    {
        sum1 += i.a.ff;  sum2 += i.a.ss;
    }
    int t1 = sum1, t2 = sum2;;
//    for(node i : v) cout<<i.a.ff<<" "<<i.a.ss<<"   ";
    f(i, 0, (int)v.size() - 1)
    {
        sum1 -= v[i].a.ff; sum2 -= v[i].a.ss;
    //    cout<<"  "<<sum1<<" "<<sum2<<"    ";
        if(sum1 != 0 || sum2 != 0)
        {
            if((val[s] & (1<<idx)))  dfs1(v[i].i, s, sum2, sum1);
            else dfs1(v[i].i, s, sum1, sum2);
        }
    }
    if(val[s] & (1<<idx)) ans[idx]++;
//    cout<<ans[idx]<<" "<<(val[s] & (1<<idx))<<"\n";
    if(g[s].size() == 1 && p != -1) return {(bool)(val[s] & (1<<idx)), (bool)!((val[s] & (1<<idx)))};
    if(val[s] & (1<<idx)) return {t2+1, t1} ;
    else return {t1, t2+1};
}

main()
{
    fastread;
    memset(ans, 0, sizeof(ans));
	int n; cin>>n;
	f(i, 1, n+1) cin>>val[i];
	f(i, 1, n)
	{
	    int s, d; cin>>s>>d; g[s].pb(d); g[d].pb(s);
	}
	findSize(1, -1);
    f(i, 0, 20)
    {
        idx = i;
        dfs(1, -1);
    }
    int res = 0;
//    f(i, 0, 20) cout<<ans[i]<<" "; cout<<"\n";
    f(i, 0, 20) res += ans[i] * (1<<i);
    cout<<res;
    //cout<<ans;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e5+10;
LL dp[maxn][2], a[maxn];
LL ans = 0;
int head[maxn], edgecnt;
struct edge{
    int to,next;
}E[maxn*2];
void init(){
    memset(head,-1,sizeof(head));
    edgecnt=0;
}
void add(int u,int v){
    E[edgecnt].to=v,E[edgecnt].next=head[u],head[u]=edgecnt++;
}
void dfs(int x, int fa, int bit){
    LL q = 0;
    LL b = (a[x] >> bit) & 1;
    dp[x][b] = 1;//init
    dp[x][b^1] = 0;
    for(int i=head[x]; ~i; i=E[i].next){
        int v = E[i].to;
        if(v == fa) continue;
        dfs(v, x, bit);
        q += dp[x][0] * dp[v][1] + dp[x][1] * dp[v][0];//统计子节点到x的路径上异或和，只需算1^0与0^1即可
        dp[x][b^0] += dp[v][0];//更新异或操作后的状态值。
        dp[x][b^1] += dp[v][1];
    }
    ans +=  (q << bit);
}
int main(){
    int n;
    init();
    scanf("%d", &n);
    for(int i=1; i<=n; i++) scanf("%lld", &a[i]), ans += a[i];
    for(int i=1; i<n; i++){
        int u, v;
        scanf("%d %d", &u,&v);
        add(u, v);
        add(v, u);
    }
    for(int i=0; i<=20; i++) dfs(1, -1, i);
    printf("%lld\n", ans);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e5+10;
LL dp[maxn][2], a[maxn];
LL ans = 0;
int head[maxn], edgecnt;
struct edge{
    int to,next;
}E[maxn*2];
void init(){
    memset(head,-1,sizeof(head));
    edgecnt=0;
}
void add(int u,int v){
    E[edgecnt].to=v,E[edgecnt].next=head[u],head[u]=edgecnt++;
}
void dfs(int x, int fa, int bit){
    LL q = 0;
    int b = (a[x] >> bit) & 1;
    dp[x][b] = 1;//init
    dp[x][b^1] = 0;
    for(int i=head[x]; ~i; i=E[i].next){
        int v = E[i].to;
        if(v == fa) continue;
        dfs(v, x, bit);
        q += dp[x][0] * dp[v][1] + dp[x][1] * dp[v][0];//统计子节点到x的路径上异或和，只需算1^0与0^1即可
        dp[x][b^0] += dp[v][0];//更新异或操作后的状态值。
        dp[x][b^1] += dp[v][1];
    }
    ans +=  (q << bit);
}
int main(){
    int n;
    init();
    scanf("%d", &n);
    for(int i=1; i<=n; i++) scanf("%lld", &a[i]), ans += a[i];
    for(int i=1; i<n; i++){
        int u, v;
        scanf("%d %d", &u,&v);
        add(u, v);
    }
    for(int i=0; i<=20; i++) dfs(1, 0, i);
    printf("%lld\n", ans);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e5+10;
LL dp[maxn][2], a[maxn];
LL ans;
int head[maxn], edgecnt;
struct edge{
    int to,next;
}E[maxn*2];
void init(){
    memset(head,-1,sizeof(head));
    edgecnt=0;
}
void add(int u,int v){
    E[edgecnt].to=v,E[edgecnt].next=head[u],head[u]=edgecnt++;
}
void dfs(int x, int fa, int bit){
    LL q = 0;
    int b = (a[x] >> bit) & 1;
    dp[x][b] = 1;//init
    dp[x][b^1] = 0;
    for(int i=head[x]; ~i; i=E[i].next){
        int v = E[i].to;
        if(v == fa) continue;
        dfs(v, x, bit);
        q += dp[x][0] * dp[v][1] + dp[x][1] * dp[v][0];//统计子节点到x的路径上异或和，只需算1^0与0^1即可
        dp[x][b^0] += dp[v][0];//更新异或操作后的状态值。
        dp[x][b^1] += dp[v][1];
    }
    ans +=  (q << bit);
}
int main(){
    int n;
    init();
    scanf("%d", &n);
    for(int i=1; i<=n; i++) scanf("%lld", &a[i]), ans += a[i];
    for(int i=1; i<n; i++){
        int u, v;
        scanf("%d %d", &u,&v);
        add(u, v);
    }
    for(int i=0; i<=20; i++) dfs(1, 0, i);
    printf("%lld\n", ans);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e5+10;
LL dp[maxn][2], a[maxn];
LL ans = 0;
int head[maxn], edgecnt;
struct edge{
    int to,next;
}E[maxn*2];
void init(){
    memset(head,-1,sizeof(head));
    edgecnt=0;
}
void add(int u,int v){
    E[edgecnt].to=v,E[edgecnt].next=head[u],head[u]=edgecnt++;
}
void dfs(int x, int fa, int bit){
    LL q = 0;
    int b = (a[x] >> bit) & 1;
    dp[x][b] = 1;//init
    dp[x][b^1] = 0;
    for(int i=head[x]; ~i; i=E[i].next){
        int v = E[i].to;
        if(v == fa) continue;
        dfs(v, x, bit);
        q += dp[x][0] * dp[v][1] + dp[x][1] * dp[v][0];//统计子节点到x的路径上异或和，只需算1^0与0^1即可
        dp[x][b^0] += dp[v][0];//更新异或操作后的状态值。
        dp[x][b^1] += dp[v][1];
    }
    ans +=  (q << bit);
}
int main(){
    int n;
    init();
    scanf("%d", &n);
    for(int i=1; i<=n; i++) scanf("%lld", &a[i]), ans += a[i];
    for(int i=1; i<n; i++){
        int u, v;
        scanf("%d %d", &u,&v);
        add(u, v);
    }
    for(int i=0; i<=20; i++) dfs(1, -1, i);
    printf("%lld\n", ans);
    return 0;
}


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

#ifdef _LOCAL_
    #define cout cerr
#endif
#define ms(s, n) memset(s, n, sizeof(s))
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define FORd(i, a, b) for (int i = (a) - 1; i >= (b); i--)
#define FORall(it, a) for (__typeof((a).begin()) it = (a).begin(); it != (a).end(); it++)
#define FORalld(it, a) for (__typeof((a).rbegin()) it = (a).rbegin(); it != (a).rend(); it++)
#define sz(a) int((a).size())
#define present(t, x) (t.find(x) != t.end())
#define all(a) (a).begin(), (a).end()
#define uni(a) (a).erase(unique(all(a)), (a).end())
#define pb push_back
#define pf push_front
#define mp make_pair
#define fi first
#define se second
#define prec(n) fixed<<setprecision(n)
#define bit(n, i) (((n) >> (i)) & 1)
#define bitcount(n) __builtin_popcountll(n)
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pi;
typedef vector<int> vi;
typedef vector<pi> vii;
const int MOD = (int) 1e9 + 7;
const int INF = (int) 1e9;
const ll LINF = (ll) 1e18;
const ld PI = acos((ld) -1);
const ld EPS = 1e-9;
inline ll gcd(ll a, ll b) {ll r; while (b) {r = a % b; a = b; b = r;} return a;}
inline ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
inline ll fpow(ll n, ll k, int p = MOD) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n % p; n = n * n % p;} return r;}
template<class T> inline int chkmin(T& a, const T& val) {return val < a ? a = val, 1 : 0;}
template<class T> inline int chkmax(T& a, const T& val) {return a < val ? a = val, 1 : 0;}
template<class T> inline T isqrt(T k) {T r = sqrt(k) + 1; while (r * r > k) r--; return r;}
template<class T> inline T icbrt(T k) {T r = cbrt(k) + 1; while (r * r * r > k) r--; return r;}
inline void addmod(int& a, int val, int p = MOD) {if ((a = (a + val)) >= p) a -= p;}
inline void submod(int& a, int val, int p = MOD) {if ((a = (a - val)) < 0) a += p;}
inline int mult(int a, int b, int p = MOD) {return (ll) a * b % p;}
inline int inv(int a, int p = MOD) {return fpow(a, p - 2, p);}
inline int sign(ld x) {return x < -EPS ? -1 : x > +EPS;}
inline int sign(ld x, ld y) {return sign(x - y);}

struct CentroidTree {
    struct Info {
        int d;
        Info() : d(0) {}
        Info(int d) : d(d) {}
        Info(const Info& rhs) : d(rhs.d) {}
    };

    static const int maxn = 100000 + 10;
    static const int logn = 20;
    int n, rt;
    int a[maxn];
    vector<int> adj[maxn];
    int size[maxn];
    int del[maxn];
    vector<int> tree[maxn];
    int lev[maxn];
    int p[logn][maxn];
    Info info[logn][maxn];

    void init(int n) {
        this->n = n;
        for (int i = 0; i < n; i++) {
            adj[i].clear();
            tree[i].clear();
            del[i] = 0;
        }
    }
    void addedge(int u, int v) {
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    void dfs(int u, int p) {
        size[u] = 1;
        for (int i = 0; i < (int) adj[u].size(); i++) {
            int v = adj[u][i];
            if (v != p && !del[v]) {
                dfs(v, u);
                size[u] += size[v];
            }
        }
    }
    int findcentroid(int u) {
        dfs(u, -1);
        int p = -1, t = size[u];
        while (1) {
            pair<int, int> best;
            for (int i = 0; i < (int) adj[u].size(); i++) {
                int v = adj[u][i];
                if (v != p && !del[v]) {
                    best = max(best, make_pair(size[v], v));
                }
            }
            if (best.first + best.first <= t) {
                return u;
            }
            p = u, u = best.second;
        }
    }
    void upd(int u, int dep, int p) {
        for (int i = 0; i < (int) adj[u].size(); i++) {
            int v = adj[u][i];
            if (v != p && !del[v]) {
                info[dep][v].d = info[dep][u].d ^ a[v];
                upd(v, dep, u);
            }
        }
    }
    int divide(int u, int dep) {
        lev[u = findcentroid(u)] = dep;
        p[0][u] = u;
        info[dep][u] = Info(a[u]);
        upd(u, dep, -1);
        del[u] = 1;
        for (int i = 0; i < (int) adj[u].size(); i++) {
            int v = adj[u][i];
            if (!del[v]) {
                int w = divide(v, dep + 1);
                tree[u].push_back(w);
                p[0][w] = u;
            }
        }
        return u;
    }
    void build() {
        rt = divide(0, 0);

    }
    long long ans;
    int hs[2][20], tmp;
    void add(int u, int ix) {
        FOR(k, 0, 20) {
            hs[bit(info[ix][u].d, k)][k]++;
        }
        for (int i = 0; i < (int) tree[u].size(); i++) {
            int v = tree[u][i];
            add(v, ix);
        }
    }
    void rem(int u, int ix) {
        FOR(k, 0, 20) {
            hs[bit(info[ix][u].d, k)][k]--;
        }
        for (int i = 0; i < (int) tree[u].size(); i++) {
            int v = tree[u][i];
            rem(v, ix);
        }
    }
    void query(int u, int ix) {
        FOR(k, 0, 20) {
            if (bit(info[ix][u].d, k)) ans += 1 << k + 1;
            int x = bit((info[ix][u].d ^ tmp), k);
            ans += (long long) hs[1 - x][k] * (1 << k);
        }
        for (int i = 0; i < (int) tree[u].size(); i++) {
            int v = tree[u][i];
            query(v, ix);
        }
    }
    void work(int u) {
        ms(hs, 0), tmp = a[u];
        FOR(k, 0, 20) {
            ans += bit(a[u], k) * (1 << k + 1);
        }
        int ix = lev[u];
        for (int i = 0; i < (int) tree[u].size(); i++) {
            int v = tree[u][i];
            add(v, ix);
        }
        for (int i = 0; i < (int) tree[u].size(); i++) {
            int v = tree[u][i];
            rem(v, ix);
            query(v, ix);
            add(v, ix);
        }
        for (int i = 0; i < (int) tree[u].size(); i++) {
            int v = tree[u][i];
            work(v);
        }
    }
} ct;

void solve() {
    cin >> ct.n;
    ct.init(ct.n);
    FOR(i, 0, n) cin >> ct.a[i];
    FOR(i, 0, n - 1) {
        int u, v; cin >> u >> v; u--, v--;
        ct.addedge(u, v);
    }
    ct.build();
    ct.work(ct.rt);
    cout << ct.ans / 2 << "\n";
}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0);
#ifdef _LOCAL_
    freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout);
#endif
    solve();
#ifdef _LOCAL_
    printf("\nTime elapsed: %dms\n", 1000 * clock() / CLOCKS_PER_SEC);
#endif
    return 0;
}


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

#ifdef _LOCAL_
    #define cout cerr
#endif
#define ms(s, n) memset(s, n, sizeof(s))
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define FORd(i, a, b) for (int i = (a) - 1; i >= (b); i--)
#define FORall(it, a) for (__typeof((a).begin()) it = (a).begin(); it != (a).end(); it++)
#define FORalld(it, a) for (__typeof((a).rbegin()) it = (a).rbegin(); it != (a).rend(); it++)
#define sz(a) int((a).size())
#define present(t, x) (t.find(x) != t.end())
#define all(a) (a).begin(), (a).end()
#define uni(a) (a).erase(unique(all(a)), (a).end())
#define pb push_back
#define pf push_front
#define mp make_pair
#define fi first
#define se second
#define prec(n) fixed<<setprecision(n)
#define bit(n, i) (((n) >> (i)) & 1)
#define bitcount(n) __builtin_popcountll(n)
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pi;
typedef vector<int> vi;
typedef vector<pi> vii;
const int MOD = (int) 1e9 + 7;
const int INF = (int) 1e9;
const ll LINF = (ll) 1e18;
const ld PI = acos((ld) -1);
const ld EPS = 1e-9;
inline ll gcd(ll a, ll b) {ll r; while (b) {r = a % b; a = b; b = r;} return a;}
inline ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
inline ll fpow(ll n, ll k, int p = MOD) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n % p; n = n * n % p;} return r;}
template<class T> inline int chkmin(T& a, const T& val) {return val < a ? a = val, 1 : 0;}
template<class T> inline int chkmax(T& a, const T& val) {return a < val ? a = val, 1 : 0;}
template<class T> inline T isqrt(T k) {T r = sqrt(k) + 1; while (r * r > k) r--; return r;}
template<class T> inline T icbrt(T k) {T r = cbrt(k) + 1; while (r * r * r > k) r--; return r;}
inline void addmod(int& a, int val, int p = MOD) {if ((a = (a + val)) >= p) a -= p;}
inline void submod(int& a, int val, int p = MOD) {if ((a = (a - val)) < 0) a += p;}
inline int mult(int a, int b, int p = MOD) {return (ll) a * b % p;}
inline int inv(int a, int p = MOD) {return fpow(a, p - 2, p);}
inline int sign(ld x) {return x < -EPS ? -1 : x > +EPS;}
inline int sign(ld x, ld y) {return sign(x - y);}

struct CentroidTree {
    struct Info {
        int d;
        Info() : d(0) {}
        Info(int d) : d(d) {}
        Info(const Info& rhs) : d(rhs.d) {}
    };

    static const int maxn = 100000 + 10;
    static const int logn = 20;
    int n, rt;
    int a[maxn];
    vector<int> adj[maxn];
    int size[maxn];
    int del[maxn];
    vector<int> tree[maxn];
    int lev[maxn];
    int p[logn][maxn];
    Info info[logn][maxn];

    void init(int n) {
        this->n = n;
        for (int i = 0; i < n; i++) {
            adj[i].clear();
            tree[i].clear();
            del[i] = 0;
        }
    }
    void addedge(int u, int v) {
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    void dfs(int u, int p) {
        size[u] = 1;
        for (int i = 0; i < (int) adj[u].size(); i++) {
            int v = adj[u][i];
            if (v != p && !del[v]) {
                dfs(v, u);
                size[u] += size[v];
            }
        }
    }
    int findcentroid(int u) {
        dfs(u, -1);
        int p = -1, t = size[u];
        while (1) {
            pair<int, int> best;
            for (int i = 0; i < (int) adj[u].size(); i++) {
                int v = adj[u][i];
                if (v != p && !del[v]) {
                    best = max(best, make_pair(size[v], v));
                }
            }
            if (best.first + best.first <= t) {
                return u;
            }
            p = u, u = best.second;
        }
    }
    void upd(int u, int dep, int p) {
        for (int i = 0; i < (int) adj[u].size(); i++) {
            int v = adj[u][i];
            if (v != p && !del[v]) {
                info[dep][v].d = info[dep][u].d ^ a[v];
                upd(v, dep, u);
            }
        }
    }
    int divide(int u, int dep) {
        lev[u = findcentroid(u)] = dep;
        p[0][u] = u;
        info[dep][u] = Info(a[u]);
        upd(u, dep, -1);
        del[u] = 1;
        for (int i = 0; i < (int) adj[u].size(); i++) {
            int v = adj[u][i];
            if (!del[v]) {
                int w = divide(v, dep + 1);
                tree[u].push_back(w);
                p[0][w] = u;
            }
        }
        return u;
    }
    void build() {
        rt = divide(0, 0);

    }
    long long ans;
    int hs[2][20], tmp;
    void add(int u, int ix) {
        FOR(k, 0, 20) {
            hs[bit(info[ix][u].d, k)][k]++;
        }
        for (int i = 0; i < (int) tree[u].size(); i++) {
            int v = tree[u][i];
            add(v, ix);
        }
    }
    void rem(int u, int ix) {
        FOR(k, 0, 20) {
            hs[bit(info[ix][u].d, k)][k]--;
        }
        for (int i = 0; i < (int) tree[u].size(); i++) {
            int v = tree[u][i];
            rem(v, ix);
        }
    }
    void query(int u, int ix) {
        FOR(k, 0, 20) {
            if (bit(info[ix][u].d, k)) ans += 1 << k + 1;
            int x = bit((info[ix][u].d ^ tmp), k);
            ans += (long long) hs[1 - x][k] * (1 << k);
        }
        for (int i = 0; i < (int) tree[u].size(); i++) {
            int v = tree[u][i];
            query(v, ix);
        }
    }
    void work(int u) {
        ms(hs, 0), tmp = a[u];
        FOR(k, 0, 20) {
            ans += bit(a[u], k) * (1 << k + 1);
        }
        int ix = lev[u];
        for (int i = 0; i < (int) tree[u].size(); i++) {
            int v = tree[u][i];
            add(v, ix);
        }
        for (int i = 0; i < (int) tree[u].size(); i++) {
            int v = tree[u][i];
            rem(v, ix);
            query(v, ix);
            add(v, ix);
        }
        for (int i = 0; i < (int) tree[u].size(); i++) {
            int v = tree[u][i];
            work(v);
        }
    }
} ct;

int n;

void solve() {
    cin >> n;
    ct.init(n);
    FOR(i, 0, n) cin >> ct.a[i];
    FOR(i, 0, n - 1) {
        int u, v; cin >> u >> v; u--, v--;
        ct.addedge(u, v);
    }
    ct.build();
    ct.work(ct.rt);
    cout << ct.ans / 2 << "\n";
}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0);
#ifdef _LOCAL_
    freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout);
#endif
    solve();
#ifdef _LOCAL_
    printf("\nTime elapsed: %dms\n", 1000 * clock() / CLOCKS_PER_SEC);
#endif
    return 0;
}


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

#ifdef _LOCAL_
    #define cout cerr
#endif
#define ms(s, n) memset(s, n, sizeof(s))
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define FORd(i, a, b) for (int i = (a) - 1; i >= (b); i--)
#define FORall(it, a) for (__typeof((a).begin()) it = (a).begin(); it != (a).end(); it++)
#define FORalld(it, a) for (__typeof((a).rbegin()) it = (a).rbegin(); it != (a).rend(); it++)
#define sz(a) int((a).size())
#define present(t, x) (t.find(x) != t.end())
#define all(a) (a).begin(), (a).end()
#define uni(a) (a).erase(unique(all(a)), (a).end())
#define pb push_back
#define pf push_front
#define mp make_pair
#define fi first
#define se second
#define prec(n) fixed<<setprecision(n)
#define bit(n, i) (((n) >> (i)) & 1)
#define bitcount(n) __builtin_popcountll(n)
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pi;
typedef vector<int> vi;
typedef vector<pi> vii;
const int MOD = (int) 1e9 + 7;
const int INF = (int) 1e9;
const ll LINF = (ll) 1e18;
const ld PI = acos((ld) -1);
const ld EPS = 1e-9;
inline ll gcd(ll a, ll b) {ll r; while (b) {r = a % b; a = b; b = r;} return a;}
inline ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
inline ll fpow(ll n, ll k, int p = MOD) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n % p; n = n * n % p;} return r;}
template<class T> inline int chkmin(T& a, const T& val) {return val < a ? a = val, 1 : 0;}
template<class T> inline int chkmax(T& a, const T& val) {return a < val ? a = val, 1 : 0;}
template<class T> inline T isqrt(T k) {T r = sqrt(k) + 1; while (r * r > k) r--; return r;}
template<class T> inline T icbrt(T k) {T r = cbrt(k) + 1; while (r * r * r > k) r--; return r;}
inline void addmod(int& a, int val, int p = MOD) {if ((a = (a + val)) >= p) a -= p;}
inline void submod(int& a, int val, int p = MOD) {if ((a = (a - val)) < 0) a += p;}
inline int mult(int a, int b, int p = MOD) {return (ll) a * b % p;}
inline int inv(int a, int p = MOD) {return fpow(a, p - 2, p);}
inline int sign(ld x) {return x < -EPS ? -1 : x > +EPS;}
inline int sign(ld x, ld y) {return sign(x - y);}

struct CentroidTree {
    struct Info {
        int d;
        Info() : d(0) {}
        Info(int d) : d(d) {}
        Info(const Info& rhs) : d(rhs.d) {}
        Info operator + (const int& w) const {
            return Info(d ^ w);
        }
        Info operator + (const Info& rhs) const {
            return Info(d ^ rhs.d);
        }
    };

    static const int maxn = 100000 + 10;
    static const int logn = 20;
    int n, rt;
    int a[maxn];
    vector<int> adj[maxn];
    int size[maxn];
    int del[maxn];
    vector<int> tree[maxn];
    int lev[maxn];
    int p[logn][maxn];
    Info info[logn][maxn];

    void init(int n) {
        this->n = n;
        for (int i = 0; i < n; i++) {
            adj[i].clear();
            tree[i].clear();
            del[i] = 0;
        }
    }
    void add(int u, int v) {
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    void dfs(int u, int p) {
        size[u] = 1;
        for (int i = 0; i < (int) adj[u].size(); i++) {
            int v = adj[u][i];
            if (v != p && !del[v]) {
                dfs(v, u);
                size[u] += size[v];
            }
        }
    }
    int findcentroid(int u) {
        dfs(u, -1);
        int p = -1, t = size[u];
        while (1) {
            pair<int, int> best;
            for (int i = 0; i < (int) adj[u].size(); i++) {
                int v = adj[u][i];
                if (v != p && !del[v]) {
                    best = max(best, make_pair(size[v], v));
                }
            }
            if (best.first + best.first <= t) {
                return u;
            }
            p = u, u = best.second;
        }
    }
    void upd(int u, int dep, int p) {
        for (int i = 0; i < (int) adj[u].size(); i++) {
            int v = adj[u][i];
            if (v != p && !del[v]) {
                info[dep][v].d = info[dep][u].d ^ a[v];
                upd(v, dep, u);
            }
        }
    }
    int divide(int u, int dep) {
        lev[u = findcentroid(u)] = dep;
        p[0][u] = u;
        info[dep][u] = Info(a[u]);
        upd(u, dep, -1);
        del[u] = 1;
        for (int i = 0; i < (int) adj[u].size(); i++) {
            int v = adj[u][i];
            if (!del[v]) {
                int w = divide(v, dep + 1);
                tree[u].push_back(w);
                p[0][w] = u;
            }
        }
        return u;
    }
    int lca(int u, int v) {
        if (lev[u] < lev[v]) swap(u, v);
        for (int k = logn - 1; k >= 0; k--) {
            if (lev[p[k][u]] >= lev[v]) {
                u = p[k][u];
            }
        }
        if (u == v) return u;
        for (int k = logn - 1; k >= 0; k--) {
            if (p[k][u] != p[k][v]) {
                u = p[k][u], v = p[k][v];
            }
        }
        return p[0][u];
    }
    Info getInfo(int u, int v) {
        int a = lca(u, v);
        int ix = lev[a];
        return info[ix][u] + info[ix][v];
    }
    void build() {
        rt = divide(0, 0);
        for (int k = 1; k < logn; k++) {
            for (int u = 0; u < n; u++) {
                p[k][u] = p[k - 1][p[k - 1][u]];
            }
        }

    }
    long long ans;
    int hs[2], tmp;
    void add(int u, int ix, int k) {
        hs[bit(info[ix][u].d, k)]++;
        for (int i = 0; i < (int) tree[u].size(); i++) {
            int v = tree[u][i];
            add(v, ix, k);
        }
    }
    void rem(int u, int ix, int k) {
        hs[bit(info[ix][u].d, k)]--;
        for (int i = 0; i < (int) tree[u].size(); i++) {
            int v = tree[u][i];
            rem(v, ix, k);
        }
    }
    void query(int u, int ix, int k) {
        if (bit(info[ix][u].d, k)) ans += 1 << k + 1;
        int x = bit((info[ix][u].d ^ tmp), k);
        ans += (long long) hs[1 - x] * (1 << k);
        for (int i = 0; i < (int) tree[u].size(); i++) {
            int v = tree[u][i];
            query(v, ix, k);
        }
    }
    void work(int u, int k) {
        fill_n(hs, 2, 0), tmp = a[u];
        ans += bit(a[u], k) * (1 << k + 1);
        int ix = lev[u];
        for (int i = 0; i < (int) tree[u].size(); i++) {
            int v = tree[u][i];
            add(v, ix, k);
        }
        for (int i = 0; i < (int) tree[u].size(); i++) {
            int v = tree[u][i];
            rem(v, ix, k);
            query(v, ix, k);
            add(v, ix, k);
        }
        for (int i = 0; i < (int) tree[u].size(); i++) {
            int v = tree[u][i];
            work(v, k);
        }
    }
} ct;

int n;

void solve() {
    cin >> n;
    ct.init(n);
    FOR(i, 0, n) cin >> ct.a[i];
    FOR(i, 0, n - 1) {
        int u, v; cin >> u >> v; u--, v--;
        ct.add(u, v);
    }
    ct.build();
    FOR(i, 0, 21) ct.work(ct.rt, i);
    cout << ct.ans / 2 << "\n";
}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0);
#ifdef _LOCAL_
    freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout);
#endif
    solve();
#ifdef _LOCAL_
    printf("\nTime elapsed: %dms\n", 1000 * clock() / CLOCKS_PER_SEC);
#endif
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MX = 1e6+69;
typedef long double ld;
const int inf = 1e9+5;
const long long mod = 1e9+7;
const long double eps = 1e-10;

int n;
vector <int> v[MX],adj[MX];
int sz[MX],a[MX];
bool vis[MX];
ll ans;
int on[31],off[31];
int f( int x , int p )
{
    sz[x] = 1;
    for ( int i=0 ; i<v[x].size() ; i++ )
    {
        int nxt = v[x][i];
        if ( nxt==p || vis[nxt] ) { continue; }
        sz[x] += f( nxt , x );
    }
    return sz[x];
}

int cent( int x , int p , int c )
{
    for ( int i=0 ; i<v[x].size() ; i++ )
    {
        int nxt = v[x][i];
        if ( nxt==p || vis[nxt] ) { continue; }
        if ( sz[nxt]>c/2 ) { return cent( nxt , x , c ); }
    }
    return x;
}

void dfs( int x , int p , int fl , int cur , int c )
{
    if ( fl )
    {
        for ( int i=0 ; i<20 ; i++ )
        {
            ll x=0;
            if ( (( a[c]&(1<<i) )&&( cur&(1<<i) )) || ( !( a[c]&(1<<i) )&& !( cur&(1<<i) ) ) ) { x = on[i]; } else { x=off[i]; }
            ans += (1ll<<i)*x;
        }
    }
    else
    {
        for ( int i=0 ; i<20 ; i++ )
        {
            if ( cur&(1<<i) ) { on[i]++; } else { off[i]++; }
        }
        ans += cur^a[c];
    }
    for ( int i=0 ; i<v[x].size() ; i++ )
    {
        int nxt = v[x][i];
        if ( nxt==p || vis[nxt] ) { continue; }
        dfs( nxt , x , fl , cur^a[nxt] , c );
    }
}

void solve( int x )
{
    vis[x]=1;
    memset ( on , 0 , sizeof on );
    memset ( off , 0 , sizeof off );

    for ( int i=0 ; i<v[x].size() ; i++ )
    {
        int nxt = v[x][i];
        if ( !vis[nxt] )
        {
            dfs( nxt , x , 1 , a[nxt] , x );
            dfs( nxt , x , 0 , a[nxt] , x );
        }
    }
    for ( int i=0 ; i<v[x].size() ; i++ )
    {
        int nxt = v[x][i];
        f( nxt , -1 );
        int c = cent( nxt , -1 , sz[nxt] );
        if ( !vis[nxt] )
        {
            solve( c );
        }
    }
}

int main()
{
    cin>>n;
    for ( int i=1 ; i<=n ; i++ ) { scanf ( "%d" , &a[i] ); ans+=a[i]; }

    for ( int i=1 ; i<n ; i++ )
    {
        int a,b;
        scanf ( "%d%d" , &a , &b );
        v[a].push_back( b );
        v[b].push_back( a );
    }
    f( 1 , -1 );
    int cen = cent( 1 , -1 , sz[1] );
    solve( cen );

    cout<<ans;

    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MX = 4e5+69;
typedef long double ld;
const int inf = 1e9+5;
const long long mod = 1e9+7;
const long double eps = 1e-10;

int n;
vector <int> v[MX];
int sz[MX],a[MX];
bool vis[MX];
ll ans;
int on[22],off[22];
int f( int x , int p )
{
    sz[x] = 1;
    for ( int i=0 ; i<v[x].size() ; i++ )
    {
        int nxt = v[x][i];
        if ( nxt==p || vis[nxt] ) { continue; }
        sz[x] += f( nxt , x );
    }
    return sz[x];
}

int cent( int x , int p , int c )
{
    for ( int i=0 ; i<v[x].size() ; i++ )
    {
        int nxt = v[x][i];
        if ( nxt==p || vis[nxt] ) { continue; }
        if ( sz[nxt]>c/2 ) { return cent( nxt , x , c ); }
    }
    return x;
}

void dfs( int x , int p , int fl , int cur , int c )
{
    if ( fl )
    {
        for ( int i=0 ; i<21 ; i++ )
        {
            ll x=0;
            if ( (( a[c]&(1<<i) )&&( cur&(1<<i) )) || ( !( a[c]&(1<<i) )&& !( cur&(1<<i) ) ) ) { x = on[i]; } else { x=off[i]; }
            ans += (1ll<<i)*x;
        }
    }
    else
    {
        for ( int i=0 ; i<21 ; i++ )
        {
            if ( cur&(1<<i) ) { on[i]++; } else { off[i]++; }
        }
        ans += cur^a[c];
    }
    for ( int i=0 ; i<v[x].size() ; i++ )
    {
        int nxt = v[x][i];
        if ( nxt==p || vis[nxt] ) { continue; }
        dfs( nxt , x , fl , cur^a[nxt] , c );
    }
}

void solve( int x )
{
    vis[x]=1;
    memset ( on , 0 , sizeof on );
    memset ( off , 0 , sizeof off );

    for ( int i=0 ; i<v[x].size() ; i++ )
    {
        int nxt = v[x][i];
        if ( !vis[nxt] )
        {
            dfs( nxt , x , 1 , a[nxt] , x );
            dfs( nxt , x , 0 , a[nxt] , x );
        }
    }
    for ( int i=0 ; i<v[x].size() ; i++ )
    {
        int nxt = v[x][i];
        if ( !vis[nxt] )
        {
            f( nxt , -1 );
            int c = cent( nxt , -1 , sz[nxt] );
            solve( c );
        }
    }
}

int main()
{
    cin>>n;
    for ( int i=1 ; i<=n ; i++ ) { scanf ( "%d" , &a[i] ); ans+=a[i]; }

    for ( int i=1 ; i<n ; i++ )
    {
        int a,b;
        scanf ( "%d%d" , &a , &b );
        v[a].push_back( b );
        v[b].push_back( a );
    }
    f( 1 , -1 );
    int cen = cent( 1 , -1 , sz[1] );
    solve( cen );

    cout<<ans;

    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MX = 4e5+69;
typedef long double ld;
const int inf = 1e9+5;
const long long mod = 1e9+7;
const long double eps = 1e-10;

int n;
vector <int> v[MX];
int sz[MX],a[MX];
bool vis[MX];
ll ans;
ll dp[3][MX][25];

void dfs( int x , int p )
{
    for ( int i=0 ; i<22 ; i++ ) { dp[ (a[x]&(1<<i))?1:0 ][x][i]++; }

    for ( int i=0 ; i<v[x].size() ; i++ )
    {
        int nxt = v[x][i];
        if ( nxt==p ) { continue; }
        dfs( nxt , x );
        for ( int i=0 ; i<22 ; i++ )
        {
            ans += (1ll<<i)*( dp[1][x][i]*dp[0][nxt][i] + dp[0][x][i]*dp[1][nxt][i] );
        }
        //cout<<ans<<endl;
        for ( int i=0 ; i<22 ; i++ )
        {
            if ( ( (a[x]&(1<<i)) ) ) { dp[1][x][i] += dp[0][nxt][i]; dp[0][x][i] += dp[1][nxt][i]; }
            else { dp[1][x][i] += dp[1][nxt][i]; dp[0][x][i] += dp[0][nxt][i]; }
            //cout<<dp[1][x][i]<<" "<<dp[0][x][i]<<endl;
        }
    }
}

int main()
{
    cin>>n;
    for ( int i=1 ; i<=n ; i++ ) { scanf ( "%d" , &a[i] ); ans+=a[i]; }

    for ( int i=1 ; i<n ; i++ )
    {
        int a,b;
        scanf ( "%d%d" , &a , &b );
        v[a].push_back( b );
        v[b].push_back( a );
    }
    dfs( 1 , -1 );
    cout<<ans;

    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MX = 1e5+69;
typedef long double ld;
const int inf = 1e9+5;
const long long mod = 1e9+7;
const long double eps = 1e-10;

int n;
vector <int> v[MX],adj[MX];
int sz[MX],a[MX];
bool vis[MX];
ll ans;
int on[21],off[21];
int f( int x , int p )
{
    sz[x] = 1;
    for ( int i=0 ; i<v[x].size() ; i++ )
    {
        int nxt = v[x][i];
        if ( nxt==p || vis[nxt] ) { continue; }
        sz[x] += f( nxt , x );
    }
    return sz[x];
}

int cent( int x , int p , int c )
{
    for ( int i=0 ; i<v[x].size() ; i++ )
    {
        int nxt = v[x][i];
        if ( nxt==p || vis[nxt] ) { continue; }
        if ( sz[nxt]>c/2 ) { return cent( nxt , x , c ); }
    }
    return x;
}

void dfs( int x , int p , int fl , int cur , int c )
{
    if ( fl )
    {
        for ( int i=0 ; i<20 ; i++ )
        {
            ll x=0;
            if ( (( a[c]&(1<<i) )&&( cur&(1<<i) )) || ( !( a[c]&(1<<i) )&& !( cur&(1<<i) ) ) ) { x = on[i]; } else { x=off[i]; }
            ans += (1ll<<i)*x;
        }
    }
    else
    {
        for ( int i=0 ; i<20 ; i++ )
        {
            if ( cur&(1<<i) ) { on[i]++; } else { off[i]++; }
        }
        ans += cur^a[c];
    }
    for ( int i=0 ; i<v[x].size() ; i++ )
    {
        int nxt = v[x][i];
        if ( nxt==p || vis[nxt] ) { continue; }
        dfs( nxt , x , fl , cur^a[nxt] , c );
    }
}

void solve( int x )
{
    vis[x]=1;
    memset ( on , 0 , sizeof on );
    memset ( off , 0 , sizeof off );

    for ( int i=0 ; i<v[x].size() ; i++ )
    {
        int nxt = v[x][i];
        if ( !vis[nxt] )
        {
            dfs( nxt , x , 1 , a[nxt] , x );
            dfs( nxt , x , 0 , a[nxt] , x );
        }
    }
    for ( int i=0 ; i<v[x].size() ; i++ )
    {
        int nxt = v[x][i];
        f( nxt , -1 );
        int c = cent( nxt , -1 , sz[nxt] );
        if ( !vis[nxt] )
        {
            solve( c );
        }
    }
}

int main()
{
    cin>>n;
    for ( int i=1 ; i<=n ; i++ ) { scanf ( "%d" , &a[i] ); ans+=a[i]; }

    for ( int i=1 ; i<n ; i++ )
    {
        int a,b;
        scanf ( "%d%d" , &a , &b );
        v[a].push_back( b );
        v[b].push_back( a );
    }
    f( 1 , -1 );
    int cen = cent( 1 , -1 , sz[1] );
    solve( cen );

    cout<<ans;

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define N 101010
#define M 25

typedef long long int ll;

ll n, sz[N], block[N], peso[N], qtd[M];
ll answer;
vector<int> adj[N];

void build_sz(ll u, ll p){
	sz[u] = 1;
	for(ll v : adj[u]){
		if(v == p || block[v]) continue;
		build_sz(v, u);
		sz[u]+=sz[v];
	}
}

ll find_centroid(ll u, ll p, ll tam){
	for(ll v : adj[u]){
		if(v == p || block[v]) continue;
		if(sz[v]*2 > tam) return find_centroid(v, u, tam);
	}
	return u;
}

void dfs(ll u, ll p, ll sum, ll add){
	sum^=peso[u];
	for(ll i=0; i<M; i++){
		if(sum&(1<<i)) {
			qtd[i]+=add;
		}
	}

	for(ll v : adj[u]){
		if(v == p || block[v]) continue;
		dfs(v, u, sum, add);
	}
}

void solve(ll u, ll p, ll quant, ll sum, ll cent){

	sum^=peso[u];
	for(ll i=0; i<M; i++){
		if(!(sum&(1<<i))) {
			answer+= qtd[i]*(1<<i);
			if(peso[cent]&(1<<i)) answer+=(1<<i);
		}else {
			answer+= (ll)(quant - qtd[i])*(1LL<<i);
			if(!(peso[cent]&(1<<i))) answer+=(1<<i);
		}
	}

	for(ll v : adj[u]){
		if(v == p || block[v]) continue;
		solve(v, u, quant, sum, cent);
	}
}

void decompose(ll u){
	build_sz(u, u);
	u = find_centroid(u, u, sz[u]);
	build_sz(u, u);
	block[u] = 1;
	//~ dfs(u, u, 0, 1);
	int t=0;
	memset(qtd, 0, sizeof qtd);
	for(ll v : adj[u]){
		if(block[v]) continue;
		//~ dfs(v, u, peso[u], -1);
		solve(v, u, t, 0, u);
		t+=sz[v];
		dfs(v, u, peso[u], 1);
	}
	//~ dfs(u, u, 0, -1);
	for(ll v : adj[u]){
		if(block[v]) continue;
		decompose(v);
	}
}

int main(){
	ll a, b;
	scanf("%lld", &n);
	answer=0;
	for(ll i=1; i<=n; i++){
		scanf("%lld", &peso[i]);
		answer+=peso[i];
	}
	for(ll i=1; i<n; i++){
		scanf("%lld %lld", &a, &b);
		adj[a].push_back(b);
		adj[b].push_back(a);
	}
	decompose(1);

	printf("%lld\n", answer);
}


#include <bits/stdc++.h>

using namespace std;

#define N 101010
#define M 25

typedef long long int ll;

int n, sz[N], block[N], peso[N], qtd[M];
ll answer;
vector<int> adj[N];

void build_sz(int u, int p){
	sz[u] = 1;
	for(int v : adj[u]){
		if(v == p || block[v]) continue;
		build_sz(v, u);
		sz[u]+=sz[v];
	}
}

int find_centroid(int u, int p, int tam){
	for(int v : adj[u]){
		if(v == p || block[v]) continue;
		if(sz[v]*2 > tam) return find_centroid(v, u, tam);
	}
	return u;
}

void dfs(int u, int p, int sum, int add){
	sum^=peso[u];
	for(int i=0; i<M; i++){
		if(sum&(1<<i)) {
			qtd[i]+=add;
		}
	}

	for(int v : adj[u]){
		if(v == p || block[v]) continue;
		dfs(v, u, sum, add);
	}
}

void solve(int u, int p, int quant, int sum, int cent){

	sum^=peso[u];
	for(int i=0; i<M; i++){
		if(!(sum&(1<<i))) {
			answer+= qtd[i]*(1<<i);
			if(peso[cent]&(1<<i)) answer+=(1<<i);
		}else {
			answer+= (ll)(quant - qtd[i])*(1LL<<i);
			if(!(peso[cent]&(1<<i))) answer+=(1<<i);
		}
	}

	for(int v : adj[u]){
		if(v == p || block[v]) continue;
		solve(v, u, quant, sum, cent);
	}
}

void decompose(int u){
	build_sz(u, u);
	u = find_centroid(u, u, sz[u]);
	build_sz(u, u);
	block[u] = 1;
	dfs(u, u, 0, 1);

	for(int v : adj[u]){
		if(block[v]) continue;
		dfs(v, u, peso[u], -1);
		solve(v, u, sz[u]-sz[v], 0, u);
		dfs(v, u, peso[u], 1);
	}
	dfs(u, u, 0, -1);
	for(int v : adj[u]){
		if(block[v]) continue;
		decompose(v);
	}
}

int main(){
	int a, b;
	scanf("%d", &n);
	answer=0;
	for(int i=1; i<=n; i++){
		scanf("%d", &peso[i]);
		answer+=peso[i]*2;
	}
	for(int i=1; i<n; i++){
		scanf("%d %d", &a, &b);
		adj[a].push_back(b);
		adj[b].push_back(a);
	}
	decompose(1);

	printf("%lld\n", answer/2);
}


#include <bits/stdc++.h>

using namespace std;

#define N 101010
#define M 25

typedef long long int ll;

ll n, sz[N], block[N], peso[N], qtd[M];
ll answer;
vector<int> adj[N];

void build_sz(ll u, ll p){
	sz[u] = 1;
	for(ll v : adj[u]){
		if(v == p || block[v]) continue;
		build_sz(v, u);
		sz[u]+=sz[v];
	}
}

ll find_centroid(ll u, ll p, ll tam){
	for(ll v : adj[u]){
		if(v == p || block[v]) continue;
		if(sz[v]*2 > tam) return find_centroid(v, u, tam);
	}
	return u;
}

void dfs(ll u, ll p, ll sum, ll add){
	sum^=peso[u];
	for(ll i=0; i<M; i++){
		if(sum&(1<<i)) {
			qtd[i]+=add;
		}
	}

	for(ll v : adj[u]){
		if(v == p || block[v]) continue;
		dfs(v, u, sum, add);
	}
}

void solve(ll u, ll p, ll quant, ll sum, ll cent){

	sum^=peso[u];
	for(ll i=0; i<M; i++){
		if(!(sum&(1<<i))) {
			answer+= qtd[i]*(1<<i);
			if(peso[cent]&(1<<i)) answer+=(1<<i);
		}else {
			answer+= (ll)(quant - qtd[i])*(1LL<<i);
			if(!(peso[cent]&(1<<i))) answer+=(1<<i);
		}
	}

	for(ll v : adj[u]){
		if(v == p || block[v]) continue;
		solve(v, u, quant, sum, cent);
	}
}

void decompose(ll u){
	build_sz(u, u);
	u = find_centroid(u, u, sz[u]);
	build_sz(u, u);
	block[u] = 1;
	dfs(u, u, 0, 1);

	for(ll v : adj[u]){
		if(block[v]) continue;
		dfs(v, u, peso[u], -1);
		solve(v, u, sz[u]-sz[v], 0, u);
		dfs(v, u, peso[u], 1);
	}
	dfs(u, u, 0, -1);
	for(ll v : adj[u]){
		if(block[v]) continue;
		decompose(v);
	}
}

int main(){
	ll a, b;
	scanf("%lld", &n);
	answer=0;
	for(ll i=1; i<=n; i++){
		scanf("%lld", &peso[i]);
		answer+=peso[i]*2;
	}
	for(ll i=1; i<n; i++){
		scanf("%lld %lld", &a, &b);
		adj[a].push_back(b);
		adj[b].push_back(a);
	}
	decompose(1);

	printf("%lld\n", answer/2);
}


#include <bits/stdc++.h>

using namespace std;

//#define int long long

int n, m;
int a[100010];
vector<int> g[100010];
char used_centroid[100010];
int sz[100010];
int cnt = 0;
long long an = 0;
int c1[100010];
int c[2][20];

void dfs(int v, int par, int sum, int centroid){
    an += sum;
    if(v != centroid){
        c1[v] = sum;
        int t = sum ^ a[centroid];
        for(int i = 0; i < 20; i++){
            if(t & (1 << i)) c[1][i]++;
            else c[0][i]++;
        }
    }
    for(auto to: g[v]){
        if(to != par && !used_centroid[to]){
            dfs(to, v, sum ^ a[to], centroid);
        }
    }
}

void upd(int v, int par, int val, int sum){
    for(int i = 0; i < 20; i++){
        if(sum & (1 << i)) c[1][i] += val;
        else c[0][i] += val;
    }
    for(auto to: g[v]){
        if(to != par && !used_centroid[to]){
            upd(to, v, val, sum ^ a[to]);
        }
    }
}

void add(int v, int par){
    for(int i = 0; i < 20; i++){
        if((1 << i) & c1[v]) an += 1ll * c[0][i] * (1 << i);
        else an += 1ll * c[1][i] * (1 << i);
    }
    for(auto to: g[v]){
        if(to != par && !used_centroid[to]){
            add(to, v);
        }
    }
}

void solve(int v){
    memset(c, 0, sizeof(c));
    dfs(v, -1, a[v], v);
    for(auto to: g[v]){
        if(!used_centroid[to]){
            upd(to, -1, -1, a[to]);
            add(to, -1);
        }
    }
}

void calc_sz(int v, int par){
    sz[v] = 1;
    cnt++;
    for(auto to: g[v]){
        if(to != par && !used_centroid[to]){
            calc_sz(to, v);
            sz[v] += sz[to];
        }
    }
}

int getCentroid(int v){
    cnt = 0;
    calc_sz(v, -1);
    int u = -1;
    bool srcCentroid = true;
    for(auto to: g[v]){
        if(!used_centroid[to]){
            if(sz[to] > cnt / 2){
                srcCentroid = false;
            }
            if(u == -1 || sz[to] > sz[u]){
                u = to;
            }
        }
    }
    if(srcCentroid) return v;
    return getCentroid(u);
}

void centroid_decomp(int v){
    int centroid = getCentroid(v);
    used_centroid[centroid] = true;
    solve(centroid);
    for(auto to: g[centroid]){
        if(!used_centroid[to]){
            centroid_decomp(to);
        }
    }
}

main()
{
    ios_base::sync_with_stdio(0);
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    cin >> n;
    for(int i = 0; i < n; i++) cin >> a[i];
    for(int i = 0; i < n - 1; i++){
        int from, to;
        cin >> from >> to;
        g[from - 1].push_back(to - 1);
        g[to - 1].push_back(from - 1);
    }
    centroid_decomp(0);
    cout << an << endl;
}


#include <bits/stdc++.h>

using namespace std;

//#define int long long

int n, m;
int a[100010];
vector<int> g[100010];
char used_centroid[100010];
int sz[100010];
int cnt = 0;
long long an = 0;
int c1[100010];
int c[20][2];

void dfs(int v, int par, int sum, int centroid){
    an += sum;
    if(v != centroid){
        c1[v] = sum;
        int t = sum ^ a[centroid];
        for(int i = 0; i < 20; i++){
            if(t & (1 << i)) c[i][1]++;
            else c[i][0]++;
        }
    }
    for(auto to: g[v]){
        if(to != par && !used_centroid[to]){
            dfs(to, v, sum ^ a[to], centroid);
        }
    }
}

void upd(int v, int par, int val, int sum){
    for(int i = 0; i < 20; i++){
        if(sum & (1 << i)) c[i][1] += val;
        else c[i][0] += val;
    }
    for(auto to: g[v]){
        if(to != par && !used_centroid[to]){
            upd(to, v, val, sum ^ a[to]);
        }
    }
}

void add(int v, int par){
    for(int i = 0; i < 20; i++){
        if((1 << i) & c1[v]) an += 1ll * c[i][0] * (1 << i);
        else an += 1ll * c[i][1] * (1 << i);
    }
    for(auto to: g[v]){
        if(to != par && !used_centroid[to]){
            add(to, v);
        }
    }
}

void solve(int v){
    memset(c, 0, sizeof(c));
    dfs(v, -1, a[v], v);
    for(auto to: g[v]){
        if(!used_centroid[to]){
            upd(to, -1, -1, a[to]);
            add(to, -1);
        }
    }
}

void calc_sz(int v, int par){
    sz[v] = 1;
    cnt++;
    for(auto to: g[v]){
        if(to != par && !used_centroid[to]){
            calc_sz(to, v);
            sz[v] += sz[to];
        }
    }
}

int getCentroid(int v, int par){
    int u = -1;
    bool ok = true;
    for(auto to: g[v]){
        if(!used_centroid[to] && to != par){
            if(sz[to] > cnt / 2){
                ok = false;
            }
            if(u == -1 || sz[to] > sz[u]){
                u = to;
            }
        }
    }
    if(ok) return v;
    return getCentroid(u, v);
}

int getCentroid(int v){
    cnt = 0;
    calc_sz(v, -1);
    return getCentroid(v, -1);
}

void centroid_decomp(int v){
    int centroid = getCentroid(v);
    used_centroid[centroid] = true;
    solve(centroid);
    for(auto to: g[centroid]){
        if(!used_centroid[to]){
            centroid_decomp(to);
        }
    }
}

main()
{
    ios_base::sync_with_stdio(0);
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    cin >> n;
    for(int i = 0; i < n; i++) cin >> a[i];
    for(int i = 0; i < n - 1; i++){
        int from, to;
        cin >> from >> to;
        g[from - 1].push_back(to - 1);
        g[to - 1].push_back(from - 1);
    }
    centroid_decomp(0);
    cout << an << endl;
}