#include<iostream>
#include<fstream>
#include<string.h>
#include<algorithm>
#include<vector>
using namespace std;
#define NMAX 100001
#define INF 1<<30
vector <int> v[NMAX],path[NMAX];
int viz[NMAX],whatpath[NMAX],whatpoz[NMAX],p[NMAX],w[NMAX],t[NMAX],lev[NMAX],nr,c[NMAX],sol1,sol2;
vector <int> a1[NMAX],a2[NMAX];
void dfs(int nod)
{
int frunza;
viz[nod]=1;
frunza=0;
w[nod]=1;
for(vector <int> :: iterator it=v[nod].begin();it!=v[nod].end();it++)
if(viz[*it]==0) {
t[*it]=nod;
lev[*it]=lev[nod]+1;
dfs(*it);
w[nod]=w[nod]+w[*it];
if(frunza==0)
frunza=*it;
else if(w[frunza]<w[*it])
frunza=*it;
}
if(frunza==0) {
nr++;
path[nr].push_back(nod);
whatpath[nod]=nr;
}
else {
path[whatpath[frunza]].push_back(nod);
whatpath[nod]=whatpath[frunza];
}
}
void build_paths()
{
int i,j;
for(i=1;i<=nr;i++) {
reverse(path[i].begin(),path[i].end());
a1[i].resize(4*path[i].size()+1);
a2[i].resize(4*path[i].size()+1);
for(j=0;j<=4*path[i].size();j++) {
a1[i][j]=-1;
a2[i][j]=-1;
}
for(vector <int> :: iterator it=path[i].begin();it!=path[i].end();it++)
whatpoz[*it]=it-path[i].begin();
p[i]=t[path[i][0]];
}
}
int LCA(int x, int y)
{
if(whatpath[x]==whatpath[y]) {
if(lev[x]<=lev[y])
return x;
else return y;
}
int p1=p[whatpath[x]];
int p2=p[whatpath[y]];
if(lev[p2]<lev[p1] || (lev[p2]==lev[p1] && p2==0)) {
swap(p1,p2);
swap(x,y);
}
return LCA(x,p2);
}
void update2(int nod, int st, int dr, int poz, int arb, int val)
{
if(st==dr) {
if(val==1)
a2[arb][nod]=st;
else a2[arb][nod]=-1;
return;
}
int mij;
mij=(st+dr)/2;
if(poz<=mij)
update2(nod*2,st,mij,poz,arb,val);
else update2(nod*2+1,mij+1,dr,poz,arb,val);
if(a2[arb][nod*2+1]==-1)
a2[arb][nod]=a2[arb][nod*2];
else a2[arb][nod]=a2[arb][nod*2+1];
}
void update1(int nod, int st, int dr, int poz, int arb, int val)
{
if(st==dr) {
if(val==1)
a1[arb][nod]=st;
else a1[arb][nod]=-1;
return;
}
int mij;
mij=(st+dr)/2;
if(poz<=mij)
update1(nod*2,st,mij,poz,arb,val);
else update1(nod*2+1,mij+1,dr,poz,arb,val);
if(a1[arb][nod*2]==-1)
a1[arb][nod]=a1[arb][nod*2+1];
else a1[arb][nod]=a1[arb][nod*2];
}
void query2(int nod, int st, int dr, int a, int b, int arb)
{
if(a<=st && dr<=b) {
if(sol2==-1 && a2[arb][nod]!=-1)
sol2=path[arb][a2[arb][nod]];
return ;
}
int mij;
mij=(st+dr)/2;
if(mij<b)
query2(nod*2+1,mij+1,dr,a,b,arb);
if(a<=mij)
query2(nod*2,st,mij,a,b,arb);
}
void query1(int nod, int st, int dr, int a, int b, int arb)
{
if(a<=st && dr<=b) {
cout<<a1[arb][nod]<<endl;
if(sol1==-1 && a1[arb][nod]!=-1)
sol1=path[arb][a1[arb][nod]];
return ;
}
int mij;
mij=(st+dr)/2;
if(a<=mij)
query1(nod*2,st,mij,a,b,arb);
if(mij<b)
query1(nod*2+1,mij+1,dr,a,b,arb);
}
void solve1(int x, int y)
{
if(whatpath[x]==whatpath[y]) {
query2(1,0,path[whatpath[x]].size()-1,whatpoz[y],whatpoz[x],whatpath[x]);
return ;
}
query2(1,0,path[whatpath[x]].size()-1,0,whatpoz[x],whatpath[x]);
solve1(p[whatpath[x]],y);
}
void solve2(int x, int y)
{
if(whatpath[x]==whatpath[y]) {
query1(1,0,path[whatpath[x]].size()-1,whatpoz[x],whatpoz[y],whatpath[x]);
return ;
}
query1(1,0,path[whatpath[y]].size()-1,0,whatpoz[y],whatpath[y]);
solve2(x,p[whatpath[y]]);
}
int main ()
{
int n,x,y,i,m,op,lca;
ifstream f("lca.in");
ofstream g("lca.out");
f>>n>>m;
for(i=1;i<=n-1;i++) {
f>>x;
v[i+1].push_back(x);
v[x].push_back(i+1);
}
dfs(1);
build_paths();
for(i=1;i<=m;i++) {
f>>x>>y;
g<<LCA(x,y)<<'\n';
}
f.close();
g.close();
return 0;
}