#include <bits/stdc++.h>
using namespace std;
const int NMAX=1e6+6;
vector <int> G[NMAX];
bitset <NMAX> Pus;
vector <pair <int, int> >A;
int N, M, i, X, position[NMAX], u, v, nn, solmax=INT_MAX, solafis;
int Arbore[5*NMAX], Arbore2[5*NMAX];
map <int, vector <int> > Mp;
void DFS (int Nod, int Nivel)
{
Pus.set(Nod);
A.push_back({Nod, Nivel});
if(!position[Nod])
position[Nod]=A.size()-1;
for(int i=0; i<G[Nod].size(); i++)
if(Pus[G[Nod][i]]==0)
{
Pus.set(G[Nod][i]);
DFS(G[Nod][i], Nivel+1);
A.push_back({Nod, Nivel});
}
}
void Update (int nod, int a, int b, int poz, int val)
{
if(a==b)
{
Arbore[nod]=val;
Arbore2[nod]=A[poz-1].first;
return;
}
int mij=(a+b)/2;
if(poz<=mij)
Update(2*nod, a, mij, poz, val);
if(poz>mij)
Update(2*nod+1, mij+1, b, poz, val);
if(Arbore[2*nod]<Arbore[2*nod+1])
{
Arbore[nod]=Arbore[2*nod];
Arbore2[nod]=Arbore2[2*nod];
}
else
{
Arbore[nod]=Arbore[2*nod+1];
Arbore2[nod]=Arbore2[2*nod+1];
}
}
int Query (int nod, int a, int b, int qa, int qb)
{
if(qa<=a && b<=qb)
{
if(Arbore[nod]<solmax)
{
solmax=Arbore[nod];
solafis=Arbore2[nod];
}
return Arbore[nod];
}
int mij=(a+b)/2;
int ans1=INT_MAX, ans2=INT_MAX;
if(qa<=mij)
ans1=Query(2*nod, a, mij, qa, qb);
if(qb>mij)
ans2=Query(2*nod+1, mij+1, b, qa, qb);
return min(ans1, ans2);
}
int solve (int u, int v)
{
int i=position[u];
int j=position[v];
if(i==j)
return A[i].first;
if(i>j)
swap(i, j);
i++;
j++;
solmax=solafis=INT_MAX;
int ans=Query(1, 1, 2*N-1, i, j);
return solafis;
}
int main()
{
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
scanf("%d%d", &N, &M);
for(i=2; i<=N; i++)
{
scanf("%d", &X);
G[X].push_back(i);
}
DFS(1, 1);
A.pop_back();
for(i=1; i<=2*N-1; i++)
Update(1, 1, 2*N-1, i, A[i-1].second);
for(i=1; i<=M; i++)
{
scanf("%d%d", &u, &v);
printf("%d\n", solve(u, v));
}
return 0;
}