#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rrep(i, n) for (int i = (int)(n - 1); i >= 0; i--)
#define all(x) (x).begin(), (x).end()
#define sz(x) int(x.size())
#define get_unique(x) x.erase(unique(all(x)), x.end());
typedef long long ll;
typedef complex<double> Complex;
const int INF = 1e9;
const ll MOD = 1e9 + 7;
const ll LINF = 1e18;
template <class T>
bool chmax(T& a, const T& b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <class T>
bool chmin(T& a, const T& b) {
    if (b < a) {
        a = b;
        return 1;
    }
    return 0;
}
template <class T>
vector<T> make_vec(size_t a) {
    return vector<T>(a);
}
template <class T, class... Ts>
auto make_vec(size_t a, Ts... ts) {
    return vector<decltype(make_vec<T>(ts...))>(a, make_vec<T>(ts...));
}
template <typename T>
ostream& operator<<(ostream& os, vector<T> v) {
    for (int i = 0; i < sz(v); i++) {
        os << v[i];
        if (i < sz(v) - 1) os << " ";
    }
    return os;
}

template <typename T>
struct SegmentTree {
    int n;
    vector<T> node;
    T calc(T a, T b) {
        return a + b;
        // return min(a, b);
        // return max(a, b);
    }
    T e = 0;
    SegmentTree(vector<T> v) {
        int sz = v.size();
        n = 1;
        while (n < sz) {
            n *= 2;
        }
        node.resize(2 * n - 1, e);
        for (int i = 0; i < sz; i++) {
            node[i + n - 1] = v[i];
        }
        for (int i = n - 2; i >= 0; i--) {
            node[i] = calc(node[2 * i + 1], node[2 * i + 2]);
        }
    }
    SegmentTree(int sz) {
        n = 1;
        while (n < sz) {
            n *= 2;
        }
        node.resize(2 * n - 1, e);
    }
    void update(int x, T val) {
        x = n + x - 1;
        node[x] = val;
        while (x > 0) {
            x = (x - 1) / 2;
            node[x] = calc(node[2 * x + 1], node[2 * x + 2]);
        }
    }
    void add(int x, T val) {
        x = n + x - 1;
        node[x] += val;
        while (x > 0) {
            x = (x - 1) / 2;
            node[x] = calc(node[2 * x + 1], node[2 * x + 2]);
        }
    }
    T query(int a, int b, int k = 0, int l = 0, int r = -1) {
        if (r < 0) r = n;
        if (r <= a || b <= l) return e;
        if (a <= l && r <= b) return node[k];
        T vl = query(a, b, 2 * k + 1, l, (l + r) / 2);
        T vr = query(a, b, 2 * k + 2, (l + r) / 2, r);
        return calc(vl, vr);
    }
    T at(int x) {
        return node[n + x - 1];
    }
};

vector<vector<int>> g;
vector<int> in, out;
int k = 0;
void dfs(int now = 0, int pre = -1) {
    in[now] = k++;
    for (int nxt : g[now]) {
        if (nxt == pre) continue;
        dfs(nxt, now);
    }
    out[now] = k;
}
ll f(int x) {
    return (ll)x * ((ll)x + 1ll) / 2ll;
}
int main() {
    int n;
    cin >> n;
    g.resize(n);
    in.resize(n);
    out.resize(n);
    vector<vector<int>> v(n);
    rep(i, n) {
        int c;
        cin >> c;
        v[--c].push_back(i);
    }
    rep(i, n - 1) {
        int a, b;
        cin >> a >> b;
        g[--a].push_back(--b);
        g[b].push_back(a);
    }
    dfs();

    vector<ll> vv(n, 1ll);
    SegmentTree<ll> segt(vv);
    rep(i, n) {
        ll ans = f(n);
        sort(all(v[i]), [&](int a, int b) { return in[a] > in[b]; });
        vector<pair<int, ll>> memo;
        for (int now : v[i]) {
            ll cnt = 1;
            for (int nxt : g[now]) {
                if (in[nxt] < in[now]) continue;
                ll x = segt.query(in[nxt], out[nxt]);
                ans -= f(x);
                cnt += x;
            }
            segt.add(in[now], -cnt);
            memo.emplace_back(in[now], cnt);
        }
        ans -= f(segt.query(0, n));
        for (auto p : memo) {
            auto [idx, val] = p;
            segt.add(idx, val);
        }
        cout << ans << endl;
    }
}

Measured memory_bytes: 40896