#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define ll long long
#define ld long double
#define F first
#define S second
#define eb emplace_back
#define pb push_back
#define mp make_pair
#define all(x) begin(x), end(x)
#define rall(x) rbegin(x), rend(x)
using namespace __gnu_pbds;
using namespace std;
template <class T> using oset = tree <pair <T, T>, null_type, less <pair <T, T>>, rb_tree_tag, tree_order_statistics_node_update>;
template <class T>
void print(vector <T> v) {
for (T i : v) cout << i << " ";
cout << '\n';
}
template <typename T>
void read(vector <T>& v) {for (T& i : v) cin >> i;}
template <typename T>
void read(T&& t) {cin >> t;}
template <typename T, typename... Args>
void read(T&& t, Args&&... args)
{
cin >> t;
read(forward<Args>(args)...);
}
template <typename T>
void print(T&& t) {cout << t << '\n';}
template <typename T, typename... Args>
void print(T&& t, Args&&... args)
{
cout << t << " ";
print(forward<Args>(args)...);
}
void usaco(string name = "")
{
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
if(name.size())
{
freopen((name+".in").c_str(), "r", stdin);
freopen((name+".out").c_str(), "w", stdout);
}
}
const int mxn = 2e5+1;
vector <set <int>> vc(mxn);
vector <int> adj[mxn], ans(mxn);
void dfs(int u, int p)
{
int big = 0, sz = 0;
for (int v : adj[u])
{
if (v == p) continue;
dfs(v, u);
if (sz < vc[v].size())
{
sz = vc[v].size();
big = v;
}
}
if (big) swap(vc[u], vc[big]);
for (int v : adj[u])
{
if (v == p) continue;
vc[u].insert(begin(vc[v]), end(vc[v]));
}
ans[u] = vc[u].size();
}
void solve()
{
int n;
read(n);
for (int i = 1; i <= n; ++i)
{
int x;
read(x);
vc[i].insert(x);
}
for (int i = 0; i < n-1; ++i)
{
int u, v;
read(u, v);
adj[u].eb(v);
adj[v].eb(u);
}
dfs(1, 0);
for (int i = 1; i <= n; ++i) cout << ans[i] << " ";
}
int32_t main()
{
usaco();
ll t = 1;
while (t--) solve();
}