#include <iostream>
#include <fstream>
#include <vector>
#include <stack>
#define INF 10000000000
#define MAX_N 100001
#define nst (nod <<1)
#define ndr (nst | 1)
#define mij ((li+ls)>>1)
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
int n,m,dads[MAX_N],viz[MAX_N],adi[MAX_N<<4],l[MAX_N<<1],sol,hsol,first[MAX_N];
vector <int> rep_euler;
vector <vector <int>> v(MAX_N);
void make_euler ()
{
stack<pair<int,int>> st;
st.push(make_pair(1,0));
// rep_euler.push_back(1);
while (!st.empty())
{
int cur=st.top().first,ok=0;
rep_euler.push_back(cur);
l[rep_euler.size()-1]=st.top().second;
first[cur]=rep_euler.size()-1;
viz[cur]=1;
for (int i=0; i<v[cur].size() && !ok; i++)
{
int next=v[cur][i];
if (!viz[next])
{
ok=1;
viz[next]=1;
st.push(make_pair(next,st.top().second+1));
}
}
if (!ok)
{
st.pop();
}
}
}
void build (int nod,int li,int ls)
{
if (li==ls)
{
adi[nod]=li;
return ;
}
build(nst,li,mij);
build(ndr,mij+1,ls);
if (l[adi[nst]]<=l[adi[ndr]])
adi[nod]=adi[nst];
else adi[nod]=adi[ndr];
}
void query(int nod,int st,int dr,int li,int ls)
{
if (st<=li && ls<=dr)
{
if (l[adi[nod]]<hsol)
sol=rep_euler[adi[nod]],hsol=l[adi[nod]];
return ;
}
if (st<=mij)
query(nst,st,dr,li,mij);
if (mij<dr)
query(ndr,st,dr,mij+1,ls);
}
int lca (int a,int b)
{
int st=first[a],dr=first[b];
if (st>dr)
swap(st,dr);
sol=hsol=INF;
query (1,st,dr,1,rep_euler.size());
return sol;
}
int main()
{
f>>n>>m;
for (int i=2; i<=n; i++)
{
f>>dads[i];
v[dads[i]].push_back(i);
}
make_euler();
build(1,1,rep_euler.size());
for (int i=1; i<=m; i++)
{
int x,y;
f>>x>>y;
g<<lca(x,y)<<'\n';
}
return 0;
}