#include <bits/stdc++.h>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int NMAX = 1e5;
struct Node{
int val, depth;
};
Node aint[8 * NMAX];
int first[NMAX + 1];
vector<int> G[NMAX + 1];
int poz, n;
void update( int node, int st, int dr, int poz, Node x ) {
if( st == dr ) {
aint[node] = x;
return ;
}
int mid = (st + dr) / 2;
if( poz <= mid )
update(2 * node, st, mid, poz, x);
else
update(2 * node + 1, mid + 1, dr, poz, x);
if( aint[2*node].depth <= aint[2*node + 1].depth )
aint[node] = aint[2*node];
else
aint[node] = aint[2*node + 1];
}
Node query( int node, int st, int dr, int left, int right ) {
if( dr < left || st > right )
return {NMAX + 1, NMAX + 1};
if( left <= st && dr <= right )
return aint[node];
int mid = (st + dr) / 2;
Node a = query(2*node, st, mid, left, right);
Node b = query(2*node + 1, mid + 1, dr, left, right);
if( a.depth <= b.depth )
return a;
else
return b;
}
void dfs( int node, int depth, int father ) {
++ poz;
update( 1, 1, 2*n - 1, poz, {node, depth} );
if( first[node] == 0 )
first[node] = poz;
for( const auto &it : G[node] ) {
if( it != father ) {
dfs(it, depth + 1, node);
++ poz;
update( 1, 1, 2*n - 1, poz, {node, depth} );
}
}
}
int main() {
int m;
fin>>n>>m;
for( int i = 2; i <= n; i ++ ) {
int x;
fin>>x;
G[x].push_back(i);
G[i].push_back(x);
}
dfs(1, 0, 0);
for( int i = 1; i <= m; i ++ ) {
int u, v;
fin>>u>>v;
int st = first[u];
int dr = first[v];
if( st > dr )
swap(st, dr);
Node ans = query(1, 1, 2*n - 1, st, dr);
fout<<ans.val<<"\n";
}
return 0;
}