#include<fstream>
#include<vector>
#include<algorithm>
#define DIM 100001
#define pb push_back
#define INF 0x3f3f3f3f
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
vector< int > G[DIM];
int Tata[DIM], N, contor, Euler[DIM *2], Lev[DIM*2], First[DIM], minim, pos, M, a, b, A[DIM << 4];
int hsol, sol, st, dr;
bool viz[DIM];
void DFs(int node, int level)
{
viz[node] = 1;
Lev[++contor] = level;
Euler[contor] = node;
First[node] = contor;
for(vector< int > ::iterator it = G[node].begin(); it != G[node].end(); ++it)
if( !viz[*it] )
{
DFs(*it, level+1);
Euler[++contor] = node;
Lev[contor] = level;
}
}
void Build(int nod, int st, int dr)
{
if(st == dr)
{
A[nod] = st;
return;
}
else
{
int mid =st + (dr-st)/2;
Build(2*nod, st, mid);
Build(2*nod+1, mid+1, dr);
if(Lev[A[2*nod]] <= Lev[A[2*nod+1]])
A[nod] = A[2*nod];
else
A[nod] = A[2*nod+1];
}
}
void Query(int nod, int li, int lf)
{
if(st <= li && lf <= dr)
{
if(Lev[A[nod]] < hsol)
sol = Euler[A[nod]],
hsol = Lev[A[nod]];
return;
}
else
{
int mid = li + (lf-li)/2;
if(st <= mid) Query(2*nod, li, mid);
if(mid < dr) Query(2*nod+1, mid+1, lf);
}
}
int lca(int x, int y)
{
st = First[x];
dr = First[y];
if( st > dr )
swap(st, dr);
sol = hsol = INF;
Query(1, 1, contor);
return sol;
}
int main()
{
int i, a, b;
in >> N >> M;
for(i = 2; i <= N; i++)
{
in >> Tata[i];
G[Tata[i]].pb(i);
}
DFs(1, 0);
Build(1, 1, contor);
for(i = 1; i <= M; i++)
{
in >> a >> b;
out << lca(a,b) << '\n';
}
}