#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

#ifdef LOCAL
#define dbg(...) debug(#__VA_ARGS__, __VA_ARGS__);
#else
#define dbg(...) 17;
#endif

template<typename T, typename S> ostream& operator << (ostream &os, const pair<T, S> &p) { return os << "(" << p.first << ", " << p.second << ")"; }
template<typename C, typename T = decay<decltype(*begin(declval<C>()))>, typename enable_if<!is_same<C, string>::value>::type* = nullptr>
ostream& operator << (ostream &os, const C &c) { bool f = true; os << "{"; for (const auto &x : c) { if (!f) os << ", "; f = false; os << x; } return os << "}"; }
template<typename T> void debug(string s, T x) { cerr << s << " = " << x << "\n"; }
template<typename T, typename... Args> void debug(string s, T x, Args... args) { cerr << s.substr(0, s.find(',')) << " = " << x << " | "; debug(s.substr(s.find(',') + 2), args...); }

struct lca_jump {
    int n;
    vector<vector<int>> par;
    vector<vector<int>> adj;
    vector<int> depth;
    void init(int _n) {
        n = _n;
        int d = 1;
        while ((1 << d) < n) d++;
        par.assign(d, vector<int>(n));
        adj.resize(n);
        depth.resize(n);
    }
    void ae(int x, int y) {
        adj[x].push_back(y);
        adj[y].push_back(x);
    }
    void gen(int root = 0) {
        par[0][root] = root;
        dfs(root);
    }
    void dfs(int src = 0) {
        for (int i = 1; i < par.size(); i++) {
            par[i][src] = par[i - 1][par[i - 1][src]];
        }
        for (int nxt: adj[src]) {
            if (nxt == par[0][src]) continue;
            depth[nxt] = depth[par[0][nxt] = src] + 1;
            dfs(nxt);
        }
    }
    int jump(int x, int d) {
        for (int i = 0; i < par.size(); i++) {
            if ((d >> i) & 1) {
                x = par[i][x];
            }
        }
        return x;
    }
    int lca(int x, int y) {
        if (depth[x] < depth[y]) swap(x, y);
        x = jump(x, depth[x] - depth[y]);
        if (x == y) return x;
        for (int i = par.size() - 1; i >= 0; i--) {
            int nx = par[i][x];
            int ny = par[i][y];
            if (nx != ny) x = nx, y = ny;
        }
        return par[0][x];
    }
};
int main() {
    ios_base::sync_with_stdio(0); cin.tie(0);
    const int INF = 1e9;
    int n; cin >> n;
    lca_jump L;
    L.init(n);
    vector<int> c(n);
    vector<vector<int>> store(n);
    vector<vector<int>> adj(n);
    for (int i = 0; i < n; i++) cin >> c[i], c[i]--;
    for (int i = 0; i < n; i++) {
        store[c[i]].push_back(i);
    }
    for (int i = 0; i < n - 1; i++) {
        int u, v; cin >> u >> v;
        u--, v--;
        L.ae(u, v);
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    L.gen(0);
    vector<set<pair<int, int>>> color(n);
    vector<int> up(n, -1);
    vector<int> sub(n);
    vector<int> depth(n);
    function<void(int, int)> dfs = [&](int src, int par) {
        color[c[src]].emplace(depth[src], src);
        sub[src] = 1;
        for (int nxt: adj[src]) {
            if (nxt == par) continue;
            depth[nxt] = depth[src] + 1;
            dfs(nxt, src);
            sub[src] += sub[nxt];
        }
        color[c[src]].erase({depth[src], src});
        if (color[c[src]].size() == 0) return;
        int vert = (*color[c[src]].rbegin()).second;
        up[src] = vert;
    };
    dfs(0, -1);
    for (int i = 0; i < n; i++) {
        ll ans = 0;
        sort(store[i].begin(), store[i].end());
        int sz = store[i].size();
        map<int, int> conv;
        map<int, int> uconv;
        for (int j = 0; j < sz; j++) {
            conv[store[i][j]] = j;
            uconv[j] = store[i][j];
        }
        vector<vector<int>> graph(sz);
        vector<int> roots;
        for (int x: store[i]) {
            if (up[x] != -1) {
                int u = conv[x];
                int v = conv[up[x]];
                graph[u].push_back(v);
                graph[v].push_back(u);
            } else {
                roots.push_back(x);
            }
        }
        auto c2 = [&](ll x) -> ll {
            return x * (x - 1) / 2 + x;
        };
        int top = n;
        for (int x: roots) {
            top -= sub[x];
        }
        ans += c2(top);
        function<void(int, int)> dfs_color = [&](int src, int par) {
            map<int, int> use;
            for (int nxt: adj[uconv[src]]) {
                if (nxt == L.par[0][uconv[src]]) continue;
                use[nxt] = sub[nxt];
            }
            for (int nxt: graph[src]) {
                if (nxt == par) continue;
                dfs_color(nxt, src);
                int diff = depth[uconv[nxt]] - depth[uconv[src]];
                int top = L.jump(uconv[nxt], diff - 1);
                use[top] -= sub[uconv[nxt]];
            }
            for (auto x: use) {
                ans += c2(x.second);
            }
        };
        for (int x: roots) {
            dfs_color(conv[x], -1);
        }
        ll total = 1LL * n * (n - 1) / 2 + n;
        cout << total - ans << '\n';
    }
    return 0;
}


Measured memory_bytes: 96400