#include <iostream>
#include <iomanip>
#include <random>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <cmath>
#include <numeric>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <sstream>
#include <bitset>
#include <cassert>
#include <fstream>
#include <queue>

#define len(X) ((int)(X).size())

#ifdef __LOCAL
	#define DEBUG_OUTPUT_ENABLED 1
	#define DBG(X) dout << #X << "=" << (X) << '\n';
	#define SAY(X) dout << (X) << '\n';
#else
	#define DEBUG_OUTPUT_ENABLED 0
	#define DBG(X) 42;
	#define SAY(X) 42;
#endif

#define dout   ___debug::instance

using namespace std;
using ll = long long int;
using ull = unsigned long long int;
using ld  = long double;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
template<typename T, typename S> inline ostream& operator<<(ostream& os, const pair<T, S> p) { cout << "[" << p.first << ";" << p.second << "]"; return os; }
template<typename T> inline ostream& operator<<(ostream& os, const vector<T>& v) { for(auto el: v) cout << el << " "; return os; }
template<typename T> inline ostream& operator<<(ostream& os, const set<T>& v) { for(auto el: v) cout << el << " "; return os; }
template<typename T, typename S> inline ostream& operator<<(ostream& os, const map<T, S>& v) { for(auto el: v) cout << el << " "; return os; }
template<typename T> inline ostream& operator<<(ostream& os, const multiset<T>& v) { for(auto el: v) cout << el << " "; return os; }
namespace ___debug {
	struct DebugStream {
		private:
			bool is_first;
		public:
			DebugStream(bool _is_first): is_first(_is_first) {}
			template<typename T> DebugStream operator<<(const T& value) const {
				assert(DEBUG_OUTPUT_ENABLED);
				if(is_first) cout << "[DBG] ";
				cout << value;
				return DebugStream(false);
			};

			template<typename T> DebugStream printArray(T* l, T* r) {
				assert(DEBUG_OUTPUT_ENABLED);
				if(is_first) cout << "[DBG] ";
				while(l != r) {
					cout << (*l);
					++l;
					if(l == r) {
						cout << '\n';
					} else {
						cout << ' ';
					}
				}
				return DebugStream(false);
			}
	};
	DebugStream instance(true);
};

const int INT_INF = (int)(2e9);
const ll  LL_INF  = (ll)(2e18);

const int NIL = -1;
static mt19937 _g(time(nullptr));

inline ll randint(ll a, ll b) { ll w = (_g() << 31LL) ^ _g(); return a + w % (b - a + 1); }
inline void fast_io() { ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); };
template<typename T> inline T sign(T x) { return T(x > 0) - T(x < 0); }
template<typename T> inline T fetch() { T ret; cin >> ret; return ret; }
template<typename T> inline vector<T> fetch_vec(int sz) { vector<T> ret(sz); for(auto& elem: ret) cin >> elem; return ret; }
const int MAXN = (int)2e5 + 7777;
int vertCol[MAXN], cntCol[MAXN], n, sz;
vector<pii> tree[2 * MAXN];
inline void addEdge(int l, int r, int v, int u) {
	if(r < l) return;
	l += sz, r += sz + 1;
	while(l < r) {
		if(l & 1) tree[l++].emplace_back(v, u);
		if(r & 1) tree[--r].emplace_back(v, u);
		l >>= 1, r >>= 1;
	}
}
int pa[MAXN], cnt[MAXN];
int St[2 * MAXN], head;
ll cur = 0;
void initDSU() {
	for(int v = 0; v < n; ++v) pa[v] = v, cnt[v] = 1;
	head = 0;
	cur = n;
}
int getParent(int v) {
	while(pa[v] != v) v = pa[v];
	return v;
}
int Connect(int v, int u) {
	v = getParent(v), u = getParent(u);
	if(v == u) return 0;
	if(cnt[v] > cnt[u]) swap(v, u);
	pa[v] = u;
	cur += cnt[v] * 1LL * cnt[u];
	cnt[u] += cnt[v];
	St[head++] = v;
	return 1;
}
void Undo() {
	int v = St[--head];
	int u = pa[v];
	cnt[u] -= cnt[v];
	pa[v] = v;
	cur -= cnt[v] * 1LL * cnt[u];
}
ll answ[MAXN];
void dfs(int v) {
	int h = head;
	for(auto& ed: tree[v]) Connect(ed.first, ed.second);
	if(v >= sz) {
		answ[v - sz] = cur;
	} else {
		dfs(2 * v);
		dfs(2 * v + 1);
	}
	while(head > h) Undo();
}
void solve() {
	cin >> n; sz = n + 1;
	for(int i = 0; i < n; ++i) {
		cin >> vertCol[i];
		++cntCol[vertCol[i]];
	}
	for(int id = 0; id < n - 1; ++id) {
		int v = fetch<int>() - 1;
		int u = fetch<int>() - 1;
		int vc = vertCol[v], uc = vertCol[u];
		if(vc == uc) {
			addEdge(0, vc - 1, v, u);
			addEdge(vc + 1, sz - 1, v, u);
		} else {
			if(vc > uc) swap(vc, uc);
			addEdge(0, vc - 1, v, u);
			addEdge(vc + 1, uc - 1, v, u);
			addEdge(uc + 1, sz - 1, v, u);
		}
	}
	initDSU();
	dfs(1);
	for(int c = 1; c <= n; ++c) {
		answ[c] -= cntCol[c];
		answ[c] = (n * 1LL * (n + 1)) / 2 - answ[c];
		cout << answ[c] << '\n';
	}
}

int main() {
	fast_io();
	solve();

	return 0;
}


Measured memory_bytes: 111920