//LCA cu Alg lui Tarjan-offline
#include<iostream>
#include<vector>
#include<fstream>
#define nmax 100001
#define mmax 200001
using namespace std;
int n,m;
vector<int> G[nmax];
vector< pair<int,int> > query[mmax];
bool colour[nmax];
int ancestor[nmax],ans[mmax],tata[nmax],h[nmax];
void read()
{
int x,y;
ifstream fin("lca.in");
fin>>n>>m;
for(int i=2;i<=n;i++)
{
fin>>x;
G[x].push_back(i);
}
for(int i=1;i<=m;i++)
{
fin>>x>>y;
query[x].push_back(make_pair(y,i));
query[y].push_back(make_pair(x,i));
}
fin.close();
}
void makeSet(int x)
{
tata[x]=x;
h[x]=1;
}
int Find(int x)
{
if(tata[x]!=x)
tata[x]=Find(tata[x]);
return tata[x];
//pot aplica regula de compresie, deoarece am retinut radacina-eventualul raspuns la query-in ancestor
}
void Union(int x,int y)
{
int xroot=Find(x),yroot=Find(y);
if(h[xroot]==h[yroot])
{
tata[yroot]=xroot;
h[xroot]++;
}
else
(h[xroot]>h[yroot]) ? tata[yroot]=xroot : tata[xroot]=yroot;
}
void Tarjan(int u)
{
makeSet(u);
ancestor[Find(u)]=u;
vector<int>::iterator it;
for(it=G[u].begin();it!=G[u].end();it++)
{
Tarjan(*it);
Union(u,*it);
ancestor[Find(u)]=u;
}
colour[u]=true;
vector< pair <int,int> >::iterator IT;
for(IT=query[u].begin();IT!=query[u].end();IT++)
{
if(colour[(*IT).first]=true)
ans[(*IT).second]=ancestor[Find((*IT).first)];
}
}
int main()
{
read();
Tarjan(1);
ofstream fout("lca.out");
for(int i=1;i<=m;i++)
fout<<ans[i]<<'\n';
fout.close();
}