#include <iostream> #include <cstdio> #define Max 500010 using namespace std; void read(int &x) { x=0;int f=1; char ch=getchar(); while(ch>'9'||ch<'0') { if(ch=='-') f=-1; ch=getchar(); } while(ch>='0'&&ch<='9') { x=x*10+(int)ch-48; ch=getchar(); } x*=f; } struct Point { int fa; int deep; int chain; int size; }point[Max]; struct Edge { int from,to,next; }edge[Max<<1]; int head[Max]; int tot; int count; inline void add(int from,int to) { tot++; edge[tot].from=from; edge[tot].to=to; edge[tot].next=head[from]; head[from]=tot; } void dfs1(int now,int father) { int pos=count++; point[now].fa=father; point[now].deep=point[point[now].fa].deep+1; for(int i=head[now];i;i=edge[i].next) { if(edge[i].to==father) continue; dfs1(edge[i].to,now); } point[now].size=count-pos; } void dfs2(int now,int chain) { int pos=0; point[now].chain=chain; for(int i=head[now];i;i=edge[i].next) { if(point[edge[i].to].chain) continue; if(point[pos].size<point[edge[i].to].size) pos=edge[i].to; } if(pos) dfs2(pos,chain); else return; for(int i=head[now];i;i=edge[i].next) { if(edge[i].to==pos||edge[i].to==point[now].fa) continue; dfs2(edge[i].to,edge[i].to); } } int LCA(int x,int y) { while(point[x].chain!=point[y].chain) { if(point[point[x].chain].deep<point[point[y].chain].deep) swap(x,y); x=point[point[x].chain].fa; } return point[x].deep<point[y].deep?x:y; } int Root,M,N,x,y; int main() { read(N); read(M); read(Root); for(int i=1;i<N;++i) { read(x); read(y); add(x,y); add(y,x); } dfs1(Root,0); count=0; dfs2(Root,Root); while(M--) { read(x);read(y); printf("%d ",LCA(x,y)); } return 0; }