#include <bits/stdc++.h>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int dim=100009;
vector<int>v[dim];
int len,nivel[dim];
int euler[2*dim],aparitie[2*dim];
void DFS(int x,int tata){
euler[++len]=x;
nivel[x]=nivel[tata]+1;
aparitie[x]=len;
for(int y:v[x]){
DFS(y,x);
euler[++len]=x;
}
}
struct SegmentTree{
struct Nod{
int val,poz;
}aint[8*dim];
Nod Merge(Nod n1,Nod n2){
if(n1.val<n2.val){
return n1;
}
return n2;
}
void update(int nod,int tl,int tr,int poz,Nod x){
if(tl==tr){
aint[nod].val=x.val;
aint[nod].poz=x.poz;
return;
}
int tm=(tl+tr)/2;
if(poz<=tm){
update(2*nod,tl,tm,poz,x);
}
else{
update(2*nod+1,tm+1,tr,poz,x);
}
aint[nod]=Merge(aint[2*nod],aint[2*nod+1]);
}
Nod query(int nod,int tl,int tr,int l,int r){
if(l==tl && r==tr){
return aint[nod];
}
int tm=(tl+tr)/2;
if(r<=tm){
return query(2*nod,tl,tm,l,r);
}
if(l>tm){
return query(2*nod+1,tm+1,tr,l,r);
}
return Merge(query(2*nod,tl,tm,l,tm),query(2*nod+1,tm+1,tr,tm+1,r));
}
}B;
void find_lca(){
DFS(1,0);
for(int i=1;i<=len;i++){
B.update(1,1,len,i,{nivel[euler[i]],euler[i]});
}
}
int lca(int a,int b){
a=aparitie[a];
b=aparitie[b];
if(a>b){
swap(a,b);
}
return B.query(1,1,len,a,b).poz;
}
signed main(){
int n,q;
fin>>n>>q;
for(int i=2;i<=n;i++){
int j;
fin>>j;
v[j].push_back(i);
}
find_lca();
while(q--){
int l,r;
fin>>l>>r;
fout<<lca(l,r)<<'\n';
}
}