#include using namespace std; const int N = 3e5 + 7; int n; int cnt[30]; long long int res; int val[N]; int pod[N]; bool block[N]; vector G[N]; inline void add(int a){ for(int i = 0; i < 20; ++i) cnt[i] += (a & (1 << i)) > 0; } int dfs(int u, int p){ pod[u] = 1; for(int v: G[u]) if(!block[v] && v != p) pod[u] += dfs(v, u); return pod[u]; } int centroid(int u){ dfs(u, u); int half = (pod[u] + 1) / 2, p = u; bool ok = true; while(ok){ ok = false; for(int v: G[u]) if(!block[v] && v != p && pod[v] >= half){ p = u; u = v; ok = true; break; } } return u; } void get(int u, int p, int mask){ mask &= val[u]; for(int i = 0; i < 20; ++i) if(mask & (1 << i)) res += 1LL * (1 << i) * cnt[i]; for(int v: G[u]) if(!block[v] && v != p) get(v, u, mask); } void dodaj(int u, int p, int mask){ mask &= val[u]; add(mask); for(int v: G[u]) if(!block[v] && v != p) dodaj(v, u, mask); } void Rozbicie(int u){ for(int i = 0; i < 20; ++i) cnt[i] = 0; u = centroid(u); add(val[u]); res += val[u]; block[u] = true; for(int v: G[u]){ if(block[v]) continue; get(v, u, (1 << 20) - 1); dodaj(v, u, val[u]); } for(int v: G[u]) if(!block[v]) Rozbicie(v); } int main(){ scanf("%d", &n); for(int i = 0; i < n; ++i) scanf("%d", &val[i]); for(int i = 1; i < n; ++i){ int u, v; scanf("%d %d", &u, &v); G[u].push_back(v); G[v].push_back(u); } Rozbicie(0); printf("%lld\n", res); return 0; }