#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#define NMAX 100005
typedef struct {
int *first, *next, *to;
int edges;
} Graph;
int lsb(int x) {
return x ^ (x & (x - 1));
}
int msb(int x) {
int v = x;
v |= x >> 1;
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
return (v + 1) >> 1;
}
int parent[NMAX];
int preorder[NMAX], asc[NMAX], level[NMAX], inlabel[NMAX], head[NMAX];
Graph g;
void new_graph(Graph* g, int n, int m) {
g->first = (int*) malloc(sizeof(int) * (n + 1));
memset(g->first, -1, sizeof(int) * (n + 1));
g->next = (int*) malloc(sizeof(int) * m);
g->to = (int*) malloc(sizeof(int) * m);
g->edges = 0;
}
void add_edge(Graph* g, int from, int to) {
g->to[g->edges] = to;
g->next[g->edges] = g->first[from];
g->first[from] = g->edges++;
}
void delete_graph(Graph* g) {
free(g->first);
free(g->next);
free(g->to);
}
int dfs1(int node, int pos) {
preorder[node] = ++pos;
inlabel[node] = preorder[node];
for (int e = g.first[node]; e != -1; e = g.next[e]) {
int to = g.to[e];
level[to] = level[node] + 1;
pos = dfs1(to, pos);
if (lsb(inlabel[to]) > lsb(inlabel[node])) {
inlabel[node] = inlabel[to];
}
}
head[inlabel[node]] = node;
return pos;
}
void dfs2(int node) {
if (parent[node] != -1) {
asc[node] = asc[parent[node]];
if (inlabel[node] != inlabel[parent[node]]) {
asc[node] |= lsb(inlabel[node]);
}
} else {
asc[node] = lsb(inlabel[node]);
}
for (int e = g.first[node]; e != -1; e = g.next[e]) {
int to = g.to[e];
dfs2(to);
}
}
void preprocess(int n) {
int i;
parent[1] = -1;
level[1] = 0;
dfs1(1, 0);
dfs2(1);
}
int findAnc(int x, int i, int b, int j, int lz) {
if (inlabel[x] == lz) {
return x;
}
int k = msb(asc[x] & (j - 1));
return parent[head[(inlabel[x] & ~(k - 1)) | k]];
}
int secondLca(int x, int y) {
if (x > y) {
int aux = x;
x = y;
y = aux;
}
int i = msb(x ^ y);
if (x & ((i << 1) - 1)) {
int b = (x | y) & ~(i - 1);
return b;
}
return x;
}
int lca(int x, int y) {
if (inlabel[x] == inlabel[y]) {
return level[x] < level[y] ? x: y;
}
int b = secondLca(inlabel[x], inlabel[y]);
int i = lsb(b);
fprintf(stderr, "%d\n", b);
int j = lsb(asc[x] & asc[y] & ~(i - 1));
int lz = (b & ~(j - 1)) | j;
int x1 = findAnc(x, i, b, j, lz);
int y1 = findAnc(y, i, b, j, lz);
assert(inlabel[x1] == lz);
assert(inlabel[y1] == lz);
return level[x1] < level[y1] ? x1: y1;
}
int main() {
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
int n, q, i;
scanf("%d%d", &n, &q);
new_graph(&g, n, n - 1);
for (i = 2; i <= n; ++i) {
int f;
scanf("%d", &f);
parent[i] = f;
}
for (i = n; i >= 2; --i) {
add_edge(&g, parent[i], i);
}
preprocess(n);
while (q-- > 0) {
int x, y;
scanf("%d%d", &x, &y);
printf("%d\n", lca(x, y));
}
delete_graph(&g);
return 0;
}