#include<cstdio>
#include<iostream>
using namespace std;
const int N=1e5+10;
int n,co[N],head[N],h,son[N],size[N],fa[N],ctl[N],num[N],top;
long long A[N],sum[N];
struct edge{int to,next;}e[N<<1];
void work(int x,int y){
	e[++h].to=y;
	e[h].next=head[x];
	head[x]=h;
}
void dfs1(int x)
{
    size[x]=1;
    for(int i=head[x];i;i=e[i].next){
        int y=e[i].to;
        if(y==fa[x]) continue;
        fa[y]=x;
        dfs1(y);
        size[x]+=size[y];
        if(size[y]>size[son[x]]) son[x]=y;
    }
}
void upd(int u,int fa,int va){
    sum[num[co[u]]]-=co[u];
    num[co[u]]+=va;
    sum[num[co[u]]]+=co[u];
    if(sum[top+1])++top;
    if(!sum[top])--top;
    for(int i=head[u];i;i=e[i].next){
        if(e[i].to!=fa&&e[i].to!=son[u])upd(e[i].to,u,va);
    }
}
void dfs2(int u,int fa,int keep)
{
    if(son[u]) dfs2(son[u],u,1),ctl[son[u]]=1;
    for(int i=head[u];i;i=e[i].next){
        int v=e[i].to;
		if(v==fa||v==son[u])continue;
        dfs2(v,u,0);
    }
    upd(u,fa,1);
    ctl[son[u]]=0;
    A[u]=sum[top];
    if(!keep) upd(u,fa,-1);
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d",&co[i]);
	for(int i=1,a,b;i<n;i++){
		scanf("%d%d",&a,&b);
		work(a,b);
		work(b,a);
	}
	dfs1(1);
	dfs2(1,0,1);
	for(int i=1;i<=n;i++) printf("%lld ",A[i]);
}


#include<bits/stdc++.h>
#define ll long long
#define ri register int
#define lson tree[num].l
#define rson tree[num].r
using namespace std;
inline ll v_in()
{
    ll f=1,sum=0;
    char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch)){sum=(sum<<3)+(sum<<1)+(ch^48);ch=getchar();}
    return sum*f;
}
const int M=1e5+5;
ll n,tot,a[M],rt[M],opo[M],u,v;
struct e{ll sum,ans,l,r;}tree[M*50];
vector<ll>g[M];
inline void pushup(ll num)
{
	if(tree[lson].sum<tree[rson].sum)
	{
		tree[num].sum=tree[rson].sum;
		tree[num].ans=tree[rson].ans;
	}
	if(tree[lson].sum>tree[rson].sum)
	{
		tree[num].sum=tree[lson].sum;
		tree[num].ans=tree[lson].ans;
	}
	if(tree[lson].sum==tree[rson].sum)
	{
		tree[num].sum=tree[lson].sum;
		tree[num].ans=tree[lson].ans+tree[rson].ans;
	}
}
inline ll merge(ll x,ll y,ll l,ll r)
{
	if(!x||!y)return x+y;
	if(l==r)
	{
		tree[x].sum+=tree[y].sum;
		tree[x].ans=l;
		return x;
	}
	ll mid=(l+r)>>1;
	tree[x].l=merge(tree[x].l,tree[y].l,l,mid);
	tree[x].r=merge(tree[x].r,tree[y].r,mid+1,r);
	pushup(x);
	return x;
}
inline void updata(ll &num,ll l,ll r,ll k)
{
	if(!num)num=++tot;
	if(l==r)
	{
		tree[num].sum++;
		tree[num].ans=l;
		return;
	}
	ll mid=(l+r)>>1;
	if(k<=mid)updata(lson,l,mid,k);
	else updata(rson,mid+1,r,k);
	pushup(num);
}
inline void dfs(ll u,ll fa)
{
	for(ri i=0;i<g[u].size();i++)
	{
		ll v=g[u][i];
		if(v==fa)continue;
		dfs(v,u);
		merge(u,v,1,M);
	}
	updata(rt[u],1,M,a[u]);
	opo[u]=tree[rt[u]].ans;
}
int main()
{
	n=v_in();
	for(ri i=1;i<=n;i++)a[i]=v_in(),rt[i]=++tot;
	for(ri i=1;i<=n-1;i++)
	{
		u=v_in(),v=v_in();
		g[u].push_back(v);g[v].push_back(u);
	}
	dfs(1,0);
	for(ri i=1;i<=n;i++)printf("%lld ",opo[i]);
	return 0;
}


#include<cstdio>
#include<map>
#define N 100005
using namespace std;
struct Edge{
	int to,next;
}edge[N*2];
int head[N],tot;
void addedge(int from,int to){
	edge[++tot].to=to;
	edge[tot].next=head[from];
	head[from]=tot;
}
int col[N];
long long ans[N];
map<int,int> dfs(int now,int fa){
	int max=1;
	long long sum=col[now];
	map<int,int> mmp;
	mmp[col[now]]=1;
	for(int i=head[now];i;i=edge[i].next){
		if(edge[i].to==fa){
			continue;
		}
		map<int,int> tmp=dfs(edge[i].to,now);
		for(map<int,int>::iterator it=tmp.begin();it!=tmp.end();++it){
			mmp[(*it).first]+=(*it).second;
			if(mmp[(*it).first]>max){
				max=mmp[(*it).first];
				sum=(*it).first;
			}else if(mmp[(*it).first]==max){
				sum+=(*it).first;
			}
		}
	}
	ans[now]=sum;
	return mmp;
}
int main(){
	int n,u,v;
	scanf("%d",&n);
	for(int i=1;i<=n;++i){
		scanf("%d",&col[i]);
	}
	for(int i=1;i<n;++i){
		scanf("%d%d",&u,&v);
		addedge(u,v);
		addedge(v,u);
	}
	dfs(1,1);
	for(int i=1;i<=n;++i){
		printf("%d ",ans[i]);
	}
}


#include<bits/stdc++.h>

using namespace std;

#define ll long long

const int maxn = 100001;

inline int read() {
	char c = getchar(); int x = 0, f = 1;
	while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
	while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
	return x * f;
}

int N, col[maxn], siz[maxn], son[maxn], cnt[maxn], Mx, Son;

ll sum = 0, ans[maxn];

vector<int> v[maxn];

void dfs(int x, int fa)
{
	siz[x] = 1;
	for(int i=0; i<v[x].size(); i++) {
		int to = v[x][i];
		if(to == fa) continue;
		dfs(to, x);
		siz[x] += siz[to];
		if(siz[to] > siz[son[x]]) son[x] = to;
	}
}

void add(int x, int fa, int val) {
	cnt[col[x]] +=val;
	if(cnt[col[x]] > Mx) Mx = cnt[col[x]], sum = col[x];
	else if (cnt[col[x]] == Mx) sum += (ll)col[x];
	for(int i=0;i<v[x].size();i++) {
		int to = v[x][i];
		if(to == fa || to == Son) continue;
		add(to, x, val);
	}
}

void dfs2(int x, int fa, int opt) {
	for(int i=0; i<=v[x].size(); i++) {
		int to = v[x][i];
		if(to == fa) continue;
		if(to != son[x]) dfs2(to, x, 0);
	}
	if(son[x]) dfs2(son[x], x, 1), Son = son[x];

	add(x, fa, 1); Son = 0;
	ans[x] = sum;
	if(!opt) add(x, fa, -1), sum = 0, Mx = 0;
}

int main()
{
	N = read();
	for(int i=1; i<=N; i++) col[i] = read();
	for(int i=1; i<=N+1; i++) {
		int x=read(), y=read();
		v[x].push_back(y); v[y].push_back(x);
	}
	dfs(1, 0);
	dfs2(1, 0, 0);
	for(int i=1; i<=N; i++) printf("%lld", ans[i]);
	return 0;
}


