struct _ {int l,r,ls,rs,sum;}tree[maxn*20];
int segtot,root[maxn],id[maxn];
int upd(int l,int r,int pos,int val)
{
int rt=++segtot;
tree[rt].l=l,tree[rt].r=r,tree[rt].sum=val;
if (l == r) return rt;
int mid=(l+r) >> 1;
if (pos<=mid) tree[rt].ls=upd(l,mid,pos,val);
else tree[rt].rs=upd(mid+1,r,pos,val);
return rt;
}
int mer(int ra,int rb,int l,int r)
{
if (!ra && !rb) return 0;
if (!ra) return ra;if (!rb) return ra;
int rt=ra;
tree[rt].l=l,tree[rt].r=r,tree[rt].sum=tree[ra].sum+tree[rb].sum;
int mid=(l+r) >> 1;
tree[rt].ls=mer(tree[ra].ls,tree[rb].ls,l,mid);
tree[rt].rs=mer(tree[ra].rs,tree[rb].rs,mid+1,r);
return rt;
}
struct _ {int ls,rs,cnt;}tree[maxn*20];
int n,k;
int h[maxn],to[maxn],nxt[maxn],tot;
int p[maxn],b[maxn];
int root[maxn],segtot;
int ans[maxn];
void add(int x,int y) {tot++;to[tot]=y;nxt[tot]=h[x];h[x]=tot;}
void update(int &rt,int l,int r,int pos,int val)
{
if (!rt) rt=++segtot;
if (l == r) {tree[rt].cnt+=val;return;}
int mid=(l+r-1) >> 1;
if (pos<=mid) update(lson,l,mid,pos,val);
else update(rson,mid+1,r,pos,val);
tree[rt].cnt=tree[lson].cnt+tree[rson].cnt;
}
int merge(int ra,int rb)
{
if (!ra) return rb;if (!rb) return ra;
tree[ra].cnt+=tree[rb].cnt;
tree[ra].ls=merge(tree[ra].ls,tree[rb].ls);
tree[ra].rs=merge(tree[ra].rs,tree[rb].rs);
return ra;
}
int query(int rt,int l,int r,int val)
{
if (!rt) return 0;
if (l == r) return tree[rt].cnt;
int mid=(l+r-1) >> 1;
if (val<=mid) return query(lson,l,mid,val)+tree[rson].cnt;
else return query(rson,mid+1,r,val);
}
void dfs(int x)
{
for (int i=h[x];i;i=nxt[i])
{
int y=to[i];
dfs(y);
root[x]=merge(root[x],root[y]);
}
ans[x]=query(root[x],1,k,p[x])-1;
}