struct val_seg_tree
{
int l,r;
}t[6400005];
int segcnt,rt[400005];
void modify(int &pos,int l,int r,int k)
{
if(!pos)pos=++segcnt;
if(l==r)return; int mid=(l+r)>>1;
if(k<=mid)modify(ls(pos),l,mid,k);
else modify(rs(pos),mid+1,r,k);
}
bool query(int pos,int l,int r,int L,int R)
{
if(!pos)return false;
if(L<=l&&r<=R)return true; int mid=(l+r)>>1;
if(L<=mid&&query(ls(pos),l,mid,L,R))return true;
if(R>mid&&query(rs(pos),mid+1,r,L,R))return true;
return false;
}
int merge(int x,int y,int l,int r)
{
if(!x||!y)return x|y;
int pos=++segcnt,mid=(l+r)>>1;
ls(pos)=merge(ls(x),ls(y),l,mid);
rs(pos)=merge(rs(x),rs(y),mid+1,r);
return pos;
}
vector<int>e[400005];
struct SAM
{
int len,fa,ch[26];
}tr[400005];
int cnt=1,lst=1;
void insert(int c)
{
int p=lst,np=lst=++cnt;tr[np].len=tr[p].len+1;
for(;p&&!tr[p].ch[c];p=tr[p].fa)tr[p].ch[c]=np;
if(!p){tr[np].fa=1;return;} int q=tr[p].ch[c];
if(tr[q].len==tr[p].len+1){tr[np].fa=q;return;}
int nq=++cnt;tr[nq]=tr[q];tr[nq].len=tr[p].len+1;
tr[np].fa=tr[q].fa=nq;
for(;p&&tr[p].ch[c]==q;p=tr[p].fa)tr[p].ch[c]=nq;
}
void dfs(int x)
{
for(int i=0;i<(int)e[x].size();++i)
{
int y=e[x][i];dfs(y);
rt[x]=merge(rt[x],rt[y],1,n);
}
}