#include <bits/stdc++.h>
#define VI vector<int>
#define VII vector<pair<int,int>>
#define QI queue<int>
#define ms(a,v) memset( a, v, sizeof( a ) )
#define FOR(i,a,b) for(int i = a; i <= b; ++i)
#define ROF(i,a,b) for(int i = a; i >= b; i--)
#define foreach(v, c) for( typeof( (c).begin() ) v = (c).begin(); v != (c).end(); ++v)
#define pb push_back
#define pp pair<int,int>
#define mp make_pair
#define fi first
#define se second
#define popcount __builtin_popcount
#define gcd __gcd
#define bit(n,i) ( n & ( 1LL << i ) )
#define lsb(x) ( x & ( -x ) )
#define FIN(str) freopen(str,"r",stdin)
#define FOUT(str) freopen(str,"w",stdout)
#define Fin(str) ifstream(str)
#define Fout(str) ostream(str)
#define SYNC ios_base::sync_with_stdio(0);
#define ll long long
#define ull unsigned long long
inline void read( int &a )
{
register char ch;
a = 0;
int sign = 1;
do
{
ch = getchar();
} while ( !isdigit( ch ) && ch != '-' );
if ( ch == '-' )
{
sign = -1;
ch = getchar();
}
do
{
a = a * 10 + ch - '0';
ch = getchar();
} while( isdigit( ch ) );
a *= sign;
}
inline void write( int a )
{
char s[20];
int i = 0;
int sign = 1;
if ( a < 0 )
sign = -1,
a = -a;
do
{
s[ i++ ] = a % 10 + '0';
a /= 10;
} while ( a );
i--;
if ( sign == -1 )
putchar( '-' );
while ( i >= 0 ) putchar( s[ i-- ] );
}
const int dx[] = { -1, 0, 1, 0 };
const int dy[] = { 0, 1, 0, -1 };
const int dl[] = { -1, -1, -1, 0, 0, 1, 1, 1 };
const int dc[] = { -1, 0, 1, -1, 1, -1, 0, 1 };
const int INF = 2e9;
const double EPS = 1e-9;
const int Nmax = 1e5 + 2;
const int LgMax = log2(Nmax) + 1;
using namespace std;
int Left[Nmax], Right[Nmax], Parent[Nmax], Cost[Nmax], Maxim[Nmax];
int Revert[Nmax];
void lazy( int x )
{
if ( Revert[x] )
{
Revert[x] = 0;
swap( Left[x], Right[x] );
if ( Left[x] != 0 ) Revert[ Left[x] ] ^= 1;
if ( Right[x] != 0 ) Revert[ Right[x] ] ^= 1;
}
}
void update( int p )
{
Maxim[p] = Cost[p];
if ( Left[p] ) Maxim[p] = max( Maxim[p], Maxim[ Left[p] ] );
if ( Right[p] ) Maxim[p] = max( Maxim[p], Maxim[ Right[p] ] );
}
bool isRoot( int p )
{
return ( !Parent[p] || ( Left[ Parent[p] ] != p && Right[ Parent[p] ] != p ) );
}
void Zig( int p )
{
int q = Parent[p];
int r = Parent[q];
if ( ( Left[q] = Right[p] ) != 0 )
Parent[ Left[q] ] = q;
Right[p] = q;
Parent[q] = p;
if ( ( Parent[p] = r ) != 0 )
{
if ( Left[r] == q )
Left[r] = p;
else
if ( Right[r] == q )
Right[r] = p;
}
update( q );
}
void Zag( int p )
{
int q = Parent[p];
int r = Parent[q];
if ( ( Right[q] = Left[p] ) != 0 )
Parent[ Right[q] ] = q;
Left[p] = q;
Parent[q] = p;
if ( ( Parent[p] = r ) != 0 )
{
if ( Left[r] == q )
Left[r] = p;
else
if ( Right[r] == q )
Right[r] = p;
}
update( q );
}
void splay( int p )
{
while ( !isRoot( p ) )
{
int q = Parent[p];
int r = Parent[q];
if ( isRoot( q ) )
{
lazy( q );
lazy( p );
if ( Left[q] == p )
Zig( p );
else
Zag( p );
}
else
{
lazy( r );
lazy( q );
lazy( p );
if ( ( p == Left[q] ) == ( q == Left[r] ) )
{
if ( p == Left[q] )
{
Zig( q );
Zig( p );
}
else
{
Zag( q );
Zag( p );
}
}
else
{
if ( p == Left[q] )
Zig( p );
else
Zag( p );
if ( p == Left[r] )
Zig( p );
else
Zag( p );
}
}
}
lazy( p );
update( p );
}
int expose( int p )
{
int last = 0;
for ( int x = p; x != 0; x = Parent[x] )
{
splay( x );
Left[x] = last;
last = x;
}
splay( p );
return last;
}
void makeroot( int p )
{
expose( p );
Revert[p] ^= 1;
}
bool connected( int x, int y )
{
if ( x == y )
return true;
expose( x );
expose( y );
return Parent[x] != 0;
}
int lca( int x, int y )
{
expose( x );
return expose( y );
}
void link( int x, int y )
{
makeroot( x );
Parent[x] = y;
}
void cut( int x, int y )
{
makeroot( x );
expose( y );
Parent[ Right[y] ] = 0;
Right[y] = 0;
}
int query( int x, int y )
{
makeroot( x );
expose( y );
return Maxim[y];
}
void updateNode( int x, int value )
{
makeroot( x );
expose( x );
Cost[x] = Maxim[x] = value;
}
int N, M;
int main()
{
FIN("lca.in");
FOUT("lca.out");
read( N ); read( M );
for ( int i = 2, a; i <= N; ++i )
{
read( a );
link( i, a );
}
for ( int i = 1, x, y; i <= M; ++i )
{
read( x ); read( y );
cout << lca( x, y ) << "\n";
}
return 0;
}