#include <fstream>
#include <vector>
#include <cmath>
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
int a[200005];
vector <int> v[100001];
bool viz[200005];
int q=0;
int prim[100005];
struct wow
{
int niv,nr;
}poz[200005],arb[500005];
void dfs(int x,int niv)
{
int i;
viz[x]=1;
for (i=0;i<v[x].size();i++)
{
if (viz[v[x][i]]==0)
{
q++;
poz[q].nr=x;
poz[q].niv=niv;
if (prim[x]==0)
{
prim[x]=q;
}
dfs(v[x][i],niv+1);
i=i;
}
}
q++;
poz[q].nr=x;
poz[q].niv=niv;
if (prim[x]==0)
{
prim[x]=q;
}
}
void update (int nod,int a,int b,int poz,wow val)
{
if (a==b)
{
arb[nod]=val;
}
else
{
int mij=(a+b)/2;
if (poz<=mij)
{
update(2*nod,a,mij,poz,val);
}
else
{
update(2*nod+1,mij+1,b,poz,val);
}
if (arb[2*nod+1].niv<arb[2*nod].niv)
{
arb[nod]=arb[2*nod+1];
}
else
{
arb[nod]=arb[2*nod];
}
}
}
int query(int a,int b,int nod,int ua,int ub)
{
int r1=100000001,r2=10000001,mij;
if (ua<=a&&ub>=b)
{
return arb[nod].nr;
}
mij=(a+b)/2;
if (ua<=mij)
{
r1=query(a,mij,2*nod,ua,ub);
}
if (ub>mij)
{
r2=query(mij+1,b,2*nod+1,ua,ub);
}
return min(r1,r2);
}
int n,m,i,x,j,lim,nr,y,st,dr,k;
int main()
{
f>>n>>m;
for (i=2;i<=n;i++)
{
f>>x;
v[x].push_back(i);
}
dfs(1,1);
lim=2*n-1;
for (i=1;i<=lim;i++)
{
arb[i].nr=arb[i].niv=1000000001;
}
for (i=1;i<=lim;i++)
{
update(1,1,lim,i,poz[i]);
}
for (i=1;i<=m;i++)
{
f>>x>>y;
st=min(prim[x],prim[y]);
dr=max(prim[x],prim[y]);
g<<query(1,lim,1,st,dr)<<'\n';
}
return 0;
}