#include <fstream>
#include <stdio.h>
#include <vector>
using namespace std;
ifstream is("lca.in");
ofstream os("lca.out");
//FILE* is = fopen("lca.in", "r");
//FILE* os = fopen("lca.out", "w");
int n, m;
vector<vector<int> > G;
vector<int> euler, depth, first, rmq;
void Read();
void Euler(int x, int d = 0);
void Rmq(int nod, int st, int dr);
int Query(int nod, int st, int dr, int p1, int p2);
int lca(int x, int y);
int main()
{
Read();
Euler(1);
rmq.resize(4*euler.size() + 1);
Rmq(1, 0, euler.size()-1);
for ( int i = 0, x, y; i < m; ++i )
{
is >> x >> y;
//fscanf(is, "%d%d", &x, &y);
//fprintf(os, "%d\n", lca(x, y));
os << lca(x, y) << "\n";
}
//fclose(is);
//fclose(os);
is.close();
os.close();
return 0;
}
void Read()
{
is >> n >> m;
//fscanf(is, "%d%d", &n, &m);
G.resize(n+1);
first.resize(n+1);
depth.resize(n+1);
for ( int i = 2, x; i <= n; ++i )
{
is >> x;
//fscanf(is, "%d", &x);
G[x].push_back(i);
}
}
void Euler(int x, int d)
{
euler.push_back(x);
depth[x] = d;
first[x] = euler.size() - 1;
for ( auto it : G[x] )
{
Euler(it, d+1);
euler.push_back(x);
}
}
void Rmq(int nod, int st, int dr)
{
if ( st == dr )
{
rmq[nod] = euler[st];
return;
}
int m = ( st + dr ) / 2;
Rmq(nod*2, st, m);
Rmq(nod*2+1, m+1, dr);
if ( depth[rmq[nod*2] ] < depth[rmq[nod*2+1] ] )
rmq[nod] = rmq[nod*2];
else
rmq[nod] = rmq[nod*2+1];
}
int Query(int nod, int st, int dr, int p1, int p2)
{
if ( p1 <= st && p2 >= dr )
return rmq[nod];
int m = (st + dr)/2;
int v1 = -1, v2 = -1;
if ( p1 <= m )
v1 = Query(nod*2, st, m, p1, p2);
if ( m < p2 )
v2 = Query(nod*2+1, m+1, dr, p1, p2);
if ( v1 == -1 )
return v2;
if ( v2 == -1 )
return v1;
if ( depth[v1] < depth[v2] )
return v1;
return v2;
}
int lca(int x, int y)
{
x = first[x];
y = first[y];
if ( x > y )
{
int aux = x;
x = y;
y = aux;
}
/*
int nod, mn = 99999999;
for ( int i = x; i <= y; ++i )
{
if ( depth[euler[i]] < mn )
{
mn = depth[euler[i]];
nod = euler[i];
}
}
return nod;
*/
return Query(1, 0, euler.size()-1, x, y);
}