#include <bits/stdc++.h>
using namespace std::literals::string_literals;
using i64 = std::int_fast64_t;
using std::cout;
using std::cerr;
using std::endl;
using std::cin;

template<typename T>
std::vector<T> make_v(size_t a){return std::vector<T>(a);}

template<typename T,typename... Ts>
auto make_v(size_t a,Ts... ts){
  return std::vector<decltype(make_v<T>(ts...))>(a,make_v<T>(ts...));
}

#ifndef INCLUDED_FENWICK_TREE_HPP
#define INCLUDED_FENWICK_TREE_HPP

#include <functional>
#include <vector>

template<class CommutativeMonoid>
class fenwick_tree {
public:
	using T = typename CommutativeMonoid::value_type;
	using size_type = std::uint_fast32_t;

	using checker = std::function<bool(T)>;

	std::vector<T> data;
	
private:
	size_type get_lsb(size_type i) const { return i & (~i + 1); }
	
public:
	fenwick_tree() = default;
	fenwick_tree(const fenwick_tree &) = default;
	fenwick_tree(fenwick_tree &&) = default;

	fenwick_tree(size_type size): data(size + 1, T{}) {}

	template<class InputIt>
	fenwick_tree(InputIt first, InputIt last) : fenwick_tree(std::distance(first, last)) {
		for(int index = 0; first != last; first++, index++) add(index, *first);
	}
	
	fenwick_tree & operator=(const fenwick_tree &) = default;
	fenwick_tree & operator=(fenwick_tree &&) = default;

	T fold(size_type last) const {
		T acc{};
		while(last) {
			acc = CommutativeMonoid::operation(data[last], acc);

			last -= get_lsb(last);
		}
		
		return acc;
	}
	T fold(size_type first, size_type last) const {
		T acc{};
		while(first < last) {
			acc = CommutativeMonoid::operation(data[last], acc);

			last -= get_lsb(last);
		}

		while(last < first) {
			acc = CommutativeMonoid::operation(CommutativeMonoid::inverse(data[first]), acc);

			first -= get_lsb(first);
		}
		
		return acc;
	}
	void update(size_type index, const T& value) {
		for(++index; index < data.size(); index += get_lsb(index)) {
			data[index] = CommutativeMonoid::operation(data[index], value);
		}
	}
	void change(size_type index, const T& value) {
		update(index, CommutativeMonoid::operation(CommutativeMonoid::inverse((*this)[index]), value));
	}

	// min{x | f(fold(x)) = true}
	template<class F>
	size_type search(const F & f) {
		if(f(T{})) return 0;

		T acc{};
		size_type i = 0, k = data.size();
		while(k >>= 1) {
			if((i | k) < data.size() and !f(CommutativeMonoid::operation(acc, data[i | k]))) {
				acc = CommutativeMonoid::operation(acc, data[i | k]);
				i |= k;
			}
		}
		return i + 1;
	}

	T operator[](const size_type& k) const { return fold(k, k + 1); };

	bool empty() const { return size() == 0; }
	size_type size() const { return data.size() - 1; }
	void swap(fenwick_tree & r) { data.swap(r.data); }
};

template<class T>
struct monoid {
	using value_type = T;

	static value_type operation(const value_type& a, const value_type& b) { return a + b; };
	static value_type inverse(const value_type& x) { return -x; }
};

#endif

#define NDEBUG

int main() {
	int n; scanf("%d", &n); std::vector<int> a(n - 1), b(n - 1), c(n);
	std::vector<std::vector<int>> g(n);
	for(int i = 0; i < n; i++) scanf("%d", &c[i]);
	for(int i = 0; i < n - 1; i++) {
		scanf("%d%d", &a[i], &b[i]);
		a[i]--; b[i]--;

		g[a[i]].push_back(i);
		g[b[i]].push_back(i);
	}
	
	std::vector<int> in(n), out(n), tour, size(n), parent(n, -1);
	auto dfs = [&](auto&& dfs, int v, int par) -> void {
		in[v] = tour.size();
		tour.push_back(v);
		size[v] = 1;
		for(int id: g[v]) {
			int to = a[id] ^ b[id] ^ v;
			if(to == par) continue;

			dfs(dfs, to, v);
			parent[to] = v;
			size[v] += size[to];
		}
		out[v] = tour.size();
	};
	dfs(dfs, 0, -1);

	std::vector<std::vector<std::pair<int, int>>> vec(n);
	for(int i = 0; i < n; i++) vec[c[i] - 1].push_back({in[i], i});
	for(auto& v: vec) sort(begin(v), end(v));
	
	fenwick_tree<monoid<int>> fwt(tour.size()), level(tour.size() + 1);
	for(int i = 0; i < (int)tour.size(); i++) fwt.update(i, 1);

	for(int k = 0; k < n; k++) {
		if(vec[k].empty()) {
			printf("0\n");
			continue;
		}
		
		std::vector<std::vector<int>> tan(1);
		if(vec[k][0].second != 0) {
			level.update(in[0], 1);
			level.update(out[0], -1);
			tan[0].push_back(0);
		}
		for(auto e: vec[k]) {
			int v = e.second;
			int tmp = level.fold(0, in[v] + 1);
			level.update(in[v], 1);
			level.update(out[v], -1);

			if((int)tan.size() <= tmp) tan.push_back({});
			tan[tmp].push_back(v);
		}
		tan.push_back({});

		#ifndef NDEBUG
		cout << k + 1 << endl;
		for(int i = 0; i < tan.size(); i++) {
			cout << i << ": ";
			for(auto v: tan[i]) cout << v + 1 << " ";
			cout << endl;
		}
		#endif

		i64 ans = (i64)n * (n + 1) >> 1;
		for(int i = 1; i < (int)tan.size(); i++) {
			for(auto v: tan[i]) fwt.update(in[v], -size[v]);

			for(auto v: tan[i - 1]) {
				if(v == 0 and vec[k][0].second != 0) {
					i64 sz = fwt.fold(in[0], out[0]);
					ans -= sz * (sz + 1) >> 1;
				} else {
					for(int id: g[v]) {
						int to = a[id] ^ b[id] ^ v;
						if(to == parent[v]) continue;
						i64 sz = fwt.fold(in[to], out[to]);
						ans -= sz * (sz + 1) >> 1;
					}
				}
			}
			
			for(auto v: tan[i]) fwt.update(in[v], size[v]);
		}
		if(vec[k][0].second != 0) {
			level.update(in[0], -1);
			level.update(out[0], 1);
		}
		for(auto e: vec[k]) {
			int v = e.second;
			level.update(in[v], -1);
			level.update(out[v], 1);
		}
		
		printf("%lld\n", ans);
	}
	return 0;
}


Measured memory_bytes: 49552