#include <fstream>
#include <algorithm>
#include <vector>
#include <cmath>
#define NMAX 100009
#define LG 20
#define pb push_back
using namespace std;
ofstream out("lca.out");
ifstream in("lca.in");
int n , m , Euler[ 2 * NMAX ] , niv[ 2 * NMAX ] , First[ NMAX ] , K;
int dp[2 * NMAX][ 2 * LG];
vector < int > G[NMAX];
typedef vector < int >:: iterator IT;
void read();
void dfs( int , int );
void RMQ();
void LCA();
int main()
{
read();
dfs(1,0);
n = 2 * n -1;
RMQ();
LCA();
return 0;
}
void read()
{
in >> n >> m ;
for(int i = 2; i<= n; i++ )
{
int x;
in>>x;
G[x].push_back(i);
}
}
void dfs( int nod , int level )
{
Euler[++K] = nod;
niv[ K ] = level;
First[nod] = K;
for( IT i = G[nod].begin () ; i!= G[nod].end() ; ++i )
{
dfs( *i , level + 1 );
Euler[ ++K ] = nod;
niv[ K ] = level;
}
}
void RMQ()
{
for( int i = 1 ; i <=n ; i++)
dp[i][0] = i ; //lucram cu indexii , nu cu valori !!!
int k = 0;
while( ( 1 << k ) <=n )
++k;
--k;
for( int j =1 ; j<=k ; j++)
{
for( int i=1 ; i<=n ; i++)
{
dp[i][j] = dp[i][j-1];
if( i + ( 1 << ( j - 1 )) <=n && niv[ dp[i][j] ] > niv[ dp[ i + ( 1 << ( j - 1 ) ) ][ j - 1 ]] )
dp[i][j] = dp[ i + ( 1 << ( j -1 ) )][j-1];
}
}
}
void LCA()
{
int v1 , v2;
for( int x , y ; m ; --m )
{
in >> v1 >> v2;
x = First[v1];
y = First[v2];
if( x > y )
swap(x,y);
if( x == y )
{
out << Euler[ dp[x][0] ] << '\n';
continue;
}
int k = 0;
k = ( int ) floor( log ( y - x )/log(2) );
if( niv[ dp[x][k] ] <= niv[ dp[ y - ( 1 << k ) + 1 ][k] ] )
out << Euler[ dp[x][k] ] << '\n';
else
out << Euler[ dp[y- ( 1 << k ) + 1 ][k] ] << '\n';
}
}