#define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;

//template
#define rep(i,a,b) for(int i=(a);i<(b);i++)
#define rrep(i,a,b) for(int i=(a);i>(b);i--)
#define ALL(v) (v).begin(),(v).end()
typedef long long int ll;
const int inf = 0x3fffffff; const ll INF = 0x1fffffffffffffff; const double eps=1e-12;
void tostr(ll x,string& res){while(x)res+=('0'+(x%10)),x/=10; reverse(ALL(res)); return;}
template<class T> inline bool chmax(T& a,T b){ if(a<b){a=b;return 1;}return 0; }
template<class T> inline bool chmin(T& a,T b){ if(a>b){a=b;return 1;}return 0; }
//template end

template<typename T>struct LCT{
   struct Node{
      Node *lp=nullptr,*rp=nullptr,*par=nullptr;
      T val,sum,dat; int idx,sz=1; bool rev=0;
      Node(){}
      Node(int idx,T val):idx(idx),val(val),sum(val){}
      void inv(){swap(lp,rp); sum.inv(); rev^=1;}
      void eval(){if(rev){if(lp)lp->inv(); if(rp)rp->inv(); rev=0;}}
      void update(){
         sz=1; if(lp)sz+=lp->sz; if(rp)sz+=rp->sz;
         sum=val+dat; if(lp)sum+=lp->sum; if(rp)sum+=rp->sum;
      }
      bool is_root(){
         return !par||(par->lp!=this&&par->rp!=this);
      }
      void rotate(){
         Node *pp,*p,*c;
         p=par,pp=p->par;
         if(p->lp==this){c=rp; rp=p; p->lp=c;}
         else{c=lp; lp=p; p->rp=c;}
         if(pp){
            if(pp->lp==p)pp->lp=this;
            if(pp->rp==p)pp->rp=this;
         }
         par=pp; p->par=this; if(c)c->par=p;
         p->update(); update();
      }
      void splay(){
         eval();
         while(!is_root()){
            Node *q=par;
            if(q->is_root()){
               q->eval(); eval();
               if(q->lp==this)rotate();
               else rotate();
            }else{
               Node *r=q->par;
               r->eval(); q->eval(); eval();
               if(r->lp==q){
                  if(q->lp==this){q->rotate(); rotate();}
                  else{rotate(); rotate();}
               }else{
                  if(q->rp==this){q->rotate(); rotate();}
                  else{rotate(); rotate();}
               }
            }
         }
      }
   };
   LCT(){}
   Node *make(int idx,T val){return new Node(idx,val);}
   Node *expose(Node *v){
      Node *pre=nullptr;
      for(Node *cur=v;cur;cur=cur->par){
         cur->splay();
         if(cur->rp)cur->dat+=cur->rp->sum;
         cur->rp=pre;
         if(cur->rp)cur->dat-=cur->rp->sum;
         cur->update(); pre=cur;
      } v->splay(); return pre;
   }
   void link(Node *c,Node *p){
      expose(c); expose(p); c->par=p; p->rp=c; p->update();
   }
   void cut(Node *c){
      expose(c); c->lp->par=nullptr; c->lp=nullptr; c->update();
   }
   void evert(Node *v){expose(v); v->inv(); v->eval();}
   Node *lca(Node *u,Node *v){expose(u); return expose(v);}
   Node *root(Node *v){expose(v); while(v->lp)v->eval(),v=v->lp; return v;}
   void set(Node *v,T t){expose(v); v->val=t; v->update();}
   T &query(Node *v){expose(v); return v->sum;}
};
struct X{
   ll s1=0,s2=0;
   X(){}
   X(ll v,ll w):s1(v),s2(w){}
   void inv(){}
   X operator+(const X& x){return X(s1+x.s1,s2+x.s2);}
   X& operator+=(const X& x){
      s1+=x.s1; s2+=x.s1*(x.s1-1)/2;
      return *this;
   }
   X& operator-=(const X& x){
      s1-=x.s1; s2-=x.s1*(x.s1-1)/2;
      return *this;
   }
};
using V=LCT<X>::Node*;

vector<int> g[201000],lis[201000]; int par[201000];
void dfs(int v,int p){
   par[v]=p;
   for(int t:g[v])if(t!=p)dfs(t,v);
}

int main(){
   int n; cin>>n; vector<int> col(n);
   rep(i,0,n)cin>>col[i],col[i]--,lis[col[i]].push_back(i);
   rep(_,0,n-1){
      int x,y; cin>>x>>y; x--; y--;
      g[x].push_back(y); g[y].push_back(x);
   }
   g[n].push_back(0); dfs(n,-1);
   LCT<X> tree; vector<V> vs(n+1);
   rep(i,0,n+1)vs[i]=tree.make(i,X(1,0));
   rep(i,0,n)tree.link(vs[i],vs[par[i]]);
   rep(c,0,n){
      ll res=lis[c].size();
      for(int v:lis[c]){
         res+=tree.query(tree.root(vs[v])).s2;
         tree.cut(vs[v]);
         res-=tree.query(tree.root(vs[par[v]])).s2;
         res-=tree.query(vs[v]).s2;
      } printf("%lld\n",res);
      for(int v:lis[c])tree.link(vs[v],vs[par[v]]);
   }
   return 0;
}