#include <iostream>
#include <string>
#include <sstream>
#include <iomanip> 
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <functional>
#include <algorithm>
#include <unordered_map>
#include <unordered_set>
#include <numeric>
#pragma warning(disable:4996)

using namespace std;

vector<long long> c, parent, d, ct, ans;
vector<bool> used;
vector<vector<int>> adj, plist;

void dfs(int id) {
	ct[id] = 1;
	long long x, s, ss = 0, v;
	for (auto p : adj[id]) {
		if (parent[p] == -1) {
			parent[p] = id;

			x = plist[c[id]].size();
			s = 0;
			dfs(p);
			while (plist[c[id]].size() > x) {
				s += plist[c[id]].back();
				plist[c[id]].pop_back();
			}

			ct[id] += ct[p];

			v = ct[p] - s;
			ans[c[id]] += v * (v - 1) / 2 + v;
			ss += s;
		}
	}

	plist[c[id]].push_back(ct[id]);
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);

	long long n, i, j, k, a, b, level, x, total;
	cin >> n;
	c.resize(n + 1);
	used.assign(n + 1, false);
	for (i = 1; i <= n; i++) {
		cin >> c[i];
		used[c[i]] = true;
	}
	adj.resize(n + 1);
	for (i = 0; i < n - 1; i++) {
		cin >> a >> b;
		adj[a].push_back(b);
		adj[b].push_back(a);
	}
	parent.assign(n + 1, -1);
	parent[1] = 0;
	ct.resize(n + 1);
	plist.resize(n + 1);

	ans.assign(n + 1, 0);
	dfs(1);

	for (i = 1; i <= n; i++) {
		if (used[i]) {
			ans[i] += (n - plist[i][0]) * (n - plist[i][0] - 1) / 2 + (n - plist[i][0]);
			ans[i] = n * (n - 1) / 2 + n - ans[i];
		}
		cout << ans[i] << "\n";
	}

	return 0;
}
