#include <bits/stdc++.h>
using namespace std;
template <typename T>
bool chmax(T& a, const T& b) {
  return a < b ? (a = b, true) : false;
}
template <typename T>
bool chmin(T& a, const T& b) {
  return b < a ? (a = b, true) : false;
}
int N;
vector<int> A;
list<int> edges[100001];
long long dp[100001][2];
long long dfs(int curr, int prev, int k) {
  vector<long long> v[2];
  long long acc[2] = {};
  long long res = 0;
  for (const auto& it : edges[curr])
    if (it != prev) {
      res += dfs(it, curr, k);
      for (int i = (int)(0); i < (int)(2); i++) {
        v[i].push_back(dp[it][i]);
        acc[i] += dp[it][i];
      }
    }
  long long x = 0;
  for (int i = (int)(0); i < (int)(v[0].size()); i++) {
    for (int j = (int)(0); j < (int)(2); j++) {
      if (j ^ (A[curr] >> k & 1)) {
        x += (v[j][i] * (acc[0] - v[0][i])) << k;
      } else {
        x += (v[j][i] * (acc[1] - v[1][i])) << k;
      }
    }
  }
  res += x / 2;
  if (A[curr] >> k & 1) {
    dp[curr][0] += acc[1];
    dp[curr][1] += acc[0];
    dp[curr][1]++;
  } else {
    dp[curr][0] += acc[0];
    dp[curr][1] += acc[1];
    dp[curr][0]++;
  }
  return res;
}
int main() {
  scanf("%d", &N);
  A.assign(N + 1, 0);
  for (int i = (int)(1); i < (int)(N + 1); i++) {
    scanf("%d", &A[i]);
  }
  for (int i = (int)(0); i < (int)(N - 1); i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    edges[u].push_back(v);
    edges[v].push_back(u);
  }
  long long ans = 0;
  for (int i = (int)(0); i < (int)(20); i++) {
    memset(dp, 0, sizeof(dp));
    ans += dfs(1, -1, i);
    for (int j = (int)(1); j < (int)(N + 1); j++) {
      ans += dp[j][1] << i;
    }
  }
  printf("%lld\n", ans);
  return 0;
}
