namespace lca{//树_最近公共祖先
const int NN=500005;//最大点数
const int MM=500005;//最大边数
int head[NN],N,n;//存图用的,N为点数,N-1条边
int d[NN],fa[NN][31];// 点深度(根为1),往上的第2^N个祖先
struct node{
int x,nex,d;
};
node a[MM<<1];
void add(int x,int y,int d){//建边,x->y,长度为d
n++;
a[n].x=y,a[n].d=d,a[n].nex=head[x];
head[x]=n;
}
void dfs(int x,int k,int f){
fa[x][0]=f,d[x]=k;
for(int i=head[x];i;i=a[i].nex){
if(a[i].x==f) continue;
dfs(a[i].x,k+1,x);
}
}
void pre(int x){//从根节点x开始预处理
for(int i=1;i<=N;++i){
for(int j=0;j<=30;++j){
fa[i][j]=-1;
}
}
dfs(x,1,x);
for(int j=1;j<=30;++j){
for(int i=1;i<=N;++i){
if(fa[i][j-1]==-1) continue;
fa[i][j]=fa[fa[i][j-1]][j-1];
}
}
}
int lca(int x,int y){//返回x,y的最近公共祖先
if(d[x]>d[y]) swap(x,y);
for(int i=30;i>=0;--i){
int y_=fa[y][i];
if(y_==-1||d[y_]<d[x]) continue;
y=y_;
}
if(x==y) return x;
for(int i=30;i>=0;--i){
int x_=fa[x][i],y_=fa[y][i];
if(x_==-1||y==-1||x_==y_) continue;
x=x_,y=y_;
}
return fa[x][0];
}
}