#include <fstream>
#include <vector>
#include <deque>
#include <algorithm>
#include <string>
#define MOD 1999999973
#define INT_MAX 1000000000
using namespace std ;
ifstream cin ("lca.in") ;
ofstream cout ("lca.out") ;
int tatal[100009], e[100009], lvl[100009], primaparitie[100009] ;
vector<int> fii[100009] ;
int peuler(int nod, int poz, int level)
{
lvl[poz] = level ;
e[poz ++] = nod ;
if(fii[nod].size())
{
for(int f = 0 ; f < fii[nod].size() ; f ++)
poz = peuler(fii[nod][f], poz, level + 1), e[poz] = nod, lvl[poz] = level, poz ++ ;
return poz ;
}
else return poz ;
}
struct nod
{
int mid, val, st, dr ;
nod *stfiu, *drfiu ;
};
int comp(int a, int b)
{
if(lvl[a] <= lvl[b])return a ;
return b ;
}
int query(nod *tatal, int st, int dr)
{
///cout << st << " " << dr << " " << tatal -> st << " " << tatal -> dr << " " << tatal -> mid << " " << tatal ->val << endl ;
if(tatal -> st == st && tatal -> dr == dr)
return tatal -> val ;
if(dr <= tatal -> mid)
return query(tatal -> stfiu, st, dr) ;
if(st >= tatal -> mid + 1)
return query(tatal -> drfiu, st, dr) ;
return comp(query(tatal -> stfiu, st, tatal -> mid), query(tatal -> drfiu, tatal -> mid + 1, dr)) ;
}
nod tree[400009] ;
void create(int f, int st, int dr)
{
if(st == dr)
{
tree[f].st = st ;
tree[f].dr = st ;
tree[f].mid = st ;
tree[f].val = st ;
return ;
}
int mid = (st + dr) / 2 ;
create(2 * f, st, mid) ;
create(2 * f + 1, mid + 1, dr) ;
tree[f].st = st ;
tree[f].dr = dr ;
tree[f].mid = mid ;
tree[f].stfiu = &tree[2 * f] ;
tree[f].drfiu = &tree[2 * f + 1] ;
tree[f].val = comp(tree[2 * f].val, tree[2 * f + 1].val) ;
}
int main()
{
int n, q ;
cin >> n >> q ;
for(int f = 2 ; f <= n ; f ++)
cin >> tatal[f], fii[tatal[f]].push_back(f) ;
int neuler = peuler(1, 1, 0) - 1 ;
for(int f = 1 ; f <= neuler ; f ++)
if(!primaparitie[e[f]])primaparitie[e[f]] = f ;
/// trebe dat indicele elementului minim
create(1, 1, neuler) ;
/*
for(int f = 1 ; f <= neuler ; f ++)
cout << lvl[f] << " " ;
cout << endl ;
for(int f = 1 ; f <= neuler ; f ++)
cout << tree[f].st << " " << tree[f].dr << " " << tree[f].val << endl ;
*/
while(q --)
{
int st, dr, a, b, mn = INT_MAX ;
cin >> a >> b ;
st = primaparitie[a] ;
dr = primaparitie[b] ;
if(st > dr)swap(st, dr) ;
///cout << st << " " << dr << endl ;
cout << e[query(&tree[1], st, dr)] << '\n' ;
}
return 0 ;
}