#include <bits/stdc++.h>
#define NMAX (int)(1e5 + 5)
#define mp make_pair
#define leftChild node<<1
#define rightChild node<<1 | 1
#define inf 0x3f3f3f
using namespace std;
int euler[2 *NMAX], depth[2 * NMAX], first[2 * NMAX];
pair<int, int> depth_aint[4 * (2 * NMAX)];
vector<int> g[NMAX];
int ind, nivel;
void dfs(int k, int lst) {
euler[++ind] = k;
depth[ind] = nivel;
first[k] = ind;
for (int child : g[k]) {
if (child == lst) continue;
++nivel;
dfs(child, k);
--nivel;
euler[++ind] = k;
depth[ind] = nivel;
}
}
void build(int node, int l, int r) {
if (l == r)
depth_aint[node] = mp(depth[l], l);
else {
int mid = (l + r) / 2;
build (leftChild, l, mid);
build (rightChild, mid+1, r);
if (depth_aint[leftChild].first <= depth_aint[rightChild].first)
depth_aint[node] = depth_aint[leftChild];
else depth_aint[node] = depth_aint[rightChild];
}
}
pair<int, int> query(int node, int l, int r, int x, int y) {
if (l >= x && r <= y) return depth_aint[node];
int mid = (l + r) / 2;
pair<int, int> lRet = mp(inf, 0);
pair<int, int> rRet = mp(inf, 0);
if (mid >= x) lRet = query(leftChild, l, mid, x, y);
if (mid+1 <= y) rRet = query(rightChild, mid+1, r, x, y);
if (lRet.first <= rRet.first)
return lRet;
return rRet;
}
int main()
{
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
int n, q;
scanf ("%d %d", &n, &q);
for (int i = 2; i <= n; ++i) {
int j;
scanf("%d", &j);
g[i].push_back(j);
g[j].push_back(i);
}
dfs(1, -1);
build(1, 1, ind);
while (q--) {
int node1, node2;
scanf("%d %d", &node1, &node2);
int x = min(first[node1], first[node2]);
int y = max(first[node1], first[node2]);
pair<int, int> ans = query(1, 1, ind, x, y);
printf("%d\n", euler[ans.second]);
}
return 0;
}