#include <bits/stdc++.h>

using namespace std;

#define int long long
#define pb push_back
#define eb emplace_back
#define fi first
#define se second
#define fr(i, j, k) for (i = j; i < (k); i++)
#define all(x) x.begin(), x.end()
#define el '\n'
#define remax(a, b) a = max(a, b)
#define remin(a, b) a = min(a, b)
#define sz(x) int32_t(x.size())

typedef long double ld;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<pii> vpi;
// --------------------------------------------------------------------

string to_string(string s) {
	return '"' + s + '"';
}
string to_string(const char* s) {
	return to_string((string) s);
}
string to_string(bool b) {
	return (b ? "true" : "false");
}
template <typename A, typename B>
string to_string(pair<A, B> p) {
	return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}
template <typename A>
string to_string(A v) {
	bool first = true;  string res = "{";
	for (const auto &x : v) {
		if (!first) { res += ", "; }
		first = false; res += to_string(x);
	}
	res += "}";         return res;
}
void debug_out() {
	cerr << endl;
}
template <typename Head, typename ... Tail>
void debug_out(Head H, Tail... T) {
	cerr << " " << to_string(H);
	debug_out(T ...);
}

// #define TRACE

#ifdef TRACE
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#else
#define debug(...)
#endif
//============================================================================

const int N = 2e5 + 2;
vvi g(N);
vi c(N), ances(N), underAnces(N), par(N), sub(N);
vvi nodesWithColor(N);

void dfs_1(int u, int p, vi& recentAncestor, vi& immediateForColor) {
	ances[u] = recentAncestor[c[u]];
	underAnces[u] = immediateForColor[c[u]];
	nodesWithColor[ c[u] ].pb(u);
	recentAncestor[c[u]] = u;
	par[u] = p;
	for(int child : g[u]) {
		if(child != p) {
			immediateForColor[c[u]] = child;
			recentAncestor[c[u]] = u;
			dfs_1(child, u, recentAncestor, immediateForColor);
		}
	}
	recentAncestor[c[u]] = ances[u];
	immediateForColor[c[u]] = underAnces[u];
}

vi colorsOnRoot(N), deductChildOfSameColor(N);

void dfs_2(int u, int p) {
	sub[u] = 1;
	for(int c : g[u]) {
		if(c != p) {
			dfs_2(c, u);
			sub[u] += sub[c];
		}
	}
	if(ances[u] != -1) {
		deductChildOfSameColor[underAnces[u]] += sub[u];
	} else {
		colorsOnRoot[c[u]] += sub[u];
	}
}

int C2(int x) {
	return (x * (x - 1) / 2) + x;
}

int32_t main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int n, i, j;
	cin >> n;

	fr(i, 1, n + 1) {
		cin >> c[i];
	}
	fr(i, 0, n-1) {
		int u,v;
		cin >>u>>v;
		g[u].pb(v);
		g[v].pb(u);
	}

	vi tmp(n + 1, -1);
	vi tmp2(n + 1, -1);
	dfs_1(1, 0, tmp, tmp2);
	dfs_2(1, 0);
	for(int color = 1; color <= n; color++) {
		int cnt = 0;
		// check if root has color
		debug(color);
		if(c[1] != color) {
			int size = sub[1] - colorsOnRoot[color];
			cnt += C2(size);
		}
		debug(cnt);
		for (int node : nodesWithColor[color]) {
			debug(node);
			for(int child : g[node]) {
				if(child != par[node]) {
					int size = sub[child] - deductChildOfSameColor[child];
					cnt += C2(size);
				}
				debug(child, cnt);
			}
		}
		int tot = C2(n) - cnt;
		cout << tot << el;
	}
	// cout << endl;
	return 0;
}

Measured memory_bytes: 49596