#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[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{
int aint[4*dim];
void update(int nod,int tl,int tr,int poz,int val){
if(tl==tr){
aint[nod]=val;
return;
}
int tm=(tl+tr)/2;
if(poz<=tm){
update(2*nod,tl,tm,poz,val);
}
else{
update(2*nod+1,tm+1,tr,poz,val);
}
aint[nod]=(nivel[aint[2*nod]]<nivel[aint[2*nod+1]]) ? aint[2*nod]:aint[2*nod+1];
}
int 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);
}
int n1=query(2*nod,tl,tm,l,tm);
int n2=query(2*nod+1,tm+1,tr,tm+1,r);
return (nivel[n1]<nivel[n2]) ? n1 : n2;
}
}B;
void find_lca(){
DFS(1,0);
for(int i=1;i<=len;i++){
B.update(1,1,len,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);
}
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';
}
}