#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <cmath>
#include <map>
#include <queue>
#include <iomanip>
#include <set>
#include <tuple>
#define mkp make_pair
#define mkt make_tuple
#define rep(i,n) for(int i = 0; i < (n); ++i)
using namespace std;
typedef long long ll;
const ll MOD=1e9+7;
template<class T> void chmin(T &a,const T &b){if(a>b) a=b;}
template<class T> void chmax(T &a,const T &b){if(a<b) a=b;}

struct Centroid{
    vector<vector<int>> g;
    vector<int> sz,dead;

    Centroid(){}
    Centroid(int V):sz(V,1),dead(V,0),g(V){}

    void init(int V){
        sz.resize(V,1);
        dead.resize(V,0);
        g.resize(V);
    }

    void add_edge(int u,int v){
        g[u].push_back(v);
        g[v].push_back(u);
    }

    int szdfs(int now,int par){
        sz[now]=1;
        for(auto nex:g[now]){
            if(nex==par||dead[nex]) continue;
            sz[now]+=szdfs(nex,now);
        }
        return sz[now];
    }

    void findCentroid(int now,int par,int V,vector<int> &cens){
        bool ok=true;
        for(auto nex:g[now]){
            if(nex==par||dead[nex]) continue;
            findCentroid(nex,now,V,cens);
            if(sz[nex]>V/2) ok=false;
        }
        if(V-sz[now]>V/2) ok=false;
        if(ok) cens.push_back(now);
    }

    vector<int> build(int root){
        vector<int> cens;
        szdfs(root,-1);
        findCentroid(root,-1,sz[root],cens);
        return cens;
    }

    void kill(int now){
        dead[now]=1;
    }

    bool alive(int now){
        return dead[now]==0;
    }
};

int N;
vector<int> C;

Centroid cent;
vector<int> mp;
vector<ll> ans;
vector<int> tmp;
vector<pair<int,ll>> v;

int dfs(int now,int par,ll sum){
    int res=1;
    mp[C[now]]++;
    for(auto nex:cent.g[now]){
        if(nex==par) continue;
        if(cent.alive(nex)==false) continue;
        res+=dfs(nex,now,sum);
    }
    mp[C[now]]--;
    if(mp[C[now]]==0){
        ans[C[now]]+=(sum-tmp[C[now]])*res;
        //tmp[C[now]]+=res;
        v.push_back(mkp(C[now],res));
    }
    return res;
}

int sfs(int now,int par){
    int res=1;
    for(auto nex:cent.g[now]){
        if(nex==par) continue;
        if(cent.alive(nex)==false) continue;
        res+=sfs(nex,now);
    }
    return res;
}

void reset(int now,int par){
    tmp[C[now]]=0;
    mp[C[now]]=0;
    for(auto nex:cent.g[now]){
        if(nex==par) continue;
        if(cent.alive(nex)==false) continue;
        reset(nex,now);
    }
}

void decompose(int now){
    vector<int> cs=cent.build(now);
    now=cs[0];

    cent.kill(now);
    vector<int> sz;
    ll sum=1;
    for(auto nex:cent.g[now]){
        if(cent.alive(nex)==false) continue;
        int res=sfs(nex,now);
        ans[C[now]]+=sum*res;
        sum+=res;
        sz.push_back(res);
    }
    ans[C[now]]++;

    int pos=0;
    for(auto nex:cent.g[now]){
        if(cent.alive(nex)==false) continue;
        mp[C[now]]=1;
        dfs(nex,now,sum-sz[pos]);
        pos++;
        //mp.clear();
        for(auto p:v) tmp[p.first]+=p.second;
        v.clear();
    }
    //cent.kill(now);
    //tmp.clear();
    reset(now,-1);

    for(auto nex:cent.g[now]){
        if(cent.alive(nex)==false) continue;
        decompose(nex);
    }
}

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

  cin>>N;
  C.resize(N);
  rep(i,N) cin>>C[i];
  rep(i,N) C[i]--;

  cent.init(N);
  rep(i,N-1){
      int a,b;
      cin>>a>>b;
      a--;b--;
      cent.add_edge(a,b);
  }

  ans.resize(N,0);
  tmp.resize(N,0);
  mp.resize(N,0);

  decompose(0);

  for(int i=0;i<N;i++) cout<<ans[i]<<endl;

  return 0;
}


Measured memory_bytes: 40372