#include<bits/stdc++.h>
#define maxn 200005
#define maxe 10000005
using namespace std;
int rt[maxe],n,a[maxn],x,y,Ans[maxn],nxt[maxn],lnk[maxn],son[maxn],tot,sum[maxe],Mx[maxe],lc[maxe],rc[maxe];
inline int read(){
	int ret=0,f=1;char ch=getchar();
	while (ch<'0'||ch>'9'){if (ch=='-') f=-f;ch=getchar();}
	while (ch<='9'&&ch>='0') ret=ret*10+ch-'0',ch=getchar();
	return ret*f;
}
inline void add(int x,int y){nxt[++tot]=lnk[x];lnk[x]=tot;son[tot]=y;}
inline void push_down(int k){
	if (sum[lc[k]]>sum[rc[k]]) sum[k]=sum[lc[k]],Mx[k]=Mx[lc[k]];
	else if (sum[lc[k]]<sum[rc[k]]) sum[k]=sum[rc[k]],Mx[k]=Mx[rc[k]];
	else sum[k]=sum[rc[k]],Mx[k]=Mx[rc[k]]+Mx[lc[k]];
}
inline void change(int &k,int L,int R){
	if (!k) k=++tot;
	if (L==R){sum[k]++,Mx[k]=x;return;}
	int mid=L+R>>1;
	if (x<=mid) change(lc[k],L,mid);
	else change(rc[k],mid+1,R);
	push_down(k);
}
inline int Merge(int x,int y,int L,int R){
	if (!x||!y) return x^y;
	if (L==R){sum[x]+=sum[y];return x;}
	int mid=L+R>>1;
	lc[x]=Merge(lc[x],lc[y],L,mid);
	rc[x]=Merge(rc[x],rc[y],mid+1,R);
	push_down(x);return x;
}
inline void Get(int x,int fa){
	for (int i=lnk[x];i;i=nxt[i])
	  if (son[i]!=fa) Get(son[i],x),rt[x]=Merge(rt[x],rt[son[i]],1,n);
	if (sum[rt[x]]>0) Ans[x]=Mx[rt[x]];
}
int main(){
	n=read();
	for (int i=1;i<=n;i++) x=read(),change(rt[i],1,n);tot=0;
	for (int i=1;i<n;i++) x=read(),y=read(),add(x,y),add(y,x);
	Get(1,0);
	for (int i=1;i<=n;i++) printf("%d ",Ans[i]);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int M=1e5+9;
struct ss {
	int i,y;
};
int n,m,cnt,mx,ans;
vector<int>e[M];
vector<ss>d[M];
int a[M],L[M],R[M],fa[M],si[M],son[M],kk[M],s[M],su[M],an[M];
int dfs(int x,int f) {
	si[x]=1;
	L[x]=++cnt;
	kk[cnt]=x;
	fa[x]=f;
	for(int i=0; i<e[x].size(); i++) {
		int to=e[x][i];
		if(to==f)continue;
		dfs(to,x);
		si[x]+=si[to];
		if(si[to]>si[son[x]])son[x]=to;
	}
	R[x]=cnt;
}
void del(int x) {
	for(int i=L[x]; i<=R[x]; i++)
		su[a[kk[i]]]--;
	mx=0;
}
void add(int x) {
	for(int i=L[x]; i<=R[x]; i++) {
		su[a[kk[i]]]++;
		if(su[a[kk[i]]]>mx) {
			mx=su[a[kk[i]]];
			ans=a[kk[i]];
		} else if(su[a[kk[i]]]==mx) {
			ans+=a[kk[i]];
		}
	}
}
int dsu(int x) {
	for(int i=0; i<e[x].size(); i++) {
		int to=e[x][i];
		if(to==fa[x]||to==son[x])continue;
		dsu(to);
		del(to);
	}
	if(son[x])dsu(son[x]);
	for(int i=0; i<e[x].size(); i++) {
		int to=e[x][i];
		if(to==fa[x]||to==son[x])continue;
		add(to);
	}
	su[a[x]]++;
	if(su[a[x]]>mx) {
		mx=su[a[x]];
		ans=a[x];
	} else if(su[a[x]]==mx) {
		ans+=a[x];
	}
	an[x]=ans;
}
int main() {
	scanf("%d",&n);
	for(int i=1; i<=n; i++)
		scanf("%d",&a[i]);
	for(int i=1; i<n; i++) {
		int x,y;
		scanf("%d%d",&x,&y);
		e[x].push_back(y);
		e[y].push_back(x);
	}
	dfs(1,0);
	dsu(1);
	for(int i=1; i<n; i++)
		printf("%d ",an[i]);
	printf("%d",an[n]);
	return 0;
}


#include<cstdio>
#include<vector>
using namespace std;
int n,c[100010],cnt[100010],u,v,siz[100010],son[100010],ans[100010],flag,big;
vector<int> e[100010];
void dfs(int x,int las)
{
	siz[x]=1;
	int s=0,b=-1e9;
	for(int i=0;i<e[x].size();++i)
	{
		int y=e[x][i];
		if(y^las)
		{
			dfs(y,x);
			siz[x]+=siz[y];
			if(siz[y]>b)
			{
				b=siz[y];
				s=y;
			}
		}
	}
	son[x]=s;
}
void del(long long x,long long las)
{
	--cnt[c[x]];
	for(long long i=0;i<e[x].size();++i)
	{
		long long y=e[x][i];
		if(y^las)	del(y,x);
	}
}
void cfs(long long x,long long las)
{
	++cnt[c[x]];
	if(cnt[c[x]]>big)
	{
		flag=c[x];
		big=cnt[c[x]];
	}
	else if(cnt[c[x]]==big)	flag+=c[x];
	for(long long i=0;i<e[x].size();++i)
	{
		long long y=e[x][i];
		if(y^las)	cfs(y,x);
	}
}
void count(long long x,long long las)
{
	++cnt[c[x]];
	if(cnt[c[x]]>big)
	{
		flag=c[x];
		big=cnt[c[x]];
	}
	else if(cnt[c[x]]==big)	flag+=c[x];
	for(long long i=0;i<e[x].size();++i)
	{
		long long y=e[x][i];
		if(y^las&&y^son[x])	cfs(y,x);
	}
}
void dsu(long long x,long long las,long long heavy)
{
	for(long long i=0;i<e[x].size();++i)
	{
		long long y=e[x][i];
		if(y^las&&y^son[x])	dsu(y,x,0);
	}
	if(son[x])	dsu(son[x],x,1);
	count(x,las);
	ans[x]=flag;
	if(!heavy)
	{
		del(x,las);
		big=flag=0;
	}
}
void getans(long long x,long long las)
{
	for(long long i=0;i<e[x].size();++i)
	{
		long long y=e[x][i];
		if(y^las)
		{
			getans(y,x);
			ans[x]+=ans[y];
		}
	}
}
int main()
{
	scanf("%lld",&n);
	for(long long i=1;i<=n;++i)	scanf("%lld",&c[i]);
	for(long long i=1;i<n;++i)
	{
		scanf("%lld %lld",&u,&v);
		e[u].push_back(v);
		e[v].push_back(u);
	}
	dfs(1,1);
	dsu(1,1,1);
//	getans(1,1);
	for(long long i=1;i<=n;++i)	printf("%lld ",ans[i]);
	return 0;
}


#include<bits/stdc++.h>
#define ll long long
#define re register
using namespace std;
const int N=2e5+10;
int n;
int c[N];//color
int v[N],nex[N],first[N],tot=1;
inline void add(int x,int y){
	v[++tot]=y;
	nex[tot]=first[x];
	first[x]=tot;
}
inline int read(){
	int x=0;char ch=getchar();
	while(!isdigit(ch))ch=getchar();
	while(isdigit(ch))x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
	return x;
}
ll ans[N],ap[N],mx,sum;//十年OI一场空，不开 long long 见祖宗
//ap表示每种颜色出现几次 mx表示出现最多的次数 sum表示颜色编号和
int sz[N];//子树大小
bool gson[N];//表示一个点是否为重儿子
void getg(int x,int f){//get 子树大小 以及 重儿子
	sz[x]=1;
	int mx=0,p=0;
	for(re int i=first[x];i;i=nex[i]){
		int y=v[i];
		if(y==f)continue;
		getg(y,x);sz[x]+=sz[y];
		if(sz[y]>mx){
			mx=sz[y];
			p=y;
		}
	}if(p)gson[p]=1;
}
void DFS(int x,int f,int p){//暴力遍历子树 p为重儿子 之后需init清空
	//统计答案
	ap[c[x]]++;
	if(ap[c[x]]>mx){
		mx=ap[c[x]];
		sum=c[x];
	}else if(ap[c[x]]==mx)sum+=c[x];
	for(re int i=first[x];i;i=nex[i]){
		int y=v[i];
		if(y==f || y==p)continue;//不要把重儿子也一起遍历了！
		DFS(y,x,p);
	}
}
inline void init(int x,int f){//暴力遍历后清空
	ap[c[x]]--;
	for(re int i=first[x];i;i=nex[i]){
		int y=v[i];
		if(y==f)continue;
		init(y,x);
	}
}
void dfs(int x,int f){//启发式合并关键函数！
	int p=0;//重儿子标记
	for(re int i=first[x];i;i=nex[i]){
		int y=v[i];
		if(y==f)continue;
		if(!gson[y]){//不是重儿子的暴力做
			dfs(y,x);
			init(y,x);
			sum=mx=0;
		}
		else p=y;
	}if(p)dfs(p,x);//重儿子单独特判
	DFS(x,f,p);
	ans[x]=sum;
}
int main(){
	n=read();
	for(re int i=1;i<=n;i++)c[i]=read();
	for(re int i=1;i<n;i++){
		int x=read(),y=read();
		add(x,y),add(y,x);
	}getg(1,0);
	dfs(1,0);
	for(re int i=1;i<=n;i++)
		printf("%lld ",ans[i]);
}


#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=2e5+10;
int n,c[N];//存颜色
int v[N],next[N],head[N],tot;
ll ans[N],ap[N],maxs,sum;//ans表示每个节点的颜色和ap表示每种颜色出现几次 mx表示出现最多的次数 sum表示颜色编号和
int sz[N];
bool zson[N];
void add(int x,int y)
{
    v[++tot]=y;
    next[tot]=head[x];
    head[x]=tot;
}
void bfs1(int x,int f)//bfs序查找重儿子和子树大小
{
    sz[x]=1;
    int mx=0,p=0;
    for(int i=head[x];i;i=next[i])
    {
        int t=v[i];
        if(t==f)
            continue;
        bfs1(t,x);
        sz[x]+=sz[t];
        if(sz[t]>mx)
        {
            p=t;
            mx=sz[t];
        }
    }
    if(p)
        zson[p]=true;
}
void dfs2(int x,int f,int p)////暴力遍历子树 p为重儿子 之后需清空轻儿子贡献
{
    ap[c[x]]++;
    if(ap[c[x]]>maxs)//当前颜色最大
    {
        maxs=ap[c[x]];
        sum=c[x];//计算最多颜色的编号和
    }
    else if(ap[c[x]]==maxs)//还有一样大的
    {
        sum+=c[x];
    }
    for(int i=head[x];i;i=next[i])
    {
        int y=v[i];
        if(y==f||y==p)//不遍历重儿子
            continue;
        dfs2(y,x,p);
    }
}
void init(int x,int f)
{
    ap[c[x]]--;
    for(int i=head[x];i;i=next[i])
    {
        int y=v[i];
        if(y==f)
            continue;
        init(y,x);
    }
}
void bfs3(int x,int f)
{
    int p=0;//标记重孩子
    for(int i=head[x];i;i=next[i])
    {
        int y=v[i];
        if(y==f)
            continue;
        if(!zson[y])//不是重孩子
        {
            bfs3(y,x);
            init(y,x);
            sum=0;
            maxs=0;
        }
        else p=y;
    }
    if(p)
        bfs3(p,x);
    dfs2(x,f,p);//将其他轻孩子合并到重孩子
    ans[x]=sum;
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&c[i]);
    for(int i=1;i<n;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        add(x,y);
        add(y,x);
    }
    bfs1(1,0);
    bfs3(1,0);
    for(int i=1;i<=n;i++)
        cout<<ans[i]<<" ";
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=1e5+10;
struct node
{
     int l,r,mx;
     ll sum;
}tree[100*N];
int col[N];
int h[N],nex[2*N],to[2*N],con=1,id=1,n,rt[N];
ll ans[N];
void add(int a,int b)
{
     nex[con]=h[a];
     h[a]=con;
     to[con++]=b;
}
void up(int now,int ls,int rs)
{
     if(tree[ls].mx==tree[rs].mx)
     {
        //  tree[now].mx=2*tree[ls].mx;
          tree[now].sum=tree[ls].sum+tree[rs].sum;
     }
     else if(tree[ls].mx>tree[rs].mx)
     {
          tree[now].mx=tree[ls].mx;
          tree[now].sum=tree[ls].sum;
     }
     else
     {

          tree[now].mx=tree[rs].mx;
          tree[now].sum=tree[rs].sum;
     }
}
void change(int l,int r,int &now,int x)
{
     if(!now)
     {
          now=id++;
          tree[now].l=tree[now].r=tree[now].mx=tree[now].sum=0;
     }
     if(l==r)
     {
          tree[now].mx++;
          tree[now].sum=x;
          return;
     }
     int mid=(l+r)>>1;
     if(x<=mid)
          change(l,mid,tree[now].l,x);
     else
          change(mid+1,r,tree[now].r,x);
     up(now,tree[now].l,tree[now].r);
}
int add(int l,int r,int a,int b)
{
     if(!a)
     {
          return b;
     }
     else if(!b)
          return a;
     if(l==r)
     {
          tree[a].mx+=tree[b].mx;
          tree[a].sum=tree[b].sum;
          return a;
     }
     int mid=(l+r)>>1;
     tree[a].l=add(l,mid,tree[a].l,tree[b].l);
     tree[a].r=add(mid+1,r,tree[a].r,tree[b].r);
     up(a,tree[a].l,tree[a].r);
     return a;
}
void dfs(int now,int fa)
{
     for(int i=h[now];i;i=nex[i])
     {
          if(to[i]==fa)
               continue;
          dfs(to[i],now);
          rt[now]=add(1,n,rt[now],rt[to[i]]);
     }
     change(1,n,rt[now],col[now]);
     ans[now]=tree[rt[now]].sum;
     return;
}
int main()
{
    // freopen("1.txt","r",stdin);
     cin>>n;
     for(int i=1;i<=n;++i)
     {
          scanf("%d",&col[i]);
     }
     for(int i=1;i<n;++i)
     {
          int a,b;
          scanf("%d%d",&a,&b);
          add(a,b);
          add(b,a);
     }
     dfs(1,0);
     for(int i=1;i<=n;++i)
          printf("%lld ",ans[i]);
     printf("\n");
     return 0;
}


//Head File
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<map>
#include<ctime>
#include<set>
#include<cstdlib>
#include<vector>
#include<cassert>
#include<cmath>
#include<queue>
#include<iostream>
using namespace std;

#define il inline

//Variable
#define ll long long
#define ull unsigned long long
#define db double
#define lb long double
#define ui unsigned int

//Debug
#define B cerr<<"Break Point"<<endl;
#define P(x) cerr<<#x<<' '<<"="<<' '<<(x)<<endl;
#define p(x) cerr<<#x<<' '<<"="<<' '<<(x)<<' ';
#define ml(x) cerr<<"Size of array is "<<x*4/1024/1024<<" MB"<<endl;

//Vector
#define vc vector
#define puf push_front
#define pof pop_front
#define pub push_back
#define pob pop_back
#define vbe(x) x.begin(),x.end()

//Memset
#define ms(x) memset(x,0,sizeof(x))
#define MS(x) memset(x,0x3f3f3f3f,sizeof(x))

//Pair
#define fi first
#define se second

//File

#define fin(x) freopen(x,"r",stdin)
#define fou(x) freopen(x,"w",stdout)
void fio()
{
    #ifndef ONLINE_JUDGE
    freopen("sample.in","r",stdin);
    freopen("sample.out","w",stdout);
    #endif
}
void pti()
{
    double timeuse = clock()*1000.0/CLOCKS_PER_SEC;
    cerr<<"Timeuse "<<timeuse<<"ms"<<endl;
}
void end()
{
    #ifndef ONLINE_JUDGE
    pti();
    #endif
    exit(0);
}

//Inf
#define INF 0x3f3f3f3f
#define LINF ((long long)(0x3f3f3f3f3f3f3f3f))

//IO
#define pc(s) putchar(s)
#define say(s) cout<<s<<endl
namespace io
{
    const int SIZ=55;int que[SIZ],op,qr;char ch;
    template<class I>
    il void gi(I &w)
    {
        ch=getchar(),op=1,w=0;
	    while(!isdigit(ch)){if(ch=='-') op=-1;ch=getchar();}
        while(isdigit(ch)){w=w*10+ch-'0';ch=getchar();}w*=op;
    }
    template<typename T,typename... Args>
    il void gi(T& t,Args&... args){gi(t);gi(args...);}
    template<class I>
    il void print(I w)
    {
        qr=0;if(!w) putchar('0');if(w<0) putchar('-'),w=-w;
	    while(w) que[++qr]=w%10+'0',w/=10;
        while(qr) putchar(que[qr--]);
    }
}
using io::gi;
using io::print;

const int N=1e5+5;

int n,top,cnt;
int siz[N],son[N],head[N],num[N],w[N];
ll ans[N],sum[N];
bool vis[N];
struct edge
{
	int to,nxt;
};
edge e[N<<1];

void add(int x,int y)
{
	e[++cnt].to=y;
	e[cnt].nxt=head[x];
	head[x]=cnt;
}
void link(int x,int y)
{
	add(x,y),add(y,x);
}
void dfs(int x,int fa)
{
	siz[x]=1;
	int maxson=-1;
	for(int i=head[x];i;i=e[i].nxt)
	{
		int v=e[i].to;
		if(v==fa) continue;
		dfs(v,x);
		siz[x]+=siz[v];
		if(siz[v]>maxson) maxson=siz[v],son[x]=v;
	}
}
void calc(int x,int fa,int val)
{
	sum[num[w[x]]]-=w[x];
	num[w[x]]+=val;
	sum[num[w[x]]]+=w[x];
	if(sum[top+1]) ++top;
	else if(top&&!sum[top]) --top;
	for(int i=head[x];i;i=e[i].nxt)
	{
		int v=e[i].to;
		if(v==fa||vis[v]) continue;
		calc(v,x,val);
	}
}
void dsu(int x,int fa,int keep)
{
	for(int i=head[x];i;i=e[i].nxt)
	{
		int v=e[i].to;
		if(v==fa||v==son[x]) continue;
		dsu(v,x,0);
	}
	if(son[x]) dsu(son[x],x,1),vis[son[x]]=true;
	calc(x,fa,1),vis[son[x]]=false;
	ans[x]=sum[top];
	if(!keep) calc(x,fa,-1);
}
int main()
{
	fio();
	gi(n);
	for(int i=1;i<=n;++i) gi(w[i]);
	for(int i=1,x,y;i<=n-1;++i) gi(x,y),link(x,y);
	dfs(1,0);
	dsu(1,0,0);
	for(int i=1;i<=n;++i) print(ans[i]),pc(' ');
	end();
}


#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1e6+10;
struct dd{
	int ys;
	int ans;
	int aans;
	int size;
	vector <int> lj;
	int spson;
};
dd tr[maxn]={};
int cx[maxn],mmax,ssum;
void bfs(int x,int fa)
{
	tr[x].size=1;tr[x].spson=-1;
	for(vector<int>::iterator it=tr[x].lj.begin();it!=tr[x].lj.end();it++)
	{
		int sx=*it;
		if(sx!=fa)
		{
			bfs(sx,x);
			tr[x].size+=tr[sx].size;
			if(tr[x].spson==-1||tr[sx].size>tr[tr[x].spson].size)
				tr[x].spson=sx;
		}
	}
	return;
}
void dfs(int x,int fa,int v,int rt)
{
	cx[tr[x].ys]+=v;
	if(v==1)
	{
		if(cx[tr[x].ys]>cx[tr[rt].ans]) tr[rt].ans=tr[x].ys;
		if(cx[tr[x].ys]>mmax) mmax=cx[tr[x].ys],ssum=tr[x].ys;
		else if(cx[tr[x].ys]==mmax)
			ssum+=tr[x].ys;
	}
	for(vector<int>::iterator it=tr[x].lj.begin();it!=tr[x].lj.end();it++)
	{
		int sx=*it;
		if(sx!=fa)
			dfs(sx,x,v,rt);
	}
}
void qiu(int x,int fa,int op)
{
	for(vector<int>::iterator it=tr[x].lj.begin();it!=tr[x].lj.end();it++)
	{
		int sx=*it;
		if(sx!=fa&&sx!=tr[x].spson)
			qiu(sx,x,1);
	}
	if(tr[x].spson!=-1) qiu(tr[x].spson,x,0);
	if(tr[x].spson!=-1) tr[x].ans=tr[tr[x].spson].ans;
	for(vector<int>::iterator it=tr[x].lj.begin();it!=tr[x].lj.end();it++)
	{
		int sx=*it;
		if(sx!=fa&&sx!=tr[x].spson)
			dfs(sx,x,1,x);
	}
	cx[tr[x].ys]++;
	if(cx[tr[x].ys]>cx[tr[x].ans])
		tr[x].ans=tr[x].ys;
	if(cx[tr[x].ys]>mmax)
		mmax=cx[tr[x].ys],ssum=tr[x].ys;
	else if(cx[tr[x].ys]==mmax)
		ssum+=tr[x].ys;
	tr[x].aans=ssum;
	if(op)
	{

		cx[tr[x].ys]--;
		for(vector<int>::iterator it=tr[x].lj.begin();it!=tr[x].lj.end();it++)
		{
			int sx=*it;
			if(sx!=fa)
				dfs(sx,x,-1,x);
		}
		ssum=0;
		mmax=0;
	}
	return;
}
signed main()
{
	int n;
	scanf("%lld",&n);
	for(int i=1;i<=n;i++)
		scanf("%lld",&tr[i].ys);
	for(int i=1;i<n;i++)
	{
		int f,r;
		scanf("%lld%lld",&f,&r);
		tr[f].lj.push_back(r);
		tr[r].lj.push_back(f);
	}
	bfs(1,0);
	qiu(1,0,0);
	for(int i=1;i<=n;i++)
		printf("%lld ",tr[i].aans);
	return 0;
}


#include <bits/stdc++.h>
using namespace std ;
const int N = 2e5+10,M = N<<5 ;
int n,a[N],tot,head[N],ver[N<<1],Next[N<<1] ;
int rt[N],cnt,lc[M],rc[M],val[M] ; long long sum[M],ans[N] ;
inline void add(int x,int y){
	ver[++tot] = y ; Next[tot] = head[x] ; head[x] = tot ;
}
inline void pushup(int p){
	if(val[lc[p]] > val[rc[p]]){
		val[p] = val[lc[p]] ;
		sum[p] = sum[lc[p]] ;
	}else if(val[lc[p]] < val[rc[p]]){
		val[p] = val[rc[p]] ;
		sum[p] = sum[rc[p]] ;
	}else if(val[lc[p]] == val[rc[p]]){
		val[p] = val[lc[p]] ;
		sum[p] = sum[lc[p]]+sum[rc[p]] ;
	}
}
inline void insert(int &p,int l,int r,int pos){
	if(!p) p = ++cnt ;
	if(l == r){ val[p]++ ;	sum[p] = l ; return ; }
	int mid = (l+r)>>1 ;
	if(pos <= mid) insert(lc[p],l,mid,pos) ;
	else insert(rc[p],mid+1,r,pos) ;
	pushup(p) ;
}
inline int merge(int p,int q,int l,int r){
	if(!p) return q ;
	if(!q) return p ;
	if(l == r){	val[p] += val[q] ; sum[p] = l ; return p ; }
	int mid = (l+r)>>1 ;
	lc[p] = merge(lc[p],lc[q],l,mid) ;
	rc[p] = merge(rc[p],rc[q],mid+1,r) ;
	pushup(p) ;
	return p ;
}
inline void solve(int x,int f){
	for(int i = head[x] ; i ; i = Next[i]){
		int y = ver[i] ;
		if(y == f) continue ;
		solve(y,x) ;
		merge(rt[x],rt[y],1,n) ;
	}
	insert(rt[x],1,n,a[x]) ;
	ans[x] = sum[rt[x]] ;
}
int main(){
	//freopen("in.txt","r",stdin) ;
	ios::sync_with_stdio(false) ;
	cin >> n ;
	for(int i = 1 ; i <= n ; i++) cin >> a[i],rt[i] = ++cnt ;
	for(int i = 1 ; i < n ; i++){ int x,y ; cin >> x >> y ; add(x,y) ; add(y,x) ; }
	solve(1,0) ;
	for(int i = 1 ; i <= n ; i++) printf("%lld ",ans[i]) ;
	return 0 ;
}


#include<bits/stdc++.h>

int main(){
    printf("I tai cai le \n");
}


#pragma-GCC-optimize("-Ofast")
#include<bits/stdc++.h>
#define N 100010
using namespace std;
int read()
{
	int sum=0;
	char ch=getchar();
	while(ch<'0'||ch>'9') ch=getchar();
	while(ch<='9'&&ch>='0')
		{
			sum=sum*10+ch-'0';
			ch=getchar();
		}
	return sum;
}
int col[N];
int n,p;
int head[N],last[N<<1],v[N<<1];
int rt[N];
long long ans[N];
int lson[N<<4],rson[N<<4];
long long sum[N<<5];
int mmax[N<<5];
int tot;
void pushup(int now)
{
	if(!lson[now]&&!rson[now]) return;
	if(!lson[now])
		{
			sum[now]=sum[rson[now]],mmax[now]=mmax[rson[now]];
			return;
		}
	if(!rson[now])
		{
			sum[now]=sum[lson[now]],mmax[now]=mmax[lson[now]];
			return;
		}
	if(mmax[lson[now]]==mmax[rson[now]]) sum[now]=sum[lson[now]]+sum[rson[now]],mmax[now]=mmax[lson[now]];
	else
		{
			if(mmax[lson[now]]>mmax[rson[now]]) sum[now]=sum[lson[now]],mmax[now]=mmax[lson[now]];
			else sum[now]=sum[rson[now]],mmax[now]=mmax[rson[now]];
		}
}
void insert(int &now,int l,int r,int t)
{
	if(!now) now=++tot;
	if(l==r)
		{
			sum[now]=t,mmax[now]++;
			return;
		}
	int mid=l+r>>1;
	if(t<=mid) insert(lson[now],l,mid,t);
	else insert(rson[now],mid+1,r,t);
	pushup(now);
}
int merge(int now,int pre,int l,int r)
{
	if(!now||!pre) return now|pre;
	if(l==r)
		{
			sum[now]=l;
			mmax[now]=mmax[now]+mmax[pre];
			return now;
		}
	int mid=l+r>>1;
	lson[now]=merge(lson[now],lson[pre],l,mid);
	rson[now]=merge(rson[now],rson[pre],mid+1,r);
	pushup(now);
	return now;
}
void add(int a,int b)
{
	v[++p]=b;
	last[p]=head[a];
	head[a]=p;
}
void solve(int a,int father)
{
	for(int i=head[a];i;i=last[i])
		if(v[i]!=father)
			{
				solve(v[i],a);
				rt[a]=merge(rt[a],rt[v[i]],1,n);
			}
	insert(rt[a],1,n,col[a]);
	ans[a]=sum[rt[a]];
}
int main()
{

	n=read();
	for(int i=1;i<=n;i++)
		col[i]=read();
	for(int i=1;i<n;i++)
		{
			int l=read(),r=read();
			add(l,r);
			add(r,l);
		}
	solve(1,0);
	for(int i=1;i<=n;i++)
		cout<<ans[i]<<' ';
	return 0;
 }


#include<iostream>
#include<cstdio>
#include<cmath>
#include<queue>
#include<cstring>
#include<algorithm>
#define lson x<<1
#define rson x<<1|1
#define ll long long
#define rint register int
#define mid  ((L + R) >> 1)
using namespace std;
template <typename xxx> inline void read(xxx &x) {
	char c = getchar(),f = 1;x = 0;
	for(;c ^ '-' && !isdigit(c);c = getchar());
	if(c == '-') c = getchar(),f = -1;
	for(;isdigit(c);c = getchar()) x = (x<<1) + (x<<3) + (c ^ '0');
	x *= f;
}
template<typename xxx>void print(xxx x)
{
    if(x<0){putchar('-');x=-x;}
    if(x>9) print(x/10);
    putchar(x%10+'0');
}
const int maxn = 100010;
const int inf = 0x7fffffff;
const int mod = 1e9 + 7;
struct edge{
	int to,last;
}e[maxn<<1];
int head[maxn],tot;
void add(int from,int to) {
	++tot;
	e[tot].to = to;
	e[tot].last = head[from];
	head[from] = tot;
}
int siz[maxn],son[maxn];
void dfs(int x,int da) {//重链剖分
	siz[x] = 1;
	for(rint i = head[x]; i; i = e[i].last) {
		if(e[i].to == da) continue;
		dfs(e[i].to,x);
		siz[x] += siz[e[i].to];
		if(son[x] == 0 || siz[son[x]] < siz[e[i].to]) son[x] = e[i].to;
	}
	return ;
}
int cnt[maxn];
ll sum,ans[maxn],Mx,Tem,col[maxn];
void deal(int x,int da,int val) {
	cnt[col[x]] +=val;//因题而异
	if(cnt[col[x]] > Mx) Mx = cnt[col[x]],sum = col[x];
	else if(cnt[col[x]] == Mx) sum += col[x];
	for(rint i = head[x]; i; i = e[i].last) {
		if(e[i].to == da || e[i].to == Tem) continue;
		deal(e[i].to,x,val);
	}
}
void ddfs(int x,int da,int opt) {
	for(rint i = head[x]; i; i = e[i].last) {
		if(e[i].to == da) continue;
		if(e[i].to ^ son[x]) ddfs(e[i].to,x,0);//暴力统计轻边的贡献，opt = 0表示递归完成后要消除对该点的影响
	}
	if(son[x]) ddfs(son[x],x,1),Tem = son[x];//统计重儿子的贡献，不消除影响
	deal(x,da,1);Tem = 0;//暴力统计所有轻儿子的贡献
	ans[x] = sum;//更新答案
	if(!opt) deal(x,da,-1),sum = 0,Mx = 0;//如果需要删除贡献的话就删掉
	return ;
}
int n;
int main()
{
	read(n);
	for(rint i = 1;i <= n; ++i) read(col[i]);
	for(rint i = 2;i <= n; ++i) {
		int x,y;
		read(x);read(y);
		add(x,y);add(y,x);
	}
	dfs(1,0);
	ddfs(1,0,0);
	for(rint i = 1;i <= n; ++i) print(ans[i]),putchar(' ');
	return 0;
}
/*

*/


#include<bits/stdc++.h>
using namespace std;
int a=0;
vector<int> elements[100005];
int length[100005];
int gg[100005];
int sum[100005][2];
int dfs(int x,int sign)
{
	int y=0;
	if(gg[x]=sign)
	{
		y++;
	}
	for(int i=0;i<length[x];i++)
	{
		y+=dfs(elements[x][i],sign);
	}
	return y;
}
void dfsx(int x,int sign)
{
	sum[x][0]=max(dfs(x,sign),sum[x][0]);
	for(int i=0;i<length[x];i++)
	{
		dfsx(elements[x][i],sign);
	}
}

int main()
{
	cin>>a;
	for(int i=1;i<=a;i++)
	{
		cin>>gg[i];
	}
	int k,l;
	for(int i=0;i<a;i++)
	{
		cin>>k>>l;
		length[k]=length[k]+1;
		elements[k].push_back(l);
	}
	for(int i=1;i<=a;i++)
	{
		dfsx(1,i);
	}
	int maxs=0;
	int ans=0;
	for(int i=1;i<=a;i++)
	{
		cout<<sum[i][0];
	}
}


#include <bits/stdc++.h>

using namespace std;

const int N = 100010;

int n, fa[N], col[N] , size[N], h_son[N];
vector <int> son[N];

map <int , int > times[N];
int ans[N], maxn[N];

void dfs1(int wz, int fat)
{
	size[wz] = 1, fa[wz] = fat;

	for(int k = 0; k < (int )son[wz].size(); k++)
	{
		int to = son[wz][k];

		if(to != fat)
		{
			dfs1(to, wz), size[wz] += size[to];

			if(size[to] > size[h_son[wz]])
				h_son[wz] = to;
		}
	}
}

map <int , int > :: iterator it;

void Insert(int wz, int key, int time)
{
	times[wz][key] += time;
	if(times[wz][key] > maxn[wz])
	{
		maxn[wz] = times[wz][key];
		ans[wz] = key;
	}
	else if(times[wz][key] == maxn[wz])
		ans[wz] += key;
}

void dfs2(int wz)
{
	for(int k = 0; k < (int )son[wz].size(); k++)
		if(son[wz][k] != fa[wz]) dfs2(son[wz][k]);

	times[wz] = times[h_son[wz]], times[h_son[wz]].clear() ;
	ans[wz] = ans[h_son[wz]], maxn[wz] = maxn[h_son[wz]];
	for(int k = 0; k < (int )son[wz].size(); k++)
	{
		int to = son[wz][k];
		if(to != fa[wz] && to != h_son[wz])
			for(it = times[to].begin() ; it != times[to].end(); ++it)
			{
				int wz0 = it -> first;

				Insert(wz, wz0, times[to][wz0]);
			}
	}

	Insert(wz, col[wz], 1);
}

int main()
{
	scanf("%d", &n);
	for(register int k = 1; k <= n; k++)
		scanf("%d", &col[k]);
	for(register int k = 1; k < n; k++)
	{
		int a, b;
		scanf("%d %d", &a, &b);

		son[a].push_back(b);
		son[b].push_back(a);
	}

	dfs1(1, 0), dfs2(1);

	for(register int k = 1; k <= n; k++)
		printf("%d ", ans[k]);

	return 0;
}


#include<cstdio>
#include<vector>
#include<algorithm>

using namespace std;

int c[200000];

struct dat
{
	int ans;long long pos;
};
dat max(dat a,dat b)
{
	dat c;c.ans=c.pos=0;c.ans=max(a.ans,b.ans);if(a.ans==c.ans)c.pos+=a.pos;if(b.ans==c.ans)c.pos+=b.pos;
	return c;
}

struct SegmentTree
{
	struct nd
	{
		int l,r,lc,rc;dat x;
	}t[1000000];int used;
	int new_node(int l,int r){++used;t[used].l=l,t[used].r=r;t[used].x.ans=0;return used;}
	void add(int pos,int k)
	{
		if(t[k].l==t[k].r){t[k].x.ans++,t[k].x.pos=t[k].l;return;}
		int mid=(t[k].l+t[k].r)>>1;
		if(!t[k].lc)t[k].lc=new_node(t[k].l,mid);if(!t[k].rc)t[k].rc=new_node(mid+1,t[k].r);
		if(pos<=mid)add(pos,t[k].lc);else add(pos,t[k].rc);
		t[k].x=max(t[t[k].lc].x,t[t[k].rc].x);
	}
	int merge(int x,int y)
	{
		if(!x||!y)return x|y;
		if(t[x].l==t[x].r)
		{
			t[x].x.ans+=t[y].x.ans;t[x].x.pos=t[x].l;return x;
		}
		t[x].lc=merge(t[x].lc,t[y].lc),t[x].rc=merge(t[x].rc,t[y].rc);
		t[x].x=max(t[t[x].lc].x,t[t[x].rc].x);return x;
	}
}T;

int rt[200000];

vector<int> ed[200000];

long long ans[200000];

void dfs(int u,int f)
{
	for(int i=0;i<ed[u].size();i++)
	{
		int v=ed[u][i];if(v==f)continue;
		dfs(v,u);rt[u]=T.merge(rt[u],rt[v]);
	}
	ans[u]=T.t[rt[u]].x.pos;
}

int main()
{
	int n=0;scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d",&c[i]);
	for(int i=1;i<=n;i++){rt[i]=T.new_node(1,n);T.add(c[i],rt[i]);}
	for(int i=1,x=0,y=0;i<n;i++)
	{
		scanf("%d%d",&x,&y);ed[x].push_back(y),ed[y].push_back(x);
	}
	dfs(1,0);for(int i=1;i<=n;i++)printf("%lld ",ans[i]);return 0;
}


#include<bits/stdc++.h>
using namespace std;
int read(){
	char s;
	int x=0,f=1;
	s=getchar();
	while(s<'0'||s>'9'){
		if(s=='-')f=-1;
		s=getchar();
	}
	while(s>='0'&&s<='9'){
		x*=10;
		x+=s-'0';
		s=getchar();
	}
	return x*f;
}
int n;
const int N=1e5+5;
int c[N];
vector<int>v[N];
int sz[N],big[N];
void go(int x,int fa){
	sz[x]=1;
	for(int i=0;i<v[x].size();i++){
		int k=v[x][i];
		if(k==fa)continue;
		go(k,x);
		sz[x]+=sz[k];
		if(sz[k]>sz[big[x]]){
			big[x]=k;
		}
	}
}
long long ans[N];
int cnt[N]; //记录颜色出现次数
int mc;//出现最多的颜色的出现次数
long long now;//出现最多次的颜色和
void add(int x,int fa,int sum,int bg=0){
	cnt[c[x]]+=sum;
	if(cnt[c[x]]>mc){
		mc=cnt[c[x]];
		now=c[x];
	}
	else if(cnt[c[x]]==mc){
		now+=(long long)c[x];
	}
	for(int i=0;i<v[x].size();i++){
		int k=v[x][i];
		if(k==fa||k==bg)continue;
		add(k,x,sum,bg);
	}
}
void dfs(int x,int fa){
	for(int i=0;i<v[x].size();i++){
		int k=v[x][i];
		if(k==fa||k==big[x])continue;
		dfs(k,x);
	}
	mc=0;
	now=0;
	if(big[x])dfs(big[x],x);
	add(x,fa,1,big[x]);
	ans[x]=now;
	if(x!=big[fa]){
		add(x,fa,-1,0);
	}
}
int main(){
	n=read();
	for(int i=1;i<=n;i++){
		c[i]=read();
	}
	for(int i=1;i<n;i++){
		int a,b;
		a=read(),b=read();
		v[a].push_back(b);
		v[b].push_back(a);
	}
	go(1,0);
	dfs(1,0);
	for(int i=1;i<=n;i++){
		printf("%lld ",ans[i]);
	}
}


#include<bits/stdc++.h>
#define maxn 200005
#define maxe 15000005
using namespace std;
int rt[maxe],n,a[maxn],x,y,Ans[maxn],nxt[maxn],lnk[maxn],son[maxn],tot,sum[maxe],Mx[maxe],lc[maxe],rc[maxe];
inline int read(){
	int ret=0,f=1;char ch=getchar();
	while (ch<'0'||ch>'9'){if (ch=='-') f=-f;ch=getchar();}
	while (ch<='9'&&ch>='0') ret=ret*10+ch-'0',ch=getchar();
	return ret*f;
}
inline void add(int x,int y){nxt[++tot]=lnk[x];lnk[x]=tot;son[tot]=y;}
inline void push_down(int k){
	if (sum[lc[k]]>sum[rc[k]]) sum[k]=sum[lc[k]],Mx[k]=Mx[lc[k]];
	else if (sum[lc[k]]<sum[rc[k]]) sum[k]=sum[rc[k]],Mx[k]=Mx[rc[k]];
	else sum[k]=sum[rc[k]],Mx[k]=Mx[rc[k]]+Mx[lc[k]];
}
inline void change(int &k,int L,int R){
	if (!k) k=++tot;
	if (L==R){sum[k]++,Mx[k]=x;return;}
	int mid=L+R>>1;
	if (x<=mid) change(lc[k],L,mid);
	else change(rc[k],mid+1,R);
	push_down(k);
}
inline int Merge(int x,int y,int L,int R){
	if (!x||!y) return x^y;
	if (L==R){sum[x]+=sum[y];return x;}
	int mid=L+R>>1;
	lc[x]=Merge(lc[x],lc[y],L,mid);
	rc[x]=Merge(rc[x],rc[y],mid+1,R);
	push_down(x);return x;
}
inline void Get(int x,int fa){
	for (int i=lnk[x];i;i=nxt[i])
	  if (son[i]!=fa) Get(son[i],x),rt[x]=Merge(rt[x],rt[son[i]],1,n);
	if (sum[rt[x]]>0) Ans[x]=Mx[rt[x]];
}
int main(){
	n=read();
	for (int i=1;i<=n;i++) x=read(),change(rt[i],1,n);tot=0;
	for (int i=1;i<n;i++) x=read(),y=read(),add(x,y),add(y,x);
	Get(1,0);
	for (int i=1;i<=n;i++) printf("%d ",Ans[i]);
	return 0;
}


#include<bits/stdc++.h>
#define maxn 300005
#define maxe 20000005
using namespace std;
int rt[maxe],n,a[maxn],x,y,Ans[maxn],nxt[maxn],lnk[maxn],son[maxn],tot,sum[maxe],Mx[maxe],lc[maxe],rc[maxe];
inline int read(){
	int ret=0,f=1;char ch=getchar();
	while (ch<'0'||ch>'9'){if (ch=='-') f=-f;ch=getchar();}
	while (ch<='9'&&ch>='0') ret=ret*10+ch-'0',ch=getchar();
	return ret*f;
}
inline void add(int x,int y){nxt[++tot]=lnk[x];lnk[x]=tot;son[tot]=y;}
inline void push_down(int k){
	if (sum[lc[k]]>sum[rc[k]]) sum[k]=sum[lc[k]],Mx[k]=Mx[lc[k]];
	else if (sum[lc[k]]<sum[rc[k]]) sum[k]=sum[rc[k]],Mx[k]=Mx[rc[k]];
	else sum[k]=sum[rc[k]],Mx[k]=Mx[rc[k]]+Mx[lc[k]];
}
inline void change(int &k,int L,int R){
	if (!k) k=++tot;
	if (L==R){sum[k]++,Mx[k]=x;return;}
	int mid=L+R>>1;
	if (x<=mid) change(lc[k],L,mid);
	else change(rc[k],mid+1,R);
	push_down(k);
}
inline int Merge(int x,int y,int L,int R){
	if (!x||!y) return x^y;
	if (L==R){sum[x]+=sum[y];return x;}
	int mid=L+R>>1;
	lc[x]=Merge(lc[x],lc[y],L,mid);
	rc[x]=Merge(rc[x],rc[y],mid+1,R);
	push_down(x);return x;
}
inline void Get(int x,int fa){
	for (int i=lnk[x];i;i=nxt[i])
	  if (son[i]!=fa) Get(son[i],x),rt[x]=Merge(rt[x],rt[son[i]],1,n);
	if (sum[rt[x]]>0) Ans[x]=Mx[rt[x]];
}
int main(){
	n=read();
	for (int i=1;i<=n;i++) x=read(),change(rt[i],1,n);tot=0;
	for (int i=1;i<n;i++) x=read(),y=read(),add(x,y),add(y,x);
	Get(1,0);
	for (int i=1;i<=n;i++) printf("%d ",Ans[i]);
	return 0;
}


#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<map>
#include<vector>
using namespace std;

const int maxn=100000+5;

inline int read()
{
	int x=0,f=1;
	char c=getchar();
	while(c<'0'||c>'9')
	{
		if(c=='-')
			f=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9')
	{
		x=x*10+c-'0';
		c=getchar();
	}
	return x*f;
}

int val[maxn];
struct node{
	int last,to;
}tree[maxn*2];
int s=0,head[maxn];

void add(int from,int to)
{
	tree[++s].to=to;
	tree[s].last=head[from];
	head[from]=s;
}

int son[maxn],Size[maxn];
void dfs1(int from,int to)
{
	Size[to]=1;
	int maxx=-0x3f3f3f3f;
	for(int i=head[to];i;i=tree[i].last)
	{
		int k=tree[i].to;
		if(k==from)
			continue;
		dfs1(to,k);
		if(Size[k]>maxx)
		{
			son[to]=k;
			maxx=Size[k];
		}
	}
}

struct DS{
	int ans;
	long long sum;
	map<int,int> M;
	vector<int> P;
	void Insert(int x,int y)
	{
		if(!M[x])
			P.push_back(x);
		M[x]+=y;
		if(ans==-1||M[x]>ans)
		{
			ans=M[x];
			sum=x;
		}
		else if(M[x]==ans)
			sum+=x;
	}
}record[maxn];

void dfs2(int from,int to)
{
	if(!son[to])
	{
		record[to].ans=-1;
		record[to].Insert(val[to],1);
		return;
	}
	for(int i=head[to];i;i=tree[i].last)
	{
		int k=tree[i].to;
		if(k==from)
			continue;
		dfs2(to,k);
	}
	record[to]=record[son[to]];
	record[to].Insert(val[to],1);
	for(int i=head[to];i;i=tree[i].last)
	{
		int k=tree[i].to;
		if(k==from||k==son[to])
			continue;
		for(int i=0;i<record[k].P.size();i++)
		{
			int t=record[k].P[i];
			record[to].Insert(t,record[k].M[t]);
		}
	}
}

int main()
{
	int n=read();
	for(int i=1;i<=n;i++)
		val[i]=read();
	int u,v;
	for(int i=1;i<=n-1;i++)
	{
		u=read(); v=read();
		add(u,v); add(v,u);
	}
	dfs1(0,1); dfs2(0,1);
	for(int i=1;i<=n;i++)
		cout<<record[i].sum<<" ";
	cout<<endl;
	return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=100005;
long long xnt[N],ans[N];
int p[N],noww[2*N],goal[2*N];
int val[N],siz[N],imp[N],vis[N];
int n,m,t1,t2,cnt;
long long maxx,sum;
void link(int f,int t)
{
	noww[++cnt]=p[f];
	goal[cnt]=t,p[f]=cnt;
}
void DFS(int nde,int fth)
{
	int tmp=0; siz[nde]=1;
	for(int i=p[nde];i;i=noww[i])
		if(goal[i]!=fth)
		{
			DFS(goal[i],nde);
			siz[nde]+=siz[goal[i]];
			if(siz[goal[i]]>tmp)
				tmp=siz[goal[i]],imp[nde]=goal[i];
		}
}
void Change(int nde,int fth,int tsk)
{
	int v=val[nde]; xnt[v]+=tsk;
	if(xnt[v]>=maxx)
		(xnt[v]>maxx)?maxx=xnt[v],sum=v:sum+=v;
	for(int i=p[nde];i;i=noww[i])
		if(goal[i]!=fth&&!vis[goal[i]])
			Change(goal[i],nde,tsk);
}
void Solve(int nde,int fth,int usd)
{
	for(int i=p[nde];i;i=noww[i])
		if(goal[i]!=fth&&goal[i]!=imp[nde])
			Solve(goal[i],nde,0);
	if(imp[nde])
		Solve(imp[nde],nde,1),vis[imp[nde]]=true;
	Change(nde,fth,1),ans[nde]=sum;
	if(imp[nde]) vis[imp[nde]]=false;
    if(!usd) Change(nde,fth,-1),maxx=sum=0;
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d",&val[i]);
	for(int i=1;i<n;i++)
	{
		scanf("%d%d",&t1,&t2);
		link(t1,t2),link(t2,t1);
	}
	DFS(1,0); Solve(1,0,0);
	for(int i=1;i<=n;i++)
		printf("%lld ",ans[i]);
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

typedef long long ll;
const int E = 100000 + 11;

int n;
ll c[E];
struct Node {
	int to, next;
} edge[E << 1];
int head[E];
struct Segment_Tree {
	int l, r, maxn;
	ll sum;
} tr[E << 2];
int rt[E];
ll ans[E];
int cnt = 1, tot = 0;

void add_edge(int u, int v) {
	cnt++;
	edge[cnt].to = v;
	edge[cnt].next = head[u];
	head[u] = cnt;
}

void push_up(int p) {
	if (tr[tr[p].l].maxn > tr[tr[p].r].maxn) {
		tr[p].maxn = tr[tr[p].l].maxn;
		tr[p].sum = tr[tr[p].l].sum;
	}
	else if (tr[tr[p].l].maxn < tr[tr[p].r].maxn) {
		tr[p].maxn = tr[tr[p].r].maxn;
		tr[p].sum = tr[tr[p].r].sum;
	}
	else {
		tr[p].maxn = tr[tr[p].l].maxn;
		tr[p].sum = tr[tr[p].l].sum + tr[tr[p].r].sum;
	}
}

void update(int p, int l, int r, int x, int k1, ll k2) {
	if (l == r) {
		tr[p].maxn += k1;
		tr[p].sum = k2;
		return ;
	}
	int mid = (l + r) >> 1;
	if (x <= mid) {
		if (!tr[p].l) tr[p].l = ++tot;
		update(tr[p].l, l, mid, x, k1, k2);
	}
	else {
		if (!tr[p].r) tr[p].r = ++tot;
		update(tr[p].r, mid + 1, r, x, k1, k2);
	}
	push_up(p);
}

int merge(int p, int q, int l, int r) {
	if (!p || !q) return p + q;
	if (l == r) {
		tr[p].maxn += tr[q].maxn;
		return p;
	}
	int mid = (l + r) >> 1;
	tr[p].l = merge(tr[p].l, tr[q].l, l, mid);
	tr[p].r = merge(tr[p].r, tr[q].r, mid + 1, r);
	push_up(p);
	return p;
}

void dfs(int u, int fa) {
	for (int i = head[u]; i; i = edge[i].next) {
		int v = edge[i].to;
		if (v == fa) continue;
		dfs(v, u);
		merge(rt[u], rt[v], 1, n);
	}
	update(rt[u], 1, n, c[u], 1, c[u]);
	ans[u] = tr[rt[u]].sum;
}

int main() {
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) scanf("%lld", &c[i]);
	for (int i = 1; i < n; i++) {
		int u, v;
		scanf("%d%d", &u, &v);
		add_edge(u, v);
		add_edge(v, u);
	}

	for (int i = 1; i <= n; i++) rt[i] = ++tot;

	dfs(1, 0);

	for (int i = 1; i <= n; i++) printf("%lld ", ans[i]);
	printf("\n");

	return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#define ll long long
using namespace std;
const int N = 1e5+10;
const int E = 20;
int n, c[N], point[N];
struct EDGE{
	int nxt, v;
}edge[N<<1];
int root[N], idx;
struct NODE{
	int ls, rs, val;
	ll sum;
	NODE(){
		lson = rson = val = sum = 0;
	}
}node[N*E];

inline void add_edge(int u, int v, int e)
{
	edge[e] = (EDGE){point[u], v};
	point[u] = e;
}

void pushUp(int now)
{
	int lson = node[now].lson;
	int rson = node[now].rson;
	if (node[lson].val != node[rson].val){
		if (node[lson].val < node[rson].val)
			swap(lson, rson);
		node[now].val = node[lson].val;
		node[now].sum = node[lson].sum;
	}
	else{
		node[now].val = node[lson].val;
		node[now].sum = node[lson].sum+node[rson].sum;
	}
}

void Update(int &now, int l, int r, int w)
{
	if (!now) now = ++ idx;
	if (l == r){
		++ node[now].val;
		node[now].sum = w;
		return;
	}
	int mid = (l+r)>>1;
	if (w <= mid) Update(node[now].lson, l, mid, w);
	else Update(node[now].rson, mid+1, r, w);
	pushUp(now);
}

int Merge(int now, int son, int l, int r)
{
	if (!now) return son;
	if (!son) return now;
	if (l == r){
		node[now].val += node[son].val;
		return now;
	}
	int mid = (l+r)>>1;
	node[now].lson = Merge(node[now].lson, node[son].lson, l, mid);
	node[now].rson = Merge(node[now].rson, node[son].rson, mid+1, r);
	pushUp(now);
	return now;
}

void Dfs(int u, int fa)
{
	Update(root[u], 1, n, c[u]);
	for (int i = point[u]; i != -1; i = edge[i].nxt){
		int v = edge[i].v;
		if (v == fa) continue;
		Dfs(v, u);
		Merge(root[u], root[v], 1, n);
	}
}

int main()
{
	scanf("%d", &n);
	for (int i = 1; i <= n; ++ i)
		scanf("%d", &c[i]);
	memset(point, -1, sizeof(point));
	for (int i = 0, sz = n-1; i < sz; ++ i){
		int x, y;
		scanf("%d%d", &x, &y);
		add_edge(x, y, i<<1);
		add_edge(y, x, i<<1^1);
	}
	memset(root, 0, sizeof(root));
	idx = 0;
	Dfs(1, 0);
	for (int i = 1; i <= n; ++ i)
		printf("%lld ", node[root[i]].sum);
	return 0;
}


#include <cstdio>
#include <algorithm>
using namespace std;
#define maxn 100100
#define ll long long
int n;
int fir[maxn], nxt[maxn * 2], vv[maxn * 2];
int tot = 0;
void add(int u, int v)
{
	nxt[++tot] = fir[u];
	fir[u] = tot;
	vv[tot] = v;
}
int cnt = 0;
int root[maxn], col[maxn];
int lz[maxn * 17 * 2], rz[maxn * 17 * 2], sum[maxn * 17 * 2];
ll ans[maxn * 17 * 2];
void pushup(int a)
{
	if(sum[lz[a]] < sum[rz[a]])
	{
		sum[a] = sum[rz[a]];
		ans[a] = ans[rz[a]];
	}
	if(sum[lz[a]] > sum[rz[a]])
	{
		sum[a] = sum[lz[a]];
		ans[a] = ans[lz[a]];
	}
	if(sum[lz[a]] == sum[rz[a]])
	{
		sum[a] = sum[lz[a]];
		ans[a] = ans[lz[a]] + ans[rz[a]];
	}
	return;
}
int merge(int a, int b, int l, int r)
{
	if(a == 0) return b;
	if(b == 0) return a;
	if(l == r)
	{
		sum[a] += sum[b];
		ans[a] = l;
		return a;
	}
	int mid = (l + r) >> 1;
	lz[a] = merge(lz[a], lz[b], l, mid);
	rz[a] = merge(rz[a], rz[b], mid + 1, r);
	pushup(a);
	return a;
}
void update(int &a, int l, int r, int v)
{
	if(!a) a = ++cnt;
	int mid = (l + r) >> 1;
	if(l == r)
	{
		sum[a] += 1;
        ans[a] = l;
		return;
	}
	if(mid >= v) update(lz[a], l, mid, v);
	if(mid < v) update(rz[a], mid + 1, r, v);
	pushup(a);
	return;
}
void dfs(int u, int fa)
{
	for(int i = fir[u]; i; i = nxt[i])
	{
		int v = vv[i];
		if(v == fa) continue;
		dfs(v, u);
		merge(root[u], root[v], 1, 100000);
	}
	update(root[u], 1, 100000, col[u]);
    ans[u] = ans[root[u]];
}
int main()
{
	scanf("%d", &n); cnt = n;
	for(int i = 1; i <= n; i++)
	{
		scanf("%d", &col[i]); root[i] = i;
	}
	for(int i = 1; i < n; i++)
	{
		int u, v;
		scanf("%d%d", &u, &v);
		add(u, v); add(v, u);
	}
	dfs(1, 0);
	for(int i = 1; i <= n; i++) printf("%lld ", ans[i]);
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define I inline
#define ll long long
#define gc ch=getchar()
template <class T> void read(T &s){
    s=0;T f=1;char gc;
    while(ch<'0' || ch>'9'){if(ch=='-')f=-1;gc;}
    while(ch>='0' && ch<='9'){s=s*10+ch-'0';gc;}
    s*=f;
}
void put(ll s){
    if(s<0)putchar('-'),s=-s;
    if(s>9)put(s/10);
    putchar(s%10+'0');
}

const int N = 1e5+10;

int n;

struct nde{
    int u,next;
}edge[N<<1];
int head[N],cnt=0;
I void addedge(int x,int y){edge[++cnt]=(nde){y,head[x]};head[x]=cnt;}

namespace TOR{
    int son[N],siz[N],f[N],dep[N];
    int color[N];ll ans[N];
    struct ARR{
        int t[N],a[N],tim,maxsize;
        ll sum;
        void clear(){tim++;maxsize=0;sum=0;}
        void insert(int o){if(t[o]!=tim){t[o]=tim;a[o]=0;} a[o]++; if(a[o]>maxsize){maxsize=a[o];sum=0;}if(a[o]==maxsize)sum+=o;}
        ll ans(){return sum;}
    }A;
    void dfs1(int u,int fa){
        f[u]=fa;dep[u]=dep[fa]+1;siz[u]=1;
        for(int i=head[u];i;i=edge[i].next){
            int to=edge[i].u;
            if(to==fa)continue;
            dfs1(to,u);
            siz[u]+=siz[to];
            if(siz[son[u]] < siz[to])son[u]=to;
        }
    }
    void dfs(int u){
        A.insert(color[u]);
        for(int i=head[u];i;i=edge[i].next){
            int to=edge[i].u;
            if(to==f[u])continue;
            dfs(to);
        }
    }
    void dfs2(int u){
        if(!son[u]){
            ans[u]=color[u];
            A.insert(color[u]);
            return;
        }
        for(int i=head[u];i;i=edge[i].next){
            int to=edge[i].u;
            if(to==son[u] || to==f[u])continue;
            dfs2(to);A.clear();
        }
        dfs2(son[u]);
        for(int i=head[u];i;i=edge[i].next){
            int to=edge[i].u;
            if(to==son[u] || to==f[u])continue;
            dfs(to);
        }
        A.insert(color[u]);
        ans[u]=A.ans();
    }
}
using namespace TOR;
int main(){
    read(n);
    for(int i=1;i<=n;++i)read(color[i]);
    int x,y;
    for(int i=1;i<n;++i){read(x);read(y);addedge(x,y);addedge(y,x);}
    dfs1(1,0);dfs2(1);
    for(int i=1;i<=n;++i)put(ans[i]),putchar(' ');
    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#define I inline
using namespace std;
typedef long long ll;
const int N=100005;
int ov[N],co[N];
struct edge{int v,nt;}e[N<<1];
int h[N],cnt=0;
I void add(int u,int v){e[++cnt]=(edge){v,h[u]};h[u]=cnt;e[++cnt]=(edge){u,h[v]};h[v]=cnt;}
int n,m,x,y,na;
ll ans[N],res=0;
int sz[N],son[N],skp[N];
void dfs1(int u,int fa){
	for(int i=h[u];i;i=e[i].nt){
		int v=e[i].v;if(v==fa)continue;
		sz[v]=1;dfs1(v,u);sz[u]+=sz[v];
		if(sz[son[u]]<sz[v])son[u]=v;
	}
}
void cal(int u,int fa,int d){
	co[ov[u]]+=d;
	if(d>0&&co[ov[u]]>=na){
		if(co[ov[u]]>na){na=co[ov[u]];res=0;}
		res+=ov[u];
	}
	for(int i=h[u];i;i=e[i].nt){
		int v=e[i].v;if(v==fa||skp[v])continue;
		cal(v,u,d);
	}
}
void dfs(int u,int fa,int kp){
	for(int i=h[u];i;i=e[i].nt){
		int v=e[i].v;if(v==fa||v==son[u])continue;
		dfs(v,u,0);
	}
	if(son[u])dfs(son[u],u,1),skp[son[u]]=1;
	cal(u,fa,1);ans[u]=res;
	if(son[u])skp[son[u]]=0;
	if(!kp)cal(u,fa,-1),res=na=0;
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++)scanf("%d",&ov[i]);
	for(int i=1;i<n;i++){scanf("%d%d",&x,&y),add(x,y);}
	sz[1]=1;dfs1(1,0);
	dfs(1,0,0);
	for(int i=1;i<=n;i++)printf("%I64d ",ans[i]);
	return 0;
}


#include<bits/stdc++.h>
#define lc(x) seg[x].l
#define rc(x) seg[x].r
using namespace std;

const int maxn=1e5+7;
int c[maxn],rt[maxn],cnt,n;
long long ans[maxn];
vector<int> to[maxn];

struct node {
	int l,r,cnt;
	long long ans;
}seg[maxn*40];

void update(int x)
{
	if(seg[lc(x)].cnt==seg[rc(x)].cnt) {
		seg[x].cnt=seg[lc(x)].cnt;
		seg[x].ans=seg[lc(x)].ans+seg[rc(x)].ans;
	}
	else if(seg[lc(x)].cnt>seg[rc(x)].cnt) {
		seg[x].cnt=seg[lc(x)].cnt;
		seg[x].ans=seg[lc(x)].ans;
	}
	else {
		seg[x].cnt=seg[rc(x)].cnt;
		seg[x].ans=seg[rc(x)].ans;
	}
}

int merge(int u,int v,int l,int r)
{
	if(!u||!v) return u+v;
	if(l==r) {
		seg[u].cnt+=seg[v].cnt;
		seg[u].ans=l;
		return u;
	}
	int mid=(l+r)>>1;
	lc(u)=merge(lc(u),lc(v),l,mid);
	rc(u)=merge(rc(u),rc(v),mid+1,r);
	update(u);
	return u;
}

void modify(int &nd,int l,int r,int pos,int d)
{
	if(!nd) nd=++cnt;
	if(l==r) {
		seg[nd].cnt+=d;
		seg[nd].ans=l;
		return ;
	}
	int mid=(l+r)>>1;
	if(pos<=mid) modify(lc(nd),l,mid,pos,d);
	else modify(rc(nd),mid+1,r,pos,d);
	update(nd);
}

void dfs(int x,int f)
{
	for(int i=0;i<to[x].size();++i) {
		int t=to[x][i];
		if(t==f) continue;
		dfs(t,x);
		merge(rt[x],rt[t],1,100000);
	}
	modify(rt[x],1,100000,c[x],1);
	ans[x]=seg[rt[x]].ans;
}

int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;++i) {
		scanf("%d",&c[i]);
		rt[i]=i;
		cnt++;
	}

	for(int i=1;i<n;++i) {
		int u,v;
		scanf("%d %d",&u,&v);
		to[u].push_back(v);
		to[v].push_back(u);
	}
	dfs(1,0);
	for(int i=1;i<=n;++i) printf("%lld ",ans[i]);
}


#include<bits/stdc++.h>
using namespace std;
int v[1000001];//访问
int s[1000001];//颜色数量
int tot,g[1000001],son[1000001],maxson[1000001],c[1000001];
long long ans[1000001];
long long sum,temp,maxi;
int read(){
 int k=0,f=0;char c=getchar();for(;c<'0'||c>'9';c=getchar())if(c=='-')f=1;
 for(;c<='9'&&c>='0';c=getchar())k=(k<<3)+(k<<1)+c-'0';return  f?-k:k;
}
struct edge{
	int next,to;
}e[1000001];
void add(int a,int b)
{
	tot++;
	e[tot].next=g[a];
	e[tot].to=b;
	g[a]=tot;
}
int dfs1(int x,int father)
{
	son[x]=1;
	for(int i=g[x];i;i=e[i].next)
	{
		if(e[i].to==father)
		continue;
		son[x]+=dfs1(e[i].to,x);
		if(son[e[i].to]>son[maxson[x]])
		maxson[x]=e[i].to;
	}
	return son[x];
}
void clear(int x,int father)
{
	s[c[x]]--;
	for(int i=g[x];i;i=e[i].next)
	{
		if(e[i].to==father)
		continue;
		clear(e[i].to,x);
	}
}
long long addcol(int x,int father,int ymax)
{
	s[c[x]]++;
	if(s[c[x]]>maxi)
	{
		maxi=s[c[x]];
		sum+=c[x]-temp;
		temp=c[x];
	}
	else if(s[c[x]]==maxi)
	{
		sum+=c[x];
		temp+=c[x];
	}
	for(int i=g[x];i;i=e[i].next)
	{
		if(e[i].to==father||e[i].to==ymax)
		continue;
		addcol(e[i].to,x,ymax);
	}
	return sum;
}
void dfs2(int x,int father)
{
	for(int i=g[x];i;i=e[i].next)
	{
		if(e[i].to==father||e[i].to==maxson[x])
		continue;
		dfs2(e[i].to,x);
		maxi=0,temp=0,sum=0;
		clear(e[i].to,x);
	}
	if(maxson[x])
	dfs2(maxson[x],x);
	ans[x]=addcol(x,father,maxson[x]);
}
int main()
{
	int n;
	n=read();
	for(int i=1;i<=n;i++)
	c[i]=read();
	for(int i=1;i<=n-1;i++)
	{
		int a,b;
		cin>>a>>b;
		add(a,b);
		add(b,a);
	}
	dfs1(1,0);
	dfs2(1,0);
	for(int i=1;i<=n;i++)
	printf("%lld ",ans[i]);
	return 0;
}


#include <iostream>
#include <cstdio>
//#define lson t[x].l
//#define rson t[x].r
//#define t[x].l (x<<1)
//#define t[x].r ((x<<1)|1)
//#define mid ((l+r)>>1)
#define int long long
using namespace std;
const int maxn = 1e5+5;
int n, a[maxn], sol[maxn];
int xx, yy;
int last[maxn], cnt;
struct edge{int y, gg;} e[maxn<<1];
inline void ins(int x, int y){
	e[++cnt].y = y;
	e[cnt].gg = last[x];
	last[x] = cnt;
}

struct seg{int l, r, sum, ans;}t[maxn*50];
int num;
inline void pushup(int x){
	if(t[t[x].l].sum < t[t[x].r].sum) t[x].sum = t[t[x].r].sum, t[x].ans = t[t[x].r].ans;
	else if(t[t[x].l].sum > t[t[x].r].sum) t[x].sum = t[t[x].l].sum, t[x].ans = t[t[x].l].ans;
	else t[x].sum = t[t[x].l].sum, t[x].ans = t[t[x].l].ans + t[t[x].r].ans;
}

void update(int &x, int l, int r, int pos){
	if(!x) x = ++num;
	if(l == r){
		++t[x].sum;
		t[x].ans = l;
		return;
	}
	int mid = (l+r)/2;
	if(pos <= mid) update(t[x].l, l, mid, pos);
	else update(t[x].r, mid+1, r, pos);
	pushup(x);
}

int merge(int x, int y, int l, int r){
	if(!x) return y;
    if(!y) return x;
	if(l == r){
		t[x].sum = t[x].sum + t[y].sum;
		t[x].ans = l;
		return x;
	}
	int mid = (l+r)/2;
	t[x].l = merge(t[x].l, t[y].l, l, mid);
	t[x].r = merge(t[x].r, t[y].r, mid+1, r);
	pushup(x);
	return x;
}

void dfs(int x, int fa){
	for(int i = last[x]; i; i = e[i].gg){
		if(e[i].y == fa) continue;
		dfs(e[i].y, x);
		merge(x, e[i].y, 1, n);
	}
	update(x, 1, n, a[x]);
	sol[x] = t[x].ans;
}
signed main(){
	scanf("%lld",&n); num = n;
	for(int i = 1; i <= n; ++i) scanf("%lld",&a[i]);
	for(int i = 1; i < n; ++i){
		scanf("%lld%lld", &xx, &yy);
		ins(xx,yy);  ins(yy,xx);
	}
	dfs(1,0);
	for(int i = 1; i <= n; ++i) printf("%lld ", sol[i]);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
int n,a[100010],t=0,Link[100010],sum[100010],son[100010],Max,g[100010],f[100010],c[100010],nu;
long long ans[100010],s;
struct dsa{int v,nex;}e[200010];
void Insert(int x,int y) {e[++t].nex=Link[x];e[t].v=y;Link[x]=t;}
void dfs(int now,int fa)
{
	sum[now]=1;
	for (int i=Link[now];i;i=e[i].nex) {
		if (e[i].v==fa) continue;
		dfs(e[i].v,now);
		sum[now]+=sum[e[i].v];
		if (sum[e[i].v]>sum[son[now]]) son[now]=e[i].v;
	}
	return ;
}
void Calc(int now,int fa,int x)
{
	if (g[c[now]]!=nu) g[c[now]]=nu,f[c[now]]=1;else f[c[now]]++;
	if (f[c[now]]>Max) s=c[now],Max=f[c[now]];
	else if (f[c[now]]==Max) s+=c[now];
	for (int i=Link[now];i;i=e[i].nex) {
		if (e[i].v==fa||e[i].v==x) continue;
		Calc(e[i].v,now,x);
	}
}
void dfs1(int now,int fa,int ty)
{
	for (int i=Link[now];i;i=e[i].nex) {
		if (e[i].v==fa||e[i].v==son[now]) continue;
		dfs1(e[i].v,now,0);
	}
	if (son[now]) dfs1(son[now],now,1);
	Calc(now,fa,son[now]);
	ans[now]=s;
	if (!ty) nu++,Max=0,s=0;
}
int main()
{
	scanf("%d",&n);
	for (int i=1;i<=n;i++) scanf("%d",&c[i]);
	for (int i=1;i<n;i++) {
		int x,y;
		scanf("%d%d",&x,&y);
		Insert(x,y);Insert(y,x);
	}
	dfs(1,0);
	dfs1(1,0,0);
	for (int i=1;i<=n;i++)
	  printf("%lld ",ans[i]);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int n;
int c[N];
int v[N],nex[N],first[N],tot=1;
inline void add(int x,int y){
	v[++tot]=y;
	nex[tot]=first[x];
	first[x]=tot;
}
inline int read(){
	int x=0;char ch=getchar();
	while(!isdigit(ch))ch=getchar();
	while(isdigit(ch))x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
	return x;
}
int ans[N],sz[N];
bool gson[N];
void getg(int x,int f){
	sz[x]=1;
	int mx=0,p=0;
	for(int i=first[x];i;i=nex[i]){
		int y=v[i];if(y==f)continue;
		getg(y,x);sz[x]+=sz[y];
		if(sz[y]>mx){
			mx=sz[y];
			p=y;
		}
	}if(p)gson[p]=1;
}
int ap[N],mx,sum;
void DFS(int x,int f,int p){
	ap[c[x]]++;
	if(ap[c[x]]>mx){
		mx=ap[c[x]];
		sum=c[x];
	}else if(ap[c[x]]==mx)sum+=c[x];
	for(int i=first[x];i;i=nex[i]){
		int y=v[i];
		if(y==f || y==p)continue;
		DFS(y,x,p);
	}
}
inline void init(){
	for(int i=1;i<=n;i++)ap[i]=0;
	sum=mx=0;
}
void dfs(int x,int f){
	int p=0;
	for(int i=first[x];i;i=nex[i]){
		int y=v[i];
		if(y==f)continue;
		if(!gson[y])dfs(y,x),init();
		else p=y;
	}if(p)dfs(p,x);
	DFS(x,f,p);
	ans[x]=sum;
}
int main(){
	n=read();
	for(int i=1;i<=n;i++)c[i]=read();
	for(int i=1;i<n;i++){
		int x=read(),y=read();
		add(x,y),add(y,x);
	}getg(1,0);
	dfs(1,0);
	for(int i=1;i<=n;i++)cout<<ans[i]<<' ';
	cout<<endl;
}


#include<bits/stdc++.h>
using namespace std;
int a=0;
vetor<int> elements[100005];
int length[100005];
int gg[100005];
int sum[100005][2];
int dfs(int x)
{
	sum[gg[x]][0]+=1;
	sum[gg[x]][1]+=x;
	for(int i=0;i<length[x];i++)
	{
		dfs(elements[x][i]);
	}
}
int main()
{
	cin>>a;
	for(int i=1;i<=a;i++)
	{
		cin>>gg[i];
	}
	int k,l;
	for(int i=0;i<a;i++)
	{
		cin>>k>>l;
		length[k]=length[k]+1;
		elements[k].push_back(l);
	}
	dfs(1);
	int maxs=0;
	int ans=0;
	for(int i=1;i<=100000;i++)
	{
		maxs=0;
		ans=0;
		if(sum[i][0]>=maxs)
		{
			maxs=sum[i][0];
			ans=sum[i][1];
		}
		cout<<ans<<" ";
	}
}


#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define R register
#define N 100010
using namespace std;
inline int read(){
	int x = 0,f = 1;
	char ch = getchar();
	while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	return x*f;
}
int n,m,head[N],siz[N],f[N],son[N],cnt[N],c[N];
long long mx,sum,ans[N];
struct edge{
	int to,next;
}e[N<<1];
int len;
void addedge(int u,int v){
	e[++len].to = v;
	e[len].next = head[u];
	head[u] = len;
}
void dfs(int u,int fa){
	siz[u] = 1;
	f[u] = fa;
	for(R int i = head[u];i;i = e[i].next){
		int v = e[i].to;
		if(v==fa)continue;
		dfs(v,u);
		siz[u] += siz[v];
		if(siz[v]>siz[son[u]])son[u] = v;
	}
}
void update(int u,int val,int p){
	cnt[c[u]] += val;
	if(cnt[c[u]]>mx)mx = cnt[c[u]],sum = c[u];
	else if(cnt[c[u]]==mx)sum += c[u];
	for(R int i = head[u];i;i = e[i].next){
		int v = e[i].to;
		if(v==f[u]||v==p)continue;
		update(v,val,p);
	}
}
void dsu(int u,int opt){
	for(R int i = head[u];i;i = e[i].next){
		int v = e[i].to;
		if(v==f[u]||v==son[u])continue;
		dsu(v,0);
	}
	if(son[u])dsu(son[u],1);
	update(u,1,son[u]);
	ans[u] = sum;
	if(opt==0){
		update(u,-1,0);
		mx = sum = 0;
	}
}
int main(){
	n = read();
	for(R int i = 1;i <= n;i++)c[i] = read();
	for(R int i = 1;i < n;i++){
		int u = read(),v = read();
		addedge(u,v),addedge(v,u);
	}
	dfs(1,0);
	dsu(1,0);
	for(R int i = 1;i <= n;i++)printf("%lld ",ans[i]);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=1e5+5;
int n,a[N],cnt[N];//cnt[x]±íÊ¾µ±Ç°ÑÕÉ«x³öÏÖµÄ´ÎÊý
int si[N],son[N],mc=0;//sum±íÊ¾³öÏÖµÄ×î¶àÑÕÉ«±àºÅºÍ ,mcÊ¾³öÏÖµÄ×î¶àÑÕÉ«Êý
LL sum=0,f[N];
struct edge{
	int x,y,nxt;
}e[N*2];
int head[N],tot=0;
inline void addedge(int x,int y){
	e[++tot]={x,y,head[x]};
	head[x]=tot;
}
void pre(int x,int fa){
	int ms=0;
	si[x]=1;
	for(int i=head[x];i;i=e[i].nxt){
		int y=e[i].y;
		if(y==fa) continue;
		pre(y,x);
		si[x]+=si[y];
		if(si[y]>ms) ms=si[y],son[x]=y;
	}
}
void dfs2(int x,int fa,int p){ //pÎªroot£¨µÚÒ»²ãµÄx£©µÄÖØ¶ù×Ó
	cnt[a[x]]++;
	if(cnt[a[x]]>mc) mc=cnt[a[x]],sum=a[x];
	else if(cnt[a[x]]==mc) sum+=a[x];
	for(int i=head[x];i;i=e[i].nxt){
		int y=e[i].y;
		if(y==fa||y==p) continue;
		dfs2(y,x,p);
	}
}
void clean(int x,int fa){
	cnt[a[x]]--;
	for(int i=head[x];i;i=e[i].nxt){
		int y=e[i].y;
		if(y==fa) continue;
		clean(y,x);
	}
}
void dfs(int x,int fa){
	for(int i=head[x];i;i=e[i].nxt){
		int y=e[i].y;
		if(y==fa||y==son[x]) continue;
		dfs(y,x);//¼ÆËãx¸÷¸ö×ÓÊ÷´ð°¸
		clean(y,x),sum=mc=0;//Çå¿Õx¸Ã×ÓÊ÷µÄÓ°Ïì£¨Èô²»Çå¿Õ¿ÉÄÜ»á¶ÔÐÖµÜ×ÓÊ÷´ð°¸¼ÆËã²úÉúÓ°Ïì£©
	}
	if(son[x]) dfs(son[x],x);//¼ÆËãÖØ¶ù×Ó×ÓÊ÷´ð°¸Í¬Ê±ËãÈë¶Ôx´ð°¸µÄ¹±Ï×
	dfs2(x,fa,son[x]);//ÀÛ¼Óx¼°Æä×ÓÊ÷³ýÖØ¶ù×Ó¶ÔÑÕÉ«ºÍx´ð°¸µÄ¹±Ï×
	f[x]=sum;
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d",a+i);
	for(int i=1;i<n;i++){
		int x,y;
		scanf("%d%d",&x,&y);
		addedge(x,y);
		addedge(y,x);
	}
	pre(1,0);
	dfs(1,0);
	for(int i=1;i<=n;i++) printf("%lld ",f[i]);
	return 0;
}
//dfs±¾ÉíÊ±¼ä¸´ÔÓ¶ÈÎªO(n)
//T(x)=2*(size(x)-size(son[x])) clean/dfs2
//clean/dfs2Ö»¶ÔÇá¶ù×Ó²Ù×÷£¬Ã¿¸öµã±»Í³¼Æµ½Ö»ÄÜÍ¨¹ýÇá±ß
//¶øÇá±ßÊý<=logn
//O(nlogn)


#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 200020;
int nex[N],to[N],head[N];
int siz[N];
LL ans[N],sum;
int mx;
int son[N],col[N];
int tot=0,cnt[N];
void ae(int x,int y)
{
	nex[++tot] = head[x];
	to[tot] = y;
	head[x] = tot;
}
void dfs(int u,int pre)
{
	siz[u] = 1;
	for(int i=head[u];i;i=nex[i])
	{
		int v = to[i];
		if(v!=pre)
		{
			dfs(v,u);
			if(siz[v] > siz[son[u]]) son[u] = v;
			siz[u] += siz[v];
		}
	}
}
int ss;
void add(int u,int pre,int val)
{
	cnt[col[u]] += val;
	if(cnt[col[u]] > mx) mx = cnt[col[u]],sum=col[u];
	else if(cnt[col[u]] == mx) sum+=1LL*col[u];
	for(int i=head[u];i;i=nex[i])
	{
		int v=to[i];
		if(v!=pre && v!=ss)
		  add(v,u,val);
	}
}
void dfs1(int u,int pre,int kep)
{
	for(int i=head[u];i;i=nex[i])
	{
		int v = to[i];
		if(v!=son[u] && v!=pre)
		{
			dfs1(v,u,0);
		}
	}
	if(son[u])dfs1(son[u],u,1),ss = son[u];

	add(u,pre,1);
	ss = 0;
	ans[u] = sum;
	if(!kep)
	{
		add(u,pre,-1);
		sum = 0;
		mx = 0;
	}
}
int main()
{
	int n,x,y;
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d",&col[i]);
	for(int i=1;i<n;i++) scanf("%d%d",&x,&y),ae(x,y),ae(y,x);
	dfs(1,0);
	dfs1(1,0,1);
	for(int i=1;i<=n;i++)
	  printf("%lld ",ans[i]);
	return 0;
}


// CF600E Lomsat gelral
// https://www.luogu.com.cn/problem/CF600E

#include<bits/stdc++.h>
#define re register
#define LL long long
#define il inline
using namespace std;
template<typename T>il void read(T &ff){
    T rr=1;ff=0;re char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')rr=-1;ch=getchar();}
    while(isdigit(ch)){ff=(ff<<1)+(ff<<3)+(ch^48);ch=getchar();}
    ff*=rr;
}
const int N=1e5+7;
int n,a[N],num,dfn[N],son[N],siz[N],c[N],ans[N],now,b[N],mx,tot,head[N];
struct E{
    int ver,nxt;
}e[N<<1];
il void add(re int u,re int v){e[++tot]=(E){v,head[u]},head[u]=tot;}
void dfs1(re int x,re int f){
    siz[x]=1,dfn[x]=++num;
    for(re int i=head[x];i;i=e[i].nxt){
        int y=e[i].ver;
        if(y==f)continue;
        dfs1(y,x);
        siz[x]+=siz[y];
        if(siz[son[x]]<siz[y])son[x]=y;
    }
}
il int Add(re int x){if(++c[x]>mx)mx=c[x],now=0; if(c[x]==mx)now+=x;}
void dfs(re int x,re int f,re int k){
    for(re int i=head[x];i;i=e[i].nxt){
        int y=e[i].ver;
        if(y!=f&&y!=son[x])dfs(y,x,0);
    }
    if(son[x])dfs(son[x],x,1);
    for(re int i=head[x];i;i=e[i].nxt){
        int y=e[i].ver;
        if(y!=f&&y!=son[x]) for(re int j=0;j<siz[y];++j)Add(a[dfn[y]+j]);
    }
    Add(a[dfn[x]]);ans[x]=now;
    if(!k)for(re int i=mx=now=0;i<siz[x];++i)c[a[dfn[x]+i]]=0;
}
signed main(){
    read(n);
    for(re int i=1;i<=n;++i)read(b[i]);
    for(re int i=1,u,v;i<n;++i)read(u),read(v),add(u,v),add(v,u);
    dfs1(1,1);
    for(re int i=1;i<=n;++i)a[dfn[i]]=b[i];
    dfs(1,1,1);
    for(re int i=1;i<=n;++i)printf("%d ",ans[i]);
    return 0;
}


#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<map>
#include<vector>
using namespace std;

const int maxn=100000+5;

inline int read()
{
	int x=0,f=1;
	char c=getchar();
	while(c<'0'||c>'9')
	{
		if(c=='-')
			f=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9')
	{
		x=x*10+c-'0';
		c=getchar();
	}
	return x*f;
}

int val[maxn];
struct node{
	int last,to;
}tree[maxn*2];
int s=0,head[maxn];

void add(int from,int to)
{
	tree[++s].to=to;
	tree[s].last=head[from];
	head[from]=s;
}

int son[maxn],Size[maxn];
void dfs1(int from,int to)
{
	Size[to]=1;
	int maxx=-0x3f3f3f3f;
	for(int i=head[to];i;i=tree[i].last)
	{
		int k=tree[i].to;
		if(k==from)
			continue;
		dfs1(to,k);
		Size[to]+=Size[k];
		if(Size[k]>maxx)
		{
			son[to]=k;
			maxx=Size[k];
		}
	}
}

struct DS{
	int ans;
	long long sum;
	map<int,int> M;
	void Insert(int x,int y)
	{
		M[x]+=y;
		if(ans==-1||M[x]>ans)
		{
			ans=M[x];
			sum=x;
		}
		else if(M[x]==ans)
			sum+=x;
	}
}record[maxn];

void dfs2(int from,int to)
{
	if(!son[to])
	{
		record[to].ans=-1;
		record[to].Insert(val[to],1);
		return;
	}
	for(int i=head[to];i;i=tree[i].last)
	{
		int k=tree[i].to;
		if(k==from)
			continue;
		dfs2(to,k);
	}
	record[to]=record[son[to]];
	record[to].Insert(val[to],1);
	for(int i=head[to];i;i=tree[i].last)
	{
		int k=tree[i].to;
		if(k==from||k==son[to])
			continue;
		map<int,int>::iterator it;
		for(it=record[k].M.begin();it!=record[k].M.end();it++)
		{
			pair<int,int> p=*it;
			record[to].Insert(p.first,p.second);
		}
	}
}

int main()
{
	int n=read();
	for(int i=1;i<=n;i++)
		val[i]=read();
	int u,v;
	for(int i=1;i<=n-1;i++)
	{
		u=read(); v=read();
		add(u,v); add(v,u);
	}
	dfs1(0,1); dfs2(0,1);
	for(int i=1;i<=n;i++)
		printf("%lld ",record[i].sum);
	printf("\n");
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define LL long long
inline int read(){
	int a=0;char c=getchar();
	while(c>'9'||c<'0')c=getchar();
	while('0'<=c&&c<='9'){
		a=a*10+c-48;
		c=getchar();
	}
	return a;
}
#define MN 100005
int siz[MN],fa[MN],w[MN],col[MN],vis[MN],n,u,v,MAX;
LL ans[MN],sum;
vector<int>edge[MN];
void dfs1(int x){
	siz[x]=1;
	for(int i=0;i<edge[x].size();++i)
		if(edge[x][i]!=fa[x]){
			fa[edge[x][i]]=x;
			dfs1(edge[x][i]);
			siz[x]+=siz[edge[x][i]];
			if(siz[w[x]]<siz[edge[x][i]])w[x]=edge[x][i];
		}
}
void calc(int x,int op,int W){
	vis[col[x]]+=op;
	if(vis[col[x]]>MAX) MAX=vis[col[x]],sum=col[x];
		else if(vis[col[x]]==MAX) sum+=col[x];
	for(int i=0;i<edge[x].size();++i)
		if(edge[x][i]!=fa[x]&&edge[x][i]!=W)
			calc(edge[x][i],op,W);
}
void dfs2(int x,int op){
	for(int i=0;i<edge[x].size();++i){
		if(edge[x][i]!=fa[x]&&edge[x][i]!=w[x])
			dfs2(edge[x][i],0);
	}
	if(w[x]) dfs2(w[x],1);
	calc(x,1,w[x]);
	ans[x]=sum;
	if(!op){
		calc(x,-1,0);
		sum=0;
		MAX=0;
	}
}
int main(){
	n=read();
	for(int i=1;i<=n;++i)col[i]=read();
	for(int i=1;i<n;++i){
		int u=read(),v=read();
		edge[u].push_back(v);
		edge[v].push_back(u);
	}
	dfs1(1);
	dfs2(1,1);
	for(int i=1;i<=n;++i)
		printf("%I64d\n",ans[i]);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e5+10;
int n;
int co[N];
struct Node{
	int y,Next;
}e[2*N];
int ans[N];
int len = 0 , linkk[N];

void Insert(int x,int y){
	e[++len] = (Node){y,linkk[x]};
	linkk[x] = len;
}

int L[N] , R[N] , cnt , hom[N];
void dfs(int x,int faa){
	L[x] = ++cnt;
	hom[cnt] = x;
	for (int i = linkk[x]; i; i = e[i].Next)
	  if (e[i].y != faa) dfs(e[i].y,x);
	R[x] = cnt;
}

int Cnt[N], Co[N] , tot = 0;
int Max = 0,sum = 0;

void Clear(){
	while (tot) Cnt[Co[tot--]]--;
	Max = sum = 0;
}

void In(int x){
	++Cnt[Co[++tot] = co[x]];
	if (Max < Cnt[co[x]]) Max = Cnt[co[x]] , sum = co[x];
	else if (Max == Cnt[co[x]]) sum+=co[x];
}

void Solve(int l,int r){
	if (l == r){if (L[hom[l]] == R[hom[l]])ans[hom[l]] = co[hom[l]];return;}
	int mid = l + r >> 1;
	Solve(l,mid); Solve(mid+1,r);
	Clear();
	int p = mid;
	for (int i = mid,j; i >= l && (j = R[hom[i]])<=r; i--){
		In(hom[i]);
		if (j <= mid) continue;
		while (p < j) In(hom[++p]);
		ans[hom[i]] = sum;
	}
}

signed main(){
	scanf("%lld",&n);
	for (int i = 1; i <= n; i++) scanf("%lld",&co[i]);
	for (int i = 1,x,y; i < n; i++) scanf("%lld %lld",&x,&y) , Insert(x,y) , Insert(y,x);
	dfs(1,0);
//	for (int i = 1; i <= n; i++) cout<<L[i]<<' '<<' '<<R[i]<<' '<<hom[L[i]]<<endl;
	Solve(1,n);
	for (int i = 1; i <= n; i++) printf("%lld ",ans[i]);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int head[N],tot,n,col[N],hson[N],siz[N],cnt[N],Mx,son,sum,ans[N];
struct Edge{
	int v,nxt;
}edge[N<<1];
void add(int u,int v){
	edge[++tot]=(Edge){v,head[u]};head[u]=tot;
}
void dfs(int x,int fa){
	siz[x]=1;
	for(int i=head[x];i;i=edge[i].nxt){
		int v=edge[i].v;if(v==fa)continue;
		dfs(v,x);siz[x]+=siz[v];if(siz[v]>siz[hson[x]])hson[x]=v;
	}
}
void update(int x,int fa,int val){
	cnt[col[x]]+=val;if(cnt[col[x]]>Mx)Mx=cnt[col[x]],sum=col[x];
	else if(cnt[col[x]]==Mx)sum+=col[x];
	for(int i=head[x];i;i=edge[i].nxt){
		int v=edge[i].v;if(v==fa||v==son)continue;
		update(v,x,val);
	}
}
void dfs2(int x,int fa,int opt){
	for(int i=head[x];i;i=edge[i].nxt){
		int v=edge[i].v;if(v==fa||v==hson[x])continue;
		dfs2(v,x,0);
	}
	if(hson[x])dfs2(hson[x],x,1);son=hson[x];
	update(x,fa,1);son=0;ans[x]=sum;if(!opt)update(x,fa,-1),sum=0,Mx=0;
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++)scanf("%d",&col[i]);
	for(int i=1;i<n;i++){
		int u,v;
		scanf("%d %d",&u,&v);add(u,v);add(v,u);
	}
	dfs(1,0);dfs2(1,0,0);
	for(int i=1;i<=n;i++)printf("%d ",ans[i]);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define re register
#define ll long long
inline int read()
{
	int f=1,lzx=0;char c=getchar();
	while(c>'9'||c<'0'){if(c=='-')f=-f;c=getchar();}
	while(c<='9'&&c>='0'){lzx=lzx*10+c-'0';c=getchar();}
	return lzx*f;
}
const int N=1e5+10;
int n,Maxn,SON,col[N],head[N],from[N*2],cnt,to[N*2],size[N],heavy[N],coun[N];
ll ans[N],sum;
inline void add(int x,int y)
{
	from[++cnt]=head[x];
	head[x]=cnt;
	to[cnt]=y;
	return;
}
inline void dfs(int x,int fa)
{
	size[x]=1;
	for(re int i=head[x];i;i=from[i])
	{
		int v=to[i];
		if(v==fa)continue;
		dfs(v,x);
		if(size[v]>size[heavy[x]])
			heavy[x]=v;
		size[x]+=size[v];
	}
	return;
}
inline void Merger(int x,int fa,int val)
{
	coun[col[x]]+=val;
	if(coun[col[x]]>Maxn)
	{
		Maxn=coun[col[x]];
		sum=col[x];
	}
	else if(coun[col[x]]==Maxn)sum+=col[x];
	for(re int i=head[x];i;i=from[i])
	{
		int v=to[i];
		if(v==SON||v==fa)continue;
//		cout<<"wrong"<<v<<' '<<SON<<endl;
		Merger(v,x,val);
	}
	return;
}
inline void dfs1(int x,int fa,int flag)
{
	for(re int i=head[x];i;i=from[i])
	{
		int v=to[i];
		if(v==fa||v==heavy[x])continue;
		dfs1(v,x,0);
	}
//	cout<<"NMSL"<<SON<<endl;
	if(heavy[x])dfs1(heavy[x],x,1);
	SON=heavy[x];
	Merger(x,fa,1);SON=0;
	ans[x]=sum;
//	puts("orz");
//	cout<<x<<' '<<Maxn<<' '<<heavy[x]<<endl;
//	for(re int i=1;i<=n;i++)cout<<coun[i]<<endl;
//	puts("orz");
	if(!flag)
	{
		Merger(x,fa,-1);
		Maxn=0;sum=0;
	}
	return;
}
int main()
{
	n=read();
	for(re int i=1;i<=n;i++)
		col[i]=read();
	for(re int i=1;i<n;i++)
	{
		int x=read(),y=read();
		add(x,y);add(y,x);
	}
	dfs(1,0);
	dfs1(1,0,0);
	for(re int i=1;i<=n;i++)printf("%lld ",ans[i]);
	return 0;
}


#include <iostream>
#include <cstdio>
#include <vector>
#define ls tr[k].l
#define rs tr[k].r
#define N 100011
#define int long long
using namespace std;
struct Node
{
	int l;   //左端点
	int r;   //右端点
	int sum; //出现次数
	int ans; //答案统计
}tr[N<<5];
vector<int>T[N<<1];
int rt[N<<5],cl[N],ans_sum[N],cnt=0;
void push_up(int k)
{
	if(tr[ls].sum>tr[rs].sum)
	{
		tr[k].sum=tr[ls].sum;
		tr[k].ans=tr[ls].ans;
	}
	if(tr[rs].sum>tr[ls].sum)
	{
		tr[k].sum=tr[rs].sum;
		tr[k].ans=tr[rs].ans;
	}
	if(tr[ls].sum==tr[rs].sum)
	{
		tr[k].ans=tr[ls].ans+tr[rs].ans;
		tr[k].sum=tr[ls].sum;
	}
}
int merge(int a,int b,int l,int r)
{
	if(!a) return b;
	if(!b) return a;
	if(l==r)
	{
		tr[a].sum+=tr[b].sum;
		tr[a].ans=l;
		return a;
	}
	int mid=(l+r)>>1;
	tr[a].l=merge(tr[a].l,tr[b].l,l,mid);
	tr[a].r=merge(tr[a].r,tr[b].r,mid+1,r);
	push_up(a);
	return a;
}
int update(int &now,int l,int r,int pos,int v)
{
	if(!now) now=++cnt;
	if(l==r)
	{
		tr[now].sum+=v;
		tr[now].ans=l;
		return 0;
	}
	int mid=(l+r)>>1;
	if(pos<=mid) update(tr[now].l,l,mid,pos,v);
	else update(tr[now].r,mid+1,r,pos,v);
	push_up(now);
}
void dfs(int u,int f)
{
	for(int i=0;i<T[u].size();++i)
	{
		int v=T[u][i];
		if(v==f) continue;
		dfs(v,u);
		merge(rt[u],rt[v],1,N);
	}
	update(rt[u],1,N,cl[u],1);
	ans_sum[u]=tr[rt[u]].ans;
}
signed main()
{
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	int n;
	scanf("%lld",&n);
	for(int i=1;i<=n;++i) scanf("%lld",&cl[i]),rt[i]=i,++cnt;
	for(int i=1;i<n;++i)
	{
		int x,y;
		scanf("%lld %lld",&x,&y);
		T[x].push_back(y);
		T[y].push_back(x);
	}
	dfs(1,0);
	for(int i=1;i<=n;++i) printf("%lld ",ans_sum[i]);
}


#include <cstdio>
#include <algorithm>
#include <cmath>
#define N 100001
using namespace std;
int n, num[N],cnt,h[N], sizee,pos[N], dfn[N],dot[N],size[N],ord, TIA[N],maxx;//tot[i]:出现i次的数的总和
long long tot[N],out[N];
struct edge{
	int next,to;
}e[N<<1];
struct doby{
	int l,r,id;
}ask[N];
inline void adde(int u,int v)
{
	e[++cnt].next=h[u];
	h[u]=cnt;
	e[cnt].to=v;
	return;
}
inline bool cmp(doby a,doby b)
{
	return pos[a.l]^pos[b.l]?pos[a.l]<pos[b.l]:(pos[a.l]&1?a.r<b.r:a.r>b.r);
}
inline void dfs(int x)
{
	dot[dfn[x]=++ord]=x;
	size[x]=1;
	for(int i=h[x],v;i;i=e[i].next)
	{
		v=e[i].to;
		if(!dfn[v])dfs(v),size[x]+=size[v];
	}
	return;
}
inline void add(int x)
{
	x=num[dot[x]];
	tot[TIA[x]]-=x;
	TIA[x]++;
	tot[TIA[x]]+=x;
	if(TIA[x]>maxx)maxx=TIA[x];
	return;
}
inline void remove(int x)
{
	x=num[dot[x]];
	tot[TIA[x]]-=x;
	if(TIA[x]==maxx&&!tot[TIA[x]])maxx--;
	TIA[x]--;
	tot[TIA[x]]+=x;
	return;
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)scanf("%d",&num[i]);
	for(int i=1,u,v;i<n;i++)
	{
		scanf("%d%d",&u,&v);
		adde(u,v),adde(v,u);
	}
	dfs(1);
	sizee=sqrt(n);
	for(int i=1;i<=n;i++)
	{
		ask[i].l=dfn[i],ask[i].r=dfn[i]+size[i]-1;
		ask[i].id=i;
		pos[i]=(i-1)/sizee+1;
		tot[0]+=num[i];
	}
	sort(ask+1,ask+n+1,cmp);
	int ql=1,qr=0;
	for(int i=1;i<=n;i++)
	{
		while(ql>ask[i].l)add(--ql);
		while(qr<ask[i].r)add(++qr);
		while(ql<ask[i].l)remove(ql++);
		while(qr>ask[i].r)remove(qr--);
		out[ask[i].id]=tot[maxx];
//														printf("%d %d %d %d~%d\n",ask[i].id,maxx,tot[maxx],ask[i].l,ask[i].r);
//														for(int j=1;j<=n;j++)printf("%d ",tot[j]);puts("");
	}
	for(int i=1;i<=n;i++)printf("%lld ",out[i]);
	return 0;
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
const int maxn =  100000 + 10 ;
struct Node
{
	int to,next;
}edge[maxn * 2];
int head[maxn * 2],tot;
void add(int x,int y)
{
	edge[++tot].to = y;
	edge[tot].next = head[x];
	head[x] = tot;
}
int n,col[maxn],siz[maxn],ans[maxn],son[maxn];
void dfs1(int u,int fa)
{
	siz[u]=1;
	for(int i=head[u];i;i=edge[i].next)
	{
		int v=edge[i].to;
		if(v==fa) continue;
		siz[u]+=siz[v];
		if(siz[v]>siz[son[u]]) son[u]=v;
	}
}
int cnt[maxn],maxx,sum,Son;
void add(int u,int fa,int  val)
{
	cnt[col[u]]+=val;
	if(cnt[col[u]] > maxx) maxx = cnt[col[u]] , sum = col[u];
	else if(cnt[col[u]] == maxx) sum+=col[u];
	for(int i=head[u];i;i=edge[i].next)
	{
		int v=edge[i].to;
		if(v==fa || v == Son) continue;
		add(v,u,val);
	}
}
void dfs2(int u,int fa,int xp)
{
	for(int i=head[u];i;i=edge[i].next)
	{
		int v=edge[i].to;
		if(v==fa) continue;
		if(v!=son[u]) dfs2(v,u,0);
	}
	if(son[u]) dfs2(son[u],u,1),Son = son[u];
	add(u,fa,1); Son = 0;
	ans[u]=sum;
	if(!xp) add(u,fa,-1) , sum = 0 , maxx = 0 ;
}
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++) scanf("%d",&col[i]);
	for(int i=1,x,y;i<n;i++)
	{
		scanf("%d%d",&x,&y);
		add(x,y);add(y,x);
	}
	dfs1(1,0);
	dfs2(1,0,0);
	for(int i=1;i<=n;i++) printf("%d ",ans[i]);
	return 0;
}


#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#define lson tr[now].l
#define rson tr[now].r
#define int long long
using namespace std;

struct tree
{
	int l,r,sum,val,ans;
}tr[5000050];

int rt[100010],cl[100010],cnt,n,anss[100010];
vector<int> g[100010];

int push_up(int now)
{
	if(tr[lson].sum>tr[rson].sum)
	{
		tr[now].sum=tr[lson].sum;
		tr[now].val=tr[lson].val;
		tr[now].ans=tr[lson].ans;
	}
	if(tr[rson].sum>tr[lson].sum)
	{
		tr[now].sum=tr[rson].sum;
		tr[now].val=tr[rson].val;
		tr[now].ans=tr[rson].ans;
	}
	if(tr[lson].sum==tr[rson].sum)
	{
		tr[now].sum=tr[lson].sum;
		tr[now].val=tr[lson].val;
		tr[now].ans=tr[lson].ans+tr[rson].ans;
	}
}

int update(int &now,int l,int r,int pos,int v)
{
	if(!now) now=++cnt;
	if(l==r)
	{
		tr[now].val=l;
		tr[now].sum+=v;
		tr[now].ans=l;
		return 0;
	}
	int mid=(l+r)>>1;
	if(pos<=mid) update(lson,l,mid,pos,v);
	else update(rson,mid+1,r,pos,v);
	push_up(now);
}

int merge(int a,int b,int l,int r)
{
	if(!a) return b;
	if(!b) return a;
	if(l==r)
	{
		tr[a].val=l;
		tr[a].sum+=tr[b].sum;
		tr[a].ans=l;
		return a;
	}
	int mid=(l+r)>>1;
	tr[a].l=merge(tr[a].l,tr[b].l,l,mid);
	tr[a].r=merge(tr[a].r,tr[b].r,mid+1,r);
	push_up(a);
	return a;
}

int dfs(int now,int f)
{
	for(int i=0;i<g[now].size();i++)
	{
		if(g[now][i]==f) continue;
		dfs(g[now][i],now);
		merge(rt[now],rt[g[now][i]],1,100000);
	}
	update(rt[now],1,100000,cl[now],1);
	anss[now]=tr[rt[now]].ans;
}

signed main()
{
	scanf("%lld",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%lld",&cl[i]);
		rt[i]=i;
		cnt++;
	}
	int from,to;
	for(int i=1;i<n;i++)
	{
		scanf("%lld%lld",&from,&to);
		g[from].push_back(to);
		g[to].push_back(from);
	}
	dfs(1,0);
	for(int i=1;i<=n;i++)
	{
		printf("%lld ",anss[i]);
	}
}


#include <bits/stdc++.h>
#define ll long long
#define lc d[k].ls
#define rc d[k].rs
using namespace std;
const int N=1e5+500;
int n,tot;
struct node{int ls,rs,mx;ll ci;}d[N*20];
void pushup(int k)
{
	if(d[lc].mx==d[rc].mx)  d[k].mx=d[lc].mx,d[k].ci=d[lc].ci+d[rc].ci;
	else if(d[lc].mx>d[rc].mx) d[k].mx=d[lc].mx,d[k].ci=d[lc].ci;
		 else d[k].mx=d[rc].mx,d[k].ci=d[rc].ci;
}
void modify(int &k,int l,int r,int x,int v)
{
	if(!k){ k=++tot;d[k].mx=0;d[k].ci=1ll*(l+r)*(r-l+1)/2; }
	if(l==r){ d[k].mx+=v;return; }
	int mid=l+r>>1;
	if(x<=mid) modify(lc,l,mid,x,v);
	else modify(rc,mid+1,r,x,v);
	pushup(k);
}
int merge(int x,int y,int l,int r)
{
	if(!x||!y) return x|y;
	if(l==r)
	{
		d[x].mx+=d[y].mx;
		return x;
	}
	int mid=l+r>>1;
	d[x].ls=merge(d[x].ls,d[y].ls,l,mid);
	d[x].rs=merge(d[x].rs,d[y].rs,mid+1,r);
	pushup(x);
	return x;
}
struct Edge{int nxt,to;}e[N<<1];
int ci[N],h[N],e_num,rt[N];
ll ans[N];
void add(int from,int to)
{
	e[++e_num]=(Edge){h[from],to};
	h[from]=e_num;
}
void dfs(int u,int pre)
{
	for(int i=h[u];i;i=e[i].nxt)
	{
		int v=e[i].to;
		if(v==pre) continue;
		dfs(v,u);
		rt[u]=merge(rt[u],rt[v],1,n);
	}
	modify(rt[u],1,n,ci[u],1);
	ans[u]=d[rt[u]].ci;
}
inline int read()
{
	char ch;
	while((ch=getchar())<'0'||ch>'9');
	int res=ch-'0';
	while((ch=getchar())>='0'&&ch<='9')
		res=res*10+ch-'0';
	return res;
}
int main()
{
	n=read();
	for(int i=1;i<=n;i++) ci[i]=read();
	int u,v;
	for(int i=1;i<n;i++)
	{
		u=read();v=read();
		add(u,v);add(v,u);
	}
	dfs(1,0);
	for(int i=1;i<=n;i++) printf("%lld ",ans[i]);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int sum[N<<6],tr[N<<6],ls[N<<6],rs[N<<6],rt[N];
int a[N],tot,ans[N];
struct edge{
	int t,nxt;
}e[N<<1];
int cnt,head[N];
int n;
void add(int u,int v){
	e[++cnt].nxt=head[u];
	e[cnt].t=v;
	head[u]=cnt;
}
void update(int x){
	if (tr[ls[x]]==tr[rs[x]]){
		sum[x]=sum[ls[x]]+sum[rs[x]];
		tr[x]=tr[ls[x]];
		return ;
	}
	if (tr[ls[x]]>tr[rs[x]]){
		sum[x]=sum[ls[x]];
		tr[x]=tr[ls[x]];
		return ;
	}
	if (tr[ls[x]]<tr[rs[x]]){
		sum[x]=sum[rs[x]];
		tr[x]=tr[rs[x]];
		return ;
	}
}
void insert(int &x,int l,int r,int L){
	if (!x) x=++tot;
	if (l==r) {
		tr[x]++;
		sum[x]=l;
		return ;
	}
	int mid=(l+r)>>1;
	if (L<=mid) insert(ls[x],l,mid,L);
	else insert(rs[x],mid+1,r,L);
	update(x);
}

int merge(int x,int y,int l,int r){
	if (!x||!y) return x|y;
	if (l==r) {
		tr[x]=tr[x]+tr[y];
		sum[x]=l;
		return x;
	}
	int mid=(l+r)>>1;
	ls[x]=merge(ls[x],ls[y],l,mid);
	rs[x]=merge(rs[x],rs[y],mid+1,r);
	update(x);
	return x;
}
void dfs(int x,int fath){
	insert(rt[x],1,n,a[x]);
	for (int i=head[x];i;i=e[i].nxt){
		int v=e[i].t;
		if (v==fath) continue;
		dfs(v,x);
		rt[x]=merge(rt[x],rt[v],1,n);
	}
	ans[x]=sum[rt[x]];

}
int main(){
	scanf("%d",&n);
	for (int i=1;i<=n;++i)
		scanf("%d",&a[i]),rt[i]=i;
	tot=n+1;
	for (int i=1;i<n;++i){
		int u,v;
		scanf("%d%d",&u,&v);
		add(u,v);
		add(v,u);
	}
	dfs(1,0);
	for (int i=1;i<=n;++i){
		printf("%d ",ans[i]);
	}
}


#include <bits/stdc++.h>
#define lson tr[now].ls
#define rson tr[now].rs
typedef long long ll;
using namespace std;
const int N = 1e5+7;
struct TREE{
	int max,ls,rs;ll sum;
}tr[N*20];
vector <int> edge[N];
int n,cnt,a[N],rt[N];ll ans[N];
template <typename TP>
inline void read(TP &x){
	x=0;char ch=getchar();
	for (;ch<'0'||ch>'9';ch=getchar());
	for (;ch>='0'&&ch<='9';ch=getchar()) x=x*10+(ch^48);
}

void add(int u, int v){edge[u].push_back(v);}

void pushup(int now){
	if (tr[lson].max>tr[rson].max){
		tr[now].max=tr[lson].max;
		tr[now].sum=tr[lson].sum;
	}else if (tr[lson].max<tr[rson].max){
		tr[now].max=tr[rson].max;
		tr[now].sum=tr[rson].sum;
	}else {
		tr[now].max=tr[lson].max;
		tr[now].sum=tr[lson].sum+tr[rson].sum;
	}
}

int merge(int s, int t, int l, int r){
	if (!s||!t){return s+t;}
	if (l==r){
		tr[s].max+=tr[t].max;
		tr[s].sum=l;
		return s;
	}
	int mid=(l+r)>>1;
	tr[s].ls=merge(tr[s].ls,tr[t].ls,l,mid);
	tr[s].rs=merge(tr[s].rs,tr[t].rs,mid+1,r);
	pushup(s);
	return s;
}

void update(int &now, int l, int r, int x){
	if (!now) now=++cnt;
	if (l==r){
		tr[now].max++;
		tr[now].sum=l;
		return;
	}
	int mid=(l+r)>>1;
	if (x<=mid) update(lson, l, mid, x);
	else update(rson, mid+1, r, x);
	pushup(now);
}

void dfs(int u, int f){
	for (int i=0,ii=edge[u].size();i<ii;++i){
		int v=edge[u][i];
		if (v!=f){
			dfs(v,u);
			rt[u]=merge(rt[u], rt[v], 1, 100000);
		}
	}
	update(rt[u],1,100000,a[u]);
	ans[u]=tr[rt[u]].sum;
}

int main() {
	read(n);
	for (int i=1;i<=n;++i) read(a[i]);
	for (int i=1;i<n;++i){
		int u,v;read(u),read(v);
		add(u, v);add(v,u);
	}
	for (int i=1;i<=n;++i) rt[i]=i;
	cnt=n;
	dfs(1,0);
	for (int i=1;i<=n;++i) printf("%lld ", ans[i]);

	return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <set>
#include <cmath>
#define maxn 50005
#define MOD 1000000007
using namespace std;
typedef long long ll;

struct Node{
    Node(){
    }
    Node(double a, double b){
        x = a;
        y = b;
    }
    double x, y;
};
Node node[100005];
double dis(Node a, Node b){
    return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
}
double get_dis(Node &a, Node &b, Node &c){

    double k1 = dis(a, b), k2 = dis(a, c), k3 = dis(b, c);
    if(k1 >= k2 + k3)return k2;
    if(k2 >= k1 + k3)return k1;
    double d = fabs((b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x));
    return d * d / k3;
}
int main(){

//  freopen("in.txt", "r", stdin);
    int n;
    double x, y;
    double maxs = 0, mins = 1e18;
    Node o;

    scanf("%d%lf%lf", &n, &o.x, &o.y);
    for(int i = 0; i < n; i++){
        scanf("%lf%lf", &node[i].x, &node[i].y);
        maxs = max(maxs, dis(o, node[i]));
    }
    for(int i = 0; i < n; i++){
        int j = (i + 1) % n;
        mins = min(mins, get_dis(o, node[i], node[j]));
    }
    double ans = (maxs - mins) * acos(-1);
    printf("%.18lf\n", ans);
    return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <set>
#include <cmath>
#define maxn 50005
#define MOD 1000000007
using namespace std;
typedef long long ll;

struct Node{
    Node(){
    }
    Node(double a, double b){
        x = a;
        y = b;
    }
    double x, y;
};
Node node[100005];
double dis(Node a, Node b){
    return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
}
double get_dis(Node &a, Node &b, Node &c){

    double k1 = dis(a, b), k2 = dis(a, c), k3 = dis(b, c);
    if(k1 >= k2 + k3)return k2;
    if(k2 >= k1 + k3)return k1;
    double d = fabs((b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x));
    return d * d / k3;
}
int main(){
    int n;
    double x, y;
    double maxs = 0, mins = 1e18;
    Node o;
    scanf("%d%lf%lf", &n, &o.x, &o.y);
    for(int i = 0; i < n; i++){
        scanf("%lf%lf", &node[i].x, &node[i].y);
        maxs = max(maxs, dis(o, node[i]));
    }
    for(int i = 0; i < n; i++){
        int j = (i + 1) % n;
        mins = min(mins, get_dis(o, node[i], node[j]));
    }
    double ans = (maxs - mins) * acos(-1);
    printf("%.18lf\n", ans);
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define ll long long
#define pi acos(-1.0)
using namespace std;
struct node
  {
      double x,y;
      double di;
  }a[100005];
double x_0,y_0;
double dis(node A)
  {
      return (A.y-y_0)*(A.y-y_0)+(A.x-x_0)*(A.x-x_0);
  }
double getdis(node A,node B)
  {
      return (A.y-B.y)*(A.y-B.y)+(A.x-B.x)*(A.x-B.x);
  }
double p(node A,node B)
  { if((x_0-A.x)*(B.x-A.x) + (y_0-A.y)*(B.y-A.y) < 0)return A.di;
    else if((x_0-B.x)*(A.x-B.x) + (y_0-B.y)*(A.y-B.y) < 0)return B.di;
     else {
       double b = (B.x-x_0)*(A.y-y_0)-(B.y-y_0)*(A.x-x_0);
          b *= b;
          b /= getdis(A,B);
      return b;
     }
  }
int main()
  {int n;
    while(~scanf("%d%lf%lf",&n,&x_0,&y_0))
    {double Max = 0;
    for(int i = 0;i < n;i ++)
    {
        scanf("%lf%lf",&a[i].x,&a[i].y);
        a[i].di = dis(a[i]);
        Max = max(a[i].di,Max);
    }
    double Min = 0x7fffffff;
    for(int i = 0;i < n-1;i ++)
    {
    Min = min(Min,p(a[i],a[i+1]));
    }
    printf("%.10lf\n",pi*(Max-Min));
   }
  }


#include<iostream>
#include<vector>
#include<cstring>
#include<cstdio>
#include<string>
#include<cmath>
#include<iomanip>
using namespace std;
const int maxn=100010;
const double pi=acos(-1.0);
int a[maxn];
struct point{
	double x,y;
};
point p[maxn],o;
double dist2(point a,point b)
{
	return(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}

/*double inner(point o_,point p1,point p2)
{
	point h;
	double k1=(p2.x-p1.x)*(o_.x-p1.x)+(p2.y-p1.y)*(o_.y-p1.y);
	double k2=dist2(p1,p2);
	double k=k1/k2;
    h.x=p1.x+(p2.x-p1.x)*k;
    h.y=p1.y+(p2.y-p1.y)*k;
	if((h.x-p1.x)*(p2.y-p1.y)==(p2.x-p1.x)*(h.y-p1.y)&&min(p1.x,p2.x)<=h.x&&h.x<=max(p1.x,p2.x)&&min(p1.y,p2.y)<=h.y&&h.y<=max(p1.y,p2.y))
	return dist2(h,o_);
	else return min(dist2(o_,p1),dist2(o_,p2));
}*/
double inner(point a,point p,point q){
    double d1=(q.x-p.x)*(a.x-p.x)+(q.y-p.y)*(a.y-p.y);
    if(d1<=0)return dist2(a,p);
    double d2=dist2(p,q);
    if(d1>=d2)return dist2(a,q);
    double r=d1/d2;
    point h;//构造垂足
    h.x=p.x+(q.x-p.x)*r;
    h.y=p.y+(q.y-p.y)*r;
    return dist2(h,a);
}
int main()
{
int n;
double max_=-1e18,min_=1e18;
cin>>n>>o.x>>o.y;
for(int i=0;i<n;i++)
{
cin>>p[i].x>>p[i].y;
double dis=dist2(p[i],o);
max_=max(max_,dis);
min_=min(min_,dis);
}
for(int i=0;i<n;++i){
min_=min(min_,inner(o,p[i],p[(i+1)%n]));
}
//cout<<max_<<endl<<min_<<endl;
cout<<setiosflags(ios::fixed)<<setprecision(18)<<pi*(max_-min_);
}


#include <cstdio>
#include <algorithm>
#include <cmath>
#define R register
#define Min(_A, _B) (_A < _B ? _A : _B)
#define Max(_A, _B) (_A > _B ? _A : _B)
int N;
struct Data
{
	double x, y;
	Data operator - (R Data i){ return (Data) {x - i.x, y - i.y}; }
	double operator * (R Data i){ return x * i.y - y * i.x; }
	double operator | (R Data i){ return x * i.x + y * i.y; }
} a[1000010], m;
double c = 1e9, d, Ans, pi = acos(-1);
int main()
{
	scanf("%d %lf %lf", &N, &m.x, &m.y);
	for(R int i = 1; i <= N; i++)
	{
		scanf("%lf %lf", &a[i].x, &a[i].y);
		if(i - 1 && a[i].x == a[i - 1].x && a[i].y == a[i - 1].y)
		{
			i--; N--;
			continue;
		}
		R double C = sqrt((a[i].x - m.x) * (a[i].x - m.x) + (a[i].y - m.y)* (a[i].y - m.y));
		d = Max(C, d);
		c = Min(C, c);
	}
	a[0] = a[N];
	for(R int i = 1; i <= N; i++)
	{
		R double C = (a[i - 1] - m) * (a[i] - m);
		C /= sqrt((a[i].x - a[i - 1].x) * (a[i].x - a[i - 1].x)
					    + (a[i].y - a[i - 1].y)* (a[i].y - a[i - 1].y));
		if(C <= 0) C = -C;
		R double U = (a[i] - a[i - 1]) | (m - a[i - 1]), V = (a[i - 1] - a[i]) | (m - a[i]);
		if(U + 1e-9 > 0 && V + 1e-9 > 0) c = Min(c, C);
	}
	for(R int i = 1; i <= N; i++)
	{
		R double t = (a[i - 1] - m) * (a[i] - m);
		if(t + 1e-9 < 0)
		{
			Ans -= c * c * pi;
			break;
		}
	}
	Ans += d * d * pi;
	printf("%.18lf", Ans);
	return 0;
}


#include<bits/stdc++.h>
#define ll long long
#define ld long double
#define M_PI (2*acos(0))
#define MAX_N 100001
#define apo(a,b) sqrtl( powl(a.x-b.x,2) + powl(a.y-b.y,2) )
using namespace std;

struct point{
    ld x;
    ld y;
};

int main(){

    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    ll n;
    point p;
    cin>>n;
    cin>>p.x>>p.y;

    ld mi= 4000000;
    ld ma= 0;
    point c;

    while(n--){
        cin>>c.x>>c.y;
        ld dis = apo(c,p);
        mi = fminl(dis,mi);
        ma = fmaxl(dis,ma);
    }

    ld ans = (M_PI * powl(ma,2.0)) - (M_PI * powl(mi,2.0));

    cout<<ans<<endl;

}


#include<bits/stdc++.h>
#define ll long long
#define ld long double
#define M_PI (2*acos(0))
#define MAX_N 100001
#define apo(a,b) sqrtl( powl(a.x-b.x,2) + powl(a.y-b.y,2) )
using namespace std;

struct point{
    ld x;
    ld y;
};

vector < point > ps;

int main(){

    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    ll n;
    point p;
    cin>>n;
    cin>>p.x>>p.y;

    ld mi= 4000000;
    ld ma= 0;
    point c;

    point ax; ax.x=0; ax.y=0;

    ld dis;
    ll zn=n;
    while(n--){
        cin>>c.x>>c.y;
        c.x -= p.x;
        c.y -= p.x;
        ps.push_back(c);
        dis = apo(c,ax);
        mi = fminl(dis,mi);
        ma = fmaxl(dis,ma);
    }

    n = zn;
    point ne;
    for(int i=0;i<n;i++){
        c.x = ps[i].x;
        c.y = ps[i].y;
        ne.x = ps[(i+1)%n].x;
        ne.y = ps[(i+1)%n].y;
        dis = 4000000;
        if(c.x == ne.x){
            if(c.y * ne.y < 0){
                dis = c.x;
            }
        }
        else if(c.y == ne.y){
            if(c.x * ne.x < 0){
                dis = c.y;
            }
        }
        else{
            ld kl = (c.y - ne.y) / (c.x - ne.x);
            ld kl2 = (-1) / kl;
            ld b = c.y - (kl * c.x);
            ld xi = b / (kl2 - kl);
            ld yi = (kl * xi) + b;
            point ka;
            ka.x = xi;
            ka.y = yi;
            if( (ka.x>=fminl(c.x,ne.x)) && (ka.y>=fminl(c.y,ne.y)) && (ka.x<=fmaxl(c.x,ne.x)) && (ka.y<=fmaxl(c.y,ne.y)) ){
                dis = apo(ax,ka);
            }
        }
        mi = fminl(dis,mi);
    }
    ld ans = (M_PI * powl(ma,2.0)) - (M_PI * powl(mi,2.0));

    cout<<setprecision(16)<<fixed<<ans<<endl;

}


#include<bits/stdc++.h>
#define ll long long
#define ld long double
#define M_PI (2*acos(0))
#define MAX_N 100001
#define apo(a,b) sqrtl( powl(a.x-b.x,2) + powl(a.y-b.y,2) )
using namespace std;

struct point{
    ld x;
    ld y;
};

vector < point > ps;

int main(){

    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    ll n;
    point p;
    cin>>n;
    cin>>p.x>>p.y;

    ld mi= 4000000;
    ld ma= 0;
    point c;

    point ax; ax.x=0; ax.y=0;

    ld dis;
    ll zn=n;
    while(n--){
        cin>>c.x>>c.y;
        c.x -= p.x;
        c.y -= p.y;
        ps.push_back(c);
        dis = apo(c,ax);
        mi = fminl(dis,mi);
        ma = fmaxl(dis,ma);
    }

    n = zn;
    point ne;
    for(int i=0;i<n;i++){
        c.x = ps[i].x;
        c.y = ps[i].y;
        ne.x = ps[(i+1)%n].x;
        ne.y = ps[(i+1)%n].y;
        dis = 4000000;
        if(c.x == ne.x){
            if(c.y * ne.y < 0){
                dis = c.x;
            }
        }
        else if(c.y == ne.y){
            if(c.x * ne.x < 0){
                dis = c.y;
            }
        }
        else{
            ld kl = (c.y - ne.y) / (c.x - ne.x);
            //cout<<"k1 = "<<kl<<endl;
            ld kl2 = (-1) / kl;
            //cout<<"k2 = "<<kl2<<endl;
            //cout<<"c.x = "<<c.x<<" c.y = "<<c.y<<endl;
            ld b = c.y - (kl * c.x);
            //cout<<"b = "<<b<<endl;
            ld xi = b / (kl2 - kl);
            ld yi = (kl * xi) + b;
            //cout<<"xi = "<<xi<<" yi = "<<yi<<endl;
            point ka;
            ka.x = xi;
            ka.y = yi;
            if( (ka.x>=fminl(c.x,ne.x)) && (ka.y>=fminl(c.y,ne.y)) && (ka.x<=fmaxl(c.x,ne.x)) && (ka.y<=fmaxl(c.y,ne.y)) ){
                dis = apo(ax,ka);
                //cout<<"i = "<<i<<" -> "<<ka.x<<" "<<ka.y<<endl;
            }
        }
        mi = fminl(dis,mi);
    }
    ld ans = (M_PI * powl(ma,2.0)) - (M_PI * powl(mi,2.0));

    cout<<setprecision(16)<<fixed<<ans<<endl;

}


#include<bits/stdc++.h>
#define ll long long
#define ld long double
#define M_PI (2*acos(0))
#define MAX_N 100001
#define apo(a,b) sqrtl( powl(a.x-b.x,2) + powl(a.y-b.y,2) )
using namespace std;

struct point{
    ld x;
    ld y;
};

vector < point > ps;

int main(){

    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    ll n;
    point p;
    cin>>n;
    cin>>p.x>>p.y;

    ld mi= 4000000;
    ld ma= 0;
    point c;

    point ax; ax.x=0; ax.y=0;

    ld dis;
    ll zn=n;
    while(n--){
        cin>>c.x>>c.y;
        c.x -= p.x;
        c.y -= p.x;
        ps.push_back(c);
        dis = apo(c,ax);
        mi = fminl(dis,mi);
        ma = fmaxl(dis,ma);
    }
    n = zn;
    point ne;
    for(int i=0;i<n;i++){
        c.x = ps[i].x;
        c.y = ps[i].y;
        ne.x = ps[(i+1)%n].x;
        ne.y = ps[(i+1)%n].y;
        dis = 4000000;
        if(c.x == ne.x){
            if(c.y * ne.y < 0){
                dis = c.x;
            }
        }
        else if(c.y == ne.y){
            if(c.x * ne.x < 0){
                dis = c.y;
            }
        }
        else{
            ld kl = (c.y - ne.y) / (c.x - ne.x);
            ld kl2 = (-1) / kl;
            ld b = c.y - (kl * c.x);
            ld xi = b / (kl2 - kl);
            ld yi = (kl * xi) + b;
            point ka;
            ka.x = xi;
            ka.y = yi;
            //cout<<ka.x<<" "<<ka.y<<endl;
            dis = apo(ax,ka);
        }
        mi = fminl(dis,mi);
    }
    ld ans = (M_PI * powl(ma,2.0)) - (M_PI * powl(mi,2.0));

    cout<<setprecision(16)<<fixed<<ans<<endl;

}


#include<bits/stdc++.h>
#define ll long long
#define ld long double
#define M_PI (2*acos(0))
#define MAX_N 100001
#define apo(a,b) sqrtl( powl(a.x-b.x,2) + powl(a.y-b.y,2) )
using namespace std;

struct point{
    ld x;
    ld y;
};

int main(){

    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    ll n;
    point p;
    cin>>n;
    cin>>p.x>>p.y;

    ld mi= 4000000;
    ld ma= 0;
    point c;

    while(n--){
        cin>>c.x>>c.y;
        ld dis = apo(c,p);
        mi = fminl(dis,mi);
        ma = fmaxl(dis,ma);
    }

    ld ans = (M_PI * powl(ma,2.0)) - (M_PI * powl(mi,2.0));

    cout<<setprecision(16)<<fixed<<ans<<endl;

}


//
//  main.cpp
//  SnowBlower
//
//  Created by Apple on 5/31/16.
//  Copyright © 2016 AMOSC. All rights reserved.
//

#include <iostream>
#include <cmath>

using namespace std;

long n;
double ax[100001],ay[100001];
double px,py,maxD,minD;
const double pi=3.141592653589793238462643383279502884;

void readFile(){
    scanf("%ld%lf%lf",&n,&px,&py);
    for (int i=1; i<=n; i++){
        scanf("%lf%lf",&ax[i],&ay[i]);
    }

}
double distancetoPoint(long i){
    return (ax[i]-px)*(ax[i]-px) + (ay[i]-py)*(ay[i]-py);
}
double countDistance(double aa, double bb, double cc){
    return abs(aa*px+bb*py+cc)/sqrt(aa*aa+bb*bb);
}
double distancetoEdge(double x1, double y1,double x2, double y2){
    if (y1==y2) return countDistance(0,1,-y1);
    double aa=1;
    double bb= (x2-x1)/(y1-y2);
    double cc= (x1*y2-x2*y1)/(y1-y2);
    return countDistance(aa, bb, cc);
}

double distanceofPoints(double x1, double y1, double x2, double y2){
    return ((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
}
bool satisfy(double x1, double y1, double x2, double y2){
    double edge1 = distanceofPoints(x1, y1, px, py);
    double edge2 = distanceofPoints(x2, y2, px, py);
    double edge3 = distanceofPoints(x1, y1, x2, y2);
    if ((edge1 + edge3 > edge2) && (edge2+edge3 >edge1)) return true;

    return false;
}

void updateMinD(){
    ax[0]=ax[n];ay[0]=ay[n];
    double value;
    for (int i=1; i<=n; i++)
    if (satisfy(ax[i-1], ay[i-1], ax[i], ay[i]) == true) {
        value = distancetoEdge(ax[i-1], ay[i-1], ax[i], ay[i]);

        if (minD>value) minD = value;

    }
}
void handleData(){
    minD = 1e14;
    maxD =0;

    double value;
    for (int i=1; i<=n; i++){
        value = distancetoPoint(i);

        if (minD>value) minD = value;
        if (value>maxD) maxD = value;
    }
    updateMinD();

    double result  = (maxD-minD)*pi;
    printf("%2.12f",result);

}

int main(int argc, const char * argv[]) {
    // insert code here...
    readFile();
    handleData();
    return 0;
}


//
//  main.cpp
//  SnowBlower
//
//  Created by Apple on 5/31/16.
//  Copyright © 2016 AMOSC. All rights reserved.
//

#include <iostream>
#include <cmath>

using namespace std;

long n;
double ax[100001],ay[100001];
double px,py,maxD,minD;
const double pi=3.141592653589793238462643383279502884;

void readFile(){
    scanf("%ld%lf%lf",&n,&px,&py);
    for (int i=1; i<=n; i++){
        scanf("%lf%lf",&ax[i],&ay[i]);
    }

}
double distancetoPoint(long i){
    return (ax[i]-px)*(ax[i]-px) + (ay[i]-py)*(ay[i]-py);
}
double countDistance(double aa, double bb, double cc){
    return abs(aa*px+bb*py+cc)/sqrt(aa*aa+bb*bb);
}
double distancetoEdge(double x1, double y1,double x2, double y2){
    if (y1==y2) return countDistance(0,1,-y1);
    double aa=1;
    double bb= (x2-x1)/(y1-y2);
    double cc= (x1*y2-x2*y1)/(y1-y2);
    return countDistance(aa, bb, cc);
}
double distanceofPoints(double x1, double y1, double x2, double y2){
    return ((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
}
bool satisfy(double x1, double y1, double x2, double y2){
    double edge1 = distanceofPoints(x1, y1, px, py);
    double edge2 = distanceofPoints(x2, y2, px, py);
    double edge3 = distanceofPoints(x1, y1, x2, y2);
    if ((edge1 + edge3 > edge2) && (edge2+edge3 >edge1)) return true;

    return false;
}

void updateMinD(){
    ax[0]=ax[n];ay[0]=ay[n];
    double value;
    for (int i=1; i<=n; i++)
    if (satisfy(ax[i-1], ay[i-1], ax[i], ay[i]) == true) {
        value = distancetoEdge(ax[i-1], ay[i-1], ax[i], ay[i]);

        if (minD>value) minD = value;

    }
}
void handleData(){
    minD = 1e13;
    maxD =0;

    double value;
    for (int i=1; i<=n; i++){
        value = distancetoPoint(i);

        if (minD>value) minD = value;
        if (value>maxD) maxD = value;
    }
    updateMinD();

    double result  = (maxD-minD)*pi;
    printf("%2.9f",result);

}

int main(int argc, const char * argv[]) {
    // insert code here...
    readFile();
    handleData();
    return 0;
}


//
//  main.cpp
//  SnowBlower
//
//  Created by Apple on 5/31/16.
//  Copyright © 2016 AMOSC. All rights reserved.
//

#include <iostream>
#include <cmath>

using namespace std;

long n;
double ax[100001],ay[100001];
double px,py;

void readFile(){
    cin>>n>>px>>py;
    for (int i=1; i<=n; i++){
        cin>>ax[i]>>ay[i];
    }

}
double distancetoPoint(long i){
    return (ax[i]-px)*(ax[i]-px) + (ay[i]-py)*(ay[i]-py);
}
void handleData(){
    double minD = 1e13;

    double maxD =0;
    double value;
    for (int i=1; i<=n; i++){
        value = distancetoPoint(i);

        if (minD>value) minD = value;
        if (value>maxD) maxD = value;
    }
    double result  = (maxD-minD)*M_PI;
    printf("%2.9f",result);

}
int main(int argc, const char * argv[]) {
    // insert code here...
    readFile();
    handleData();
    return 0;
}


//
//  main.cpp
//  SnowBlower
//
//  Created by Apple on 5/31/16.
//  Copyright © 2016 AMOSC. All rights reserved.
//

#include <iostream>
#include <cmath>

using namespace std;

long n;
double ax[100001],ay[100001];
double px,py,maxD,minD;
const double pi=3.141592653589793238462643383279502884;

void readFile(){
    scanf("%ld%lf%lf",&n,&px,&py);
    for (int i=1; i<=n; i++){
        scanf("%lf%lf",&ax[i],&ay[i]);
    }

}
double distancetoPoint(long i){
    return (ax[i]-px)*(ax[i]-px) + (ay[i]-py)*(ay[i]-py);
}
double countDistance(double aa, double bb, double cc){
    return abs(aa*px+bb*py+cc)/sqrt(aa*aa+bb*bb);
}
double distancetoEdge(double x1, double y1,double x2, double y2){
    if (y1==y2) return countDistance(0,1,-y1);
    double aa=1;
    double bb= (x2-x1)/(y1-y2);
    double cc= (x1*y2-x2*y1)/(y1-y2);
    return countDistance(aa, bb, cc);
}

double distanceofPoints(double x1, double y1, double x2, double y2){
    return ((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
}
bool satisfy(double x1, double y1, double x2, double y2){
    double edge1 = distanceofPoints(x1, y1, px, py);
    double edge2 = distanceofPoints(x2, y2, px, py);
    double edge3 = distanceofPoints(x1, y1, x2, y2);
    if ((edge1 + edge3 > edge2) && (edge2+edge3 >edge1)) return true;

    return false;
}

void updateMinD(){
    ax[0]=ax[n];ay[0]=ay[n];
    double value;
    for (int i=1; i<=n; i++)
    if (satisfy(ax[i-1], ay[i-1], ax[i], ay[i]) == true) {
        value = distancetoEdge(ax[i-1], ay[i-1], ax[i], ay[i]);
        value = value*value;

        if (minD>value) minD = value;

    }
}
void handleData(){
    minD = 1e14;
    maxD =0;

    double value;
    for (int i=1; i<=n; i++){
        value = distancetoPoint(i);

        if (minD>value) minD = value;
        if (value>maxD) maxD = value;
    }
    updateMinD();

    double result  = (maxD-minD)*pi;
    printf("%2.12f",result);

}

int main(int argc, const char * argv[]) {
    // insert code here...
    readFile();
    handleData();
    return 0;
}


//
//  main.cpp
//  SnowBlower
//
//  Created by Apple on 5/31/16.
//  Copyright © 2016 AMOSC. All rights reserved.
//

#include <iostream>
#include <cmath>

using namespace std;

long n;
double ax[100001],ay[100001];
double px,py;

void readFile(){
    scanf("%ld%lf%lf",&n,&px,&py);
    for (int i=1; i<=n; i++){
        scanf("%lf%lf",&ax[i],&ay[i]);
    }

}
double distancetoPoint(long i){
    return (ax[i]-px)*(ax[i]-px) + (ay[i]-py)*(ay[i]-py);
}
void handleData(){
    double minD = 1e13;

    double maxD =0;
    double value;
    for (int i=1; i<=n; i++){
        value = distancetoPoint(i);

        if (minD>value) minD = value;
        if (value>maxD) maxD = value;
    }
    double result  = (maxD-minD)*M_PI;
    printf("%2.9f",result);

}
int main(int argc, const char * argv[]) {
    // insert code here...
    readFile();
    handleData();
    return 0;
}