#include<cstdio>
#include<cassert>
#include<cstring>
#include<vector>
#include<algorithm>
#include<fstream>
#include<iostream>
#include<queue>
using namespace std;
const int kinf = 2e9;
class node{
public:
node(){};
node(int left1, int right1, int ltree1, int rtree1, int val1){
left = left1;
right = right1;
ltree = ltree1;
rtree = rtree1;
val = val1;
}
friend void make(int nod);
friend void update(int pos, int val, int nod);
friend int query(int l, int r, int nod);
private:
int left, right, ltree, rtree, val;
};
vector<node> t;
int p, init[300005];
void make(int nod){
if(t[nod].left != t[nod].right){
p = t.size();
t[nod].ltree = p;
t.push_back(node(t[nod].left, (t[nod].left + t[nod].right) >> 1, 0, 0, 0));
++p;
t[nod].rtree = p;
t.push_back(node(((t[nod].left + t[nod].right) >> 1) + 1, t[nod].right, 0, 0, 0));
make(t[nod].ltree);
make(t[nod].rtree);
t[nod].val = min(t[t[nod].ltree].val, t[t[nod].rtree].val);
}
else
t[nod].val = init[t[nod].left];
}
void update(int pos, int val, int nod){
if(t[nod].left == t[nod].right){
t[nod].val = val;
return;
}
if(pos <= (t[nod].left + t[nod].right) >> 1)
update(pos, val, t[nod].ltree);
else
update(pos, val, t[nod].rtree);
t[nod].val = min(t[t[nod].ltree].val, t[t[nod].rtree].val);
}
int query(int l, int r, int nod){
if(l <= t[nod].left && r >= t[nod].right)
return t[nod].val;
if(l > t[nod].right || r < t[nod].left)
return kinf;
return min(query(l, r, t[nod].ltree), query(l, r, t[nod].rtree));
}
int u, vis[100005], ind[100005], num[100005], pos[100005];
vector<int> graph[100005];
void bfs(){
memset(vis, 0, sizeof(vis));
int n = 0;
queue<int> q;
q.push(1);
vis[1] = 1;
ind[1] = ++n;
num[n] = 1;
while(!q.empty()){
int now = q.front();
q.pop();
for(int i = 0; i < graph[now].size(); ++i)
if(!vis[graph[now][i]]){
vis[graph[now][i]] = 1;
ind[graph[now][i]] = ++n;
num[n] = graph[now][i];
q.push(graph[now][i]);
}
}
}
void dfs(int x){
vis[x] = 1;
init[++u] = x;
pos[x] = u;
for(int i = 0; i < graph[x].size(); ++i)
if(!vis[graph[x][i]]){
dfs(graph[x][i]);
init[++u] = x;
}
}
int main(){
ifstream in("lca.in");
ofstream out("lca.out");
int n, x, y, m;
in >> n >> m;
for(int i = 2; i <= n; ++i){
in >> x;
graph[x].push_back(i);
graph[i].push_back(x);
}
dfs(1);
bfs();
for(int i = 1; i <= u; ++i)
init[i] = ind[init[i]];
t.push_back(node(1, u, 0, 0, 0));
make(0);
for(int i = 0; i < m; ++i){
in >> x >> y;
if(pos[x] > pos[y])
swap(x, y);
out << num[query(pos[x], pos[y], 0)] << "\n";
}
return 0;
}