#include <bits/stdc++.h>
using namespace std;
const int maxn = 100010;
int n, head[maxn], cnt, yanse[maxn], root[maxn], tot;
long long ans[maxn << 1];
struct edge {
  int to, next;
} e[maxn << 1];
struct tree {
  int lson, rson, geshu_maxx;
  long long ans;
} t[maxn * 50];
inline int read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-') f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = (x << 1) + (x << 3) + (ch ^ 48);
    ch = getchar();
  }
  return x * f;
}
inline void write(int a) {
  if (a < 0) {
    char a = '-', b = '1';
    putchar(a);
    putchar(b);
  } else {
    if (a >= 10) write(a / 10);
    putchar(a % 10 + '0');
  }
}
void add(int from, int to) {
  e[++cnt] = (edge){to, head[from]};
  head[from] = cnt;
}
void pushup(int k1) {
  int ls = t[k1].lson, rs = t[k1].rson;
  if (t[ls].geshu_maxx > t[rs].geshu_maxx) {
    t[k1].geshu_maxx = t[ls].geshu_maxx;
    t[k1].ans = t[ls].ans;
  } else if (t[ls].geshu_maxx < t[rs].geshu_maxx) {
    t[k1].geshu_maxx = t[rs].geshu_maxx;
    t[k1].ans = t[rs].ans;
  } else {
    t[k1].geshu_maxx = t[ls].geshu_maxx;
    t[k1].ans = t[ls].ans + t[rs].ans;
  }
}
int hebing(int k1, int k2, int l, int r) {
  if (!k1 || !k2) return k1 + k2;
  if (l == r) {
    t[k1].geshu_maxx += t[k2].geshu_maxx;
    return k1;
  }
  int mid = (l + r) / 2;
  t[k1].lson = hebing(t[k1].lson, t[k2].lson, l, mid);
  t[k1].rson = hebing(t[k1].rson, t[k2].rson, mid + 1, r);
  pushup(k1);
  return k1;
}
void kaidian(int p, int l, int r, int o) {
  if (l == r) {
    t[o].geshu_maxx++;
    t[o].ans = l;
    return;
  }
  int mid = (l + r) / 2;
  if (p <= mid) {
    if (!t[o].lson) t[o].lson = ++tot;
    kaidian(p, l, mid, t[o].lson);
  } else {
    if (!t[o].rson) t[o].rson = ++tot;
    kaidian(p, mid + 1, r, t[o].rson);
  }
  pushup(o);
}
void dfs(int now, int father) {
  for (int i = head[now]; i; i = e[i].next) {
    int to = e[i].to;
    if (to == father) continue;
    dfs(to, now);
    root[now] = hebing(root[now], root[to], 1, n);
  }
  if (!root[now]) root[now] = ++tot;
  kaidian(yanse[now], 1, n, root[now]);
  ans[now] = t[root[now]].ans;
}
signed main() {
  n = read();
  for (int i = 1; i <= n; i++) yanse[i] = read();
  for (int i = 1; i < n; i++) {
    int u = read(), v = read();
    add(u, v), add(v, u);
  }
  dfs(1, 0);
  for (int i = 1; i <= n; i++) printf("%lld ", ans[i]);
  return 0;
}
