#include <fstream>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
const int NMAX=100005, MAX_POWER=21;
// a[node][i] - al 2^i lea ancestor al lui node
// suma de puteri de 2
int n,queries;
int a[NMAX][MAX_POWER];
vector<vector<int>> graph;
vector<int> sol,level,parent;
void read_and_initialise_tree_data()
{
cin>>n>>queries;
graph.resize(n+1,vector<int>());
parent.resize(n+1);
level.resize(n+1,-1);
parent[1]=1;
for(int i=1;i<n;i++){
int value; cin>>value;
parent[i+1]=value;
graph[value].push_back(i+1);
graph[i+1].push_back(value);
}
}
void bfs(int start)
{
queue<int> q; q.push(start); level[start]=1;
while(!q.empty()){
int node=q.front(); q.pop();
for(int neighbor:graph[node]){
if(level[neighbor]!=-1) continue;
level[neighbor]=level[node]+1;
q.push(neighbor);
}
}
}
void build_matrix()
{
for(int i=1;i<=n;i++) a[i][0]=parent[i];
for(int j=1;j<21;j++)
for(int i=1;i<=n;i++) a[i][j]=a[a[i][j-1]][j-1];
}
int find_new_level(int& node,int dif)
{
for(int j=20;j>=0;j--){
if((1<<j)<=dif){
node=a[node][j]; dif-=(1<<j);}
if(dif==0) break;
} return node;
}
void compare(int& node1,int& node2)
{
if(level[node1]>level[node2]) {
node1=find_new_level(node1,level[node1]-level[node2]);
return ;
}
if(level[node1]<level[node2])
node2=find_new_level(node2,level[node2]-level[node1]);
}
int find_lca(int& node1,int& node2)
{
int lca;
for(int j=20;j>=0;j--){
if(a[node1][j]!=a[node2][j]){
node1=a[node1][j];
node2=a[node2][j];}
} return parent[node1];
}
void read_and_answer_queries()
{
for(int i=0;i<queries;i++){
int node1,node2; cin>>node1>>node2;
compare(node1,node2);
if(node1==node2){
sol.push_back(node1); continue;
}
sol.push_back(find_lca(node1,node2));
}
}
void print_solution()
{
for(int x:sol) cout<<x<<'\n';
}
int main()
{
read_and_initialise_tree_data();
bfs(1);
build_matrix();
read_and_answer_queries();
print_solution();
return 0;
}