#include<iostream>#include<algorithm>#include<cstring>#include<vector>#include<cstdio>#define mem(a, b) memset(a, b, sizeof(a))usingnamespace std;constint maxn =5e5+10;struct node{
int v, nex;}edge[maxn <<1];struct Node{
int v, id;};int father[maxn], head[maxn], ans[maxn];int n, m, r, cnt;
vector<Node> q[maxn];bool vis[maxn <<1];voidinit(){
mem(head,-1);for(int i =0; i < maxn; i++)
father[i]= i;}voidaddedge(int u,int v)//链式向前星存边{
edge[cnt].v = v;
edge[cnt].nex = head[u];
head[u]= cnt++;}intfind(int x){
int cur = x;while(x != father[x]){
x = father[x];}while(cur != x){
int z = cur;
cur = father[z];
father[z]= x;}return x;}voidUnion(int x,int fa){
int fx =find(x);int fy =find(fa);if(fx != fy)
father[fx]= fy;}voidtarjan(int u){
vis[u]=true;//标记 for(int i = head[u]; i !=-1; i = edge[i].nex)//遍历当前节点的儿子{
int v = edge[i].v;if(vis[v])continue;//若访问过, 跳过,主要是为了防止查找其父亲节点,若是单向边可以省去 tarjan(v);Union(v, u);//将v的并到u的祖先里 }
vector<Node>::iterator it = q[u].begin();for(; it != q[u].end(); it++)//需要查找的边里有没有以u为起点 {
if(vis[(*it).v]){
ans[(*it).id]=find((*it).v);//若访问过,则该组答案就是此时v的祖先 }}}intmain(){
init();// cin >> n >> m >> r;scanf("%d%d%d",&n,&m,&r);int x, y;for(int i =0; i < n -1; i++){
// cin >> x >> y;scanf("%d%d",&x,&y);addedge(x, y);addedge(y, x);}for(int i =0; i < m; i++){
// cin >> x >> y;scanf("%d%d",&x,&y);
Node cur;
cur.v = y;
cur.id = i;
q[x].push_back(cur);
cur.v = x;
q[y].push_back(cur);}tarjan(r);for(int i =0; i < m; i++)printf("%d\n", ans[i]);// cout << ans[i] << endl;return0;}