#include <bits/stdc++.h>
#pragma GCC optimize("O3")
using namespace std;
ifstream fin ("lca.in");
ofstream fout ("lca.out");
const int NMAX = 1e5, LOG = 18;
int n, m, up[NMAX + 5][LOG + 5], dt[NMAX];
vector <int> g[NMAX + 5];
void dfs (int node) {
for (auto nx : g[node]) {
dt[nx] = dt[node] + 1;
dfs (nx);
}
}
int lca (int u, int v) {
int node_to_lift = u, other_node = v;
if (dt[u] < dt[v])
node_to_lift = v, other_node = u;
int diff = dt[node_to_lift] - dt[other_node];
for (int i = 0; i < LOG; i++) {
if (diff & (1 << i))
node_to_lift = up[node_to_lift][i];
}
if (node_to_lift == other_node)
return node_to_lift;
for (int i = LOG; i >= 0; i--) {
if (up[node_to_lift][i] != up[other_node][i]) {
node_to_lift = up[node_to_lift][i];
other_node = up[other_node][i];
}
}
return up[node_to_lift][0];
}
int main() {
//ios::sync_with_stdio(false);
//cin.tie(nullptr);
fin >> n >> m;
for (int i = 2; i <= n; i++) {
fin >> up[i][0];
g[up[i][0]].push_back(i); // parinte -> copil
}
for (int j = 1; j < LOG; j++) {
for (int i = 1; i <= n; i++)
up[i][j] = up[up[i][j - 1]][j - 1];
}
dt[1] = 0;
dfs (1);
while (m--) {
int u, v;
fin >> u >> v;
fout << lca(u, v) << "\n";
}
return 0;
}