# 约束RMQ

(怎么做呢？把这段二进制数提出来，移到最右边，由于我们规定0表示小于，1表示大于，所以会贪心地选取前面的数，查表减去偏移量就可以了)

int MYLOG (unsigned int x) {
static const int log_2[256] = {
0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
};
int l = -1;
while (x >= 256) { l += 8; x >>= 8; }
return l + log_2[x];
} 

//drunk,fix later
#include<iostream>
#include<cstdio>
#include<cmath>
#define Re register
using namespace std;

const int MAXN=1000005;

inline int rd() {
int ret=0,f=1;
char c;
while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
while(isdigit(c))ret=ret*10+c-'0',c=getchar();
return ret*f;
}

int n,m,st;

struct Edge {
int next,to;
} e[MAXN<<1];
inline void add(int x,int y) {
e[ecnt].to = y;
}

int appear[MAXN],elm[MAXN],dep[MAXN],tot;
void dfs(int x,int pre) {
appear[x]=++tot;
elm[tot]=x;
dep[tot]=dep[appear[pre]]+1;
int v=e[i].to;
if(v==pre) continue;
dfs(v,x);
elm[++tot]=x;
dep[tot]=dep[appear[x]];
}
}

int blockLen,num,L[MAXN],R[MAXN],bl[MAXN];
int blockTyp[MAXN],f[MAXN][32],g[MAXN][32];
int lookUp[MAXN];
inline int computeType(int x) {
int sum=0;
for(Re int i=L[x]; i<=R[x]-1; i++)
sum<<=1,sum+=(dep[i+1]>dep[i]);
return sum;
}

inline void calcPos(int x) {
int len=0,po=0,cnt=0,mn=1<<30,mnid;
len=blockLen;
for(Re int i=len; i>=0; i--) {
po++;
if((1<<i)&x) cnt++;
else cnt--;
if(cnt<mn) mn=cnt,mnid=po;
}
lookUp[x]=mnid-1;
}

void build() {
blockLen=log2(tot)/2;
num=tot/blockLen;
if(tot%blockLen) num++;
for(Re int i=1; i<=num; i++) {
L[i]=(i-1)*blockLen+1;
R[i]=i*blockLen;
}
for(Re int i=tot+1; i<=R[num]; i++) dep[i]=(1<<30);
for(Re int i=1; i<=tot; i++)bl[i]=(i-1)/blockLen+1;
for(Re int i=0; i*i<=tot; i++) calcPos(i);
for(Re int i=1; i<=num; i++)blockTyp[i]=computeType(i);
for(Re int i=1; i<=num; i++) g[i][0]=(i-1)*blockLen+lookUp[blockTyp[i]],f[i][0]=dep[g[i][0]]; //offset!
for(Re int j=1; (1<<j)<=num; j++)
for(Re int i=1; i<=num; i++)
if(f[i][j-1]<f[i+(1<<(j-1))][j-1]) f[i][j]=f[i][j-1],g[i][j]=g[i][j-1];
else f[i][j]=f[i+(1<<(j-1))][j-1],g[i][j]=g[i+(1<<(j-1))][j-1];
}

inline int inBlockQuery(int x,int y) {
int u=blockTyp[bl[x]],v=(bl[x]-1)*blockLen+lookUp[u];
if(x<=v&&v<=y) return v;
int sav=bl[x];
x-=L[sav]-1;y-=L[sav]-1;
u>>=(blockLen-y);
u&=(~((-1)<<(y-x)));
return (sav-1)*blockLen+lookUp[u]-(blockLen-y);
}

int query(int x,int y) {
if(bl[x]==bl[y]) return inBlockQuery(x,y);
int mn=1<<30,mnid,tmp;
tmp=inBlockQuery(x,R[bl[x]]);
if(dep[tmp]<mn) mn=dep[tmp],mnid=tmp;
tmp=inBlockQuery(L[bl[y]],y);
if(dep[tmp]<mn) mn=dep[tmp],mnid=tmp;
int l=bl[x]+1,r=bl[y]-1,len;
if((r-l+1>0))  len=log2(r-l+1);
else return mnid;
if(f[l][len]<mn) mn=f[l][len],mnid=g[l][len];
if(f[r-(1<<len)+1][len]<mn) mn=f[r-(1<<len)+1][len],mnid=g[r-(1<<len)+1][len];
return mnid;
}

int main() {
n=rd();m=rd();st=rd();
int x,y;
for(Re int i=1; i<=n-1; i++) {
x=rd();y=rd();
}