#include<bits/stdc++.h>
#define Access using
#define Code namespace
#define Talker std;
Access Code Talker;
#define int long long
inline int r(){
int x=0,f=1;char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){x=(x<<3)+(x<<1)+c-'0';c=getchar();}return x*f;
}
const int maxn=300010;
int add(int x,int y){
return x+y;
}
struct segtree{
int tr[maxn<<2],lz[maxn<<2];
int*og;
int (*func)(int,int);
segtree(int a[],int(*fun)(int,int)){
og=a;
func=fun;
memset(tr,0,sizeof tr);
memset(lz,0,sizeof lz);
}
segtree(){
func=add;
memset(tr,0,sizeof tr);
memset(lz,0,sizeof lz);
}
~segtree(){
delete []og;
}
void maintain(int x){
tr[x]=func(tr[x<<1],tr[x<<1|1]);
}
void pushdown(int s,int t,int now){
int m=(s+t)>>1;
tr[now<<1]+=lz[now]*(m-s+1);
tr[now<<1|1]+=lz[now]*(t-m);
lz[now<<1]+=lz[now];
lz[now<<1|1]+=lz[now];
lz[now]=0;
}
void bulid(int s,int t,int now){
if(s==t){
tr[now]=og[s];
return;
}
int m=(s+t)>>1;
bulid(s,m,now<<1);
bulid(m+1,t,now<<1|1);
maintain(now);
}
void modify(int x,int w,int s,int t,int now){
if(s==t){
tr[now]=func(tr[now],w);
return;
}
int m=(s+t)>>1;
if(x<=m)modify(x,w,s,m,now<<1);
else modify(x,w,m+1,t,now<<1|1);
maintain(now);
}
void update(int l,int r,int w,int s,int t,int now){
if(l<=s&&t<=r){
tr[now]+=(t-s+1)*w;
lz[now]+=w;
return;
}
int m=(s+t)>>1;
if(lz[now]&&s!=t)
pushdown(s,t,now);
if(l<=m)update(l,r,w,s,m,now<<1);
if(m<r)update(l,r,w,m+1,t,now<<1|1);
maintain(now);
}
int query(int l,int r,int s,int t,int now){
if(l<=s&&t<=r)
return tr[now];
int m=(s+t)>>1,res=0;
if(lz[now])
pushdown(s,t,now);
if(l<=m)res=func(res,query(l,r,s,m,now<<1));
if(m<r)res=func(res,query(l,r,m+1,t,now<<1|1));
return res;
}
};
struct Graph{
int next[maxn<<1];
int to[maxn<<1];
int dis[maxn<<1];
int h[maxn<<1];
int cnt;
Graph(){
memset(next,0,sizeof next);
memset(h,0,sizeof h);
cnt=0;
}
void add(int u,int v,int w){
next[++cnt]=h[u];
to[cnt]=v;
dis[cnt]=w;
h[u]=cnt;
}
};
struct tree_chains{
int tp[maxn],dfn[maxn];
int son[maxn],fa[maxn],sz[maxn],dp[maxn];
int n,rt,idx;
segtree chains;
Graph tr;
tree_chains(Graph g,int root,int num){
rt=root;
n=num;
tr=g;
memset(tp,0,sizeof tp);
memset(dfn,0,sizeof dfn);
memset(son,0,sizeof son);
memset(fa,0,sizeof fa);
memset(sz,0,sizeof sz);
memset(dp,0,sizeof dp);
dp[root]=1;
findson(root,0);
setrank(root,root);
}
void findson(int u,int f){
dp[u]=dp[f]+1;
sz[u]=1;
fa[u]=f;
int now=0;
for(int i=tr.h[u];i;i=tr.next[i]){
int v=tr.to[i];
if(v==f)continue;
findson(v,u);
if(sz[son[u]]<sz[v])
son[u]=v;
sz[u]+=sz[v];
}
}
void setrank(int u,int t){
dfn[u]=++idx;
tp[u]=t;
if(!son[u])return;
setrank(son[u],t);
for(int i=tr.h[u];i;i=tr.next[i]){
int v=tr.to[i];
if(v==fa[u]||v==son[u])
continue;
setrank(v,v);
}
}
int LCA(int u,int v){
while(tp[u]!=tp[v]){
if(dp[tp[u]]<dp[tp[v]])swap(u,v);
u=fa[tp[u]];
}
return dp[u]<dp[v]?u:v;
}
void upd(int u,int v,int c){
while(tp[u]!=tp[v]){
if(dp[tp[u]]<dp[tp[v]])swap(u,v);
chains.update(dfn[tp[u]],dfn[u],c,1,n,1);
u=fa[tp[u]];
}
if(dp[u]<dp[v])swap(u,v);
chains.update(dfn[v],dfn[u],c,1,n,1);
}
int qry(int u,int v){
int ret=0;
while(tp[u]!=tp[v]){
if(dp[tp[u]]<dp[tp[v]])swap(u,v);
ret=chains.func(ret,chains.query(dfn[tp[u]],dfn[u],1,n,1));
u=fa[tp[u]];
}
if(dp[u]<dp[v])swap(u,v);
return chains.func(ret,chains.query(dfn[v],dfn[u],1,n,1));
}
void sub_upd(int x,int c){
chains.update(dfn[x],dfn[x]+sz[x]-1,c,1,n,1);
}
int sub_ask(int x){
chains.query(dfn[x],dfn[x]+sz[x]-1,1,n,1);
}
};
int n;
int a[maxn];
Graph g;
signed main(){
n=r();
for(int i=1;i<=n;i++)
a[i]=r();
for(int i=1;i<n;i++){
int u=r(),v=r();
g.add(u,v,1);
g.add(v,u,1);
}
tree_chains zkw(g,a[1],n);
for(int i=1;i<n;i++){
zkw.upd(a[i],a[i+1],1);
zkw.upd(a[i],a[i],-1);
}
for(int i=1;i<=n;i++)
cout<<zkw.chains.query(zkw.dfn[i],zkw.dfn[i],1,n,1)<<endl;
return 0;
}