#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:66777216")
using namespace std;
const char SPACE = ' ', ENDL = '\n';
const int BASE = 1000 * 1000 * 1000 + 7;
const int MODULO = BASE;
template <class T>
T read() {
  T value;
  cin >> value;
  return value;
}
int read_int() { return read<int>(); }
size_t read_size() { return read<size_t>(); }
long long read_ll() { return read<long long>(); }
pair<int, int> read_ii() {
  int x = read_int();
  int y = read_int();
  return pair<int, int>(x, y);
}
string read_string() { return read<string>(); }
template <class T>
void read_vector(vector<T>& a, size_t size) {
  a.resize(size);
  for (T& value : a) cin >> value;
}
template <class T1, class T2>
void read_pairs(vector<pair<T1, T2>>& a, size_t size) {
  a.resize(size);
  for (auto& value : a) cin >> value.first >> value.second;
}
void read_graph(int n, int edges, vector<vector<int>>& graph,
                bool oriented = false) {
  graph.assign(n, vector<int>());
  for (int e = 0; e < edges; ++e) {
    int from = read_size() - 1;
    int to = read_size() - 1;
    graph[from].push_back(to);
    if (!oriented) graph[to].push_back(from);
  }
}
void read_tree(int n, vector<vector<int>>& graph) {
  read_graph(n, n - 1, graph);
}
void add_to_each(vector<int>& a, int delta) {
  for (int& value : a) value += delta;
}
void add_to_each(vector<pair<int, int>>& a, int delta) {
  for (pair<int, int>& value : a) {
    value.first += delta;
    value.second += delta;
  }
}
template <class T>
void print(T& a, char sep = ENDL) {
  cout << a << sep;
}
template <class T>
void print_vector(vector<T>& a, char sep = SPACE) {
  for (T& value : a) cout << value << sep;
  if (sep != ENDL) cout << ENDL;
}
template <class T>
void print_matrix(vector<vector<T>>& a, char sep = SPACE) {
  for (vector<T>& row : a) {
    print_vector(row, sep);
  }
}
void print_pairs(vector<pair<int, int>>& a, char sep = ENDL) {
  for (pair<int, int>& value : a)
    cout << value.first << " " << value.second << sep;
  if (sep != ENDL) cout << ENDL;
}
int get_bit(long long mask, int bit) { return (int)((mask >> bit) & 1); }
long long set_bit(long long mask, int bit) { return mask | (1LL << bit); }
long long clear_bit(long long mask, int bit) { return mask & (~(1LL << bit)); }
vector<int> reverse(vector<int>& a) {
  reverse(a.begin(), a.end());
  return a;
}
void update_max(long long& cur_value, long long new_value) {
  cur_value = max(cur_value, new_value);
}
void update_min(long long& cur_value, long long new_value) {
  cur_value = min(cur_value, new_value);
}
long long gcd(long long a, long long b) { return (a == 0 ? b : gcd(b % a, a)); }
long long lcm(long long a, long long b) {
  return (a * b == 0 ? 0 : a / gcd(a, b) * b);
}
bool check_index(int index, int size) { return 0 <= index && index < size; }
bool check_cell(int x, int xSize, int y, int ySize) {
  return check_index(x, xSize) && check_index(y, ySize);
}
void init() {}
int n;
vector<int> a;
vector<vector<int>> graph;
void read_input() {
  n = read_size();
  read_vector(a, n);
  read_tree(n, graph);
}
vector<long long> answer;
vector<int> sizes;
vector<int> order;
vector<vector<int>> ct;
vector<int> tin, tout;
vector<int> nt;
int dt;
void dfs(int from = 0, int p = -1) {
  int color = a[from];
  order.push_back(from);
  tin[from] = dt++;
  ct[color].push_back(tin[from]);
  sizes[from] = 1;
  for (int to : graph[from]) {
    if (to != p) {
      dfs(to, from);
      sizes[from] += sizes[to];
    }
  }
  order.push_back(from);
  tout[from] = dt++;
  nt[from] = ct[color].size();
  ct[color].push_back(tout[from]);
}
int f(int c, vector<int>& tree, int ps, int left, int right, int max_t) {
  if (left > right) {
    return left;
  }
  long long& ans = answer[c];
  vector<int> sz;
  int i = left;
  while (i < right) {
    int t = tree[i];
    if (t >= max_t) break;
    int v = order[t];
    sz.push_back(sizes[v]);
    ++i;
    long long sum = 0;
    for (int to : graph[v]) {
      if (tin[to] < tin[v]) continue;
      i = f(c, tree, sizes[to], i, right, tout[to]);
      ans += sizes[to] * sum;
      sum += sizes[to];
    }
    ans += sizes[v];
    i = nt[v] + 1;
  }
  long long sum = 0;
  for (long long size : sz) {
    ans += size * (ps - size);
    ans -= size * sum;
    sum += size;
  }
  return i;
}
vector<long long> get_answer() {
  order.clear();
  ct.assign(n + 1, vector<int>(0));
  sizes.assign(n, 0);
  tin.assign(n, -1);
  tout.assign(n, -1);
  nt.assign(n, -1);
  dt = 0;
  dfs();
  answer.assign(n, 0);
  for (int c = 1; c <= n; ++c) {
    f(c - 1, ct[c], n, 0, ct[c].size(), order.size());
  }
  return answer;
}
void print_answer(vector<long long> answer) {
  print_vector(answer, ENDL);
  cout << ENDL;
}
void solve_test() {
  read_input();
  vector<long long> answer = get_answer();
  print_answer(answer);
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  init();
  int tests = 1;
  for (int test = 1; test <= tests; ++test) {
    solve_test();
  }
  return 0;
}
