#include <iostream>
#include <fstream>
#include <stack>
#include <queue>
#include <vector>
#include <map>
#include <cctype>
#include <unordered_map>
#include <cmath>
#include <bitset>
#include <set>
#include <string>
#include <cstring>
#include <algorithm>
#include <deque>
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
typedef pair <int,int>iPair;
int a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,S,t,x,y,z,ok,nr,C,xc,yc,Min,w,weight,u,v,ans,cost,Max,MOD,val,lvl,sum,MAX,current,st,dr,BASE,mid,semn;
int parent[100005];
int euler[500005];
int depth[500005];
int rpoz[100005];
vector <int>fii[100005];
struct RR {
int mn,poz;
};
RR rmq[600005][25];
int blog[500005];
void ParcEuler(int k){
euler[++l]=k;
for(auto w:fii[k]){
ParcEuler(w);
}
euler[++l]=k;
}
void Dfind(int k,int d){
depth[k]=d;
for(auto w:fii[k]){
Dfind(w,d+1);
}
}
int main()
{
in>>n>>m;
parent[1]=1;
for(i=2;i<=n;i++){
in>>parent[i];
fii[parent[i]].push_back(i);
}
l=0;
ParcEuler(1);
Dfind(1,1);
for(i=1;i<=l;i++){
rpoz[euler[i]]=i;
}
for(i=1;i<=l;i++){
rmq[i][0].mn=depth[euler[i]];
rmq[i][0].poz=i;
}
for(j=1;(1<<j)<=l;j++){
for(i=1;i+(1<<j)-1<=l;i++){
if(rmq[i][j-1].mn<rmq[i+(1<<j-1)][j-1].mn){
rmq[i][j].mn=rmq[i][j-1].mn;
rmq[i][j].poz=rmq[i][j-1].poz;
}
else{
rmq[i][j].mn=rmq[i+(1<<j-1)][j-1].mn;
rmq[i][j].poz=rmq[i+(1<<j-1)][j-1].poz;
}
}
}
blog[1]=0;
for(i=2;i<=l+2;i++){
blog[i]=blog[i/2]+1;
}
for(i=1;i<=m;i++){
in>>x>>y;
if(rpoz[x]>rpoz[y]) {swap(x,y);}
s=rpoz[y]-rpoz[x]+1;
if(rmq[rpoz[x]][blog[s]].mn<rmq[rpoz[y]-(1<<blog[s])+1][blog[s]].mn){
out<<euler[rmq[rpoz[x]][blog[s]].poz]<<'\n';
}
else {
out<<euler[rmq[rpoz[y]-(1<<blog[s])+1][blog[s]].poz]<<'\n';
}
}
return 0;
}