#include <fstream>
#include <vector>
using namespace std;
const int Nmax = 100000;
int h[Nmax + 1], l[Nmax + 1];
pair <int, int> aint[8 * Nmax + 1];
vector <int> adj[Nmax + 1];
vector <int> euler;
bool viz[Nmax + 1];
int n, k = 1;
void dfs(int node, int q = 0)
{
viz[node] = true;
euler.push_back(node);
l[node] = euler.size();
h[node] = q;
for (auto u : adj[node])
{
if (!viz[u])
{
dfs(u, q + 1);
euler.push_back(node);
}
}
}
void build(int node, int l, int r)
{
if (l == r)
{
aint[node] = {h[euler[l - 1]], euler[l - 1]};
}
else
{
int mid = (l + r) / 2;
build(2 * node, l, mid);
build(2 * node + 1, mid + 1, r);
if (aint[2 * node].first <= aint[2 * node + 1].first)
{
aint[node] = aint[2 * node];
}
else
{
aint[node] = aint[2 * node + 1];
}
}
}
pair <int, int> query(int node, int l, int r, int p, int q)
{
if (p > q)
{
return make_pair(-1, -1);
}
else if (l == p && r == q)
{
return aint[node];
}
else
{
int mid = (l + r) / 2;
pair <int, int> qry1 = query(2 * node, l, mid, p, min(mid, q));
pair <int, int> qry2 = query(2 * node + 1, mid + 1, r, max(p, mid + 1), q);
if (qry1.first == -1)
{
return qry2;
}
else if (qry2.first == -1)
{
return qry1;
}
if (qry1.first <= qry2.first)
{
return qry1;
}
else
{
return qry2;
}
}
}
int lca(int u, int v)
{
pair <int, int> p = query(1, 1, n, min(l[u], l[v]), max(l[u], l[v]));
return p.second;
}
int main()
{
ifstream fin("lca.in");
ofstream fout("lca.out");
int m;
fin >> n >> m;
for (int i = 2; i <= n; i++)
{
int nr;
fin >> nr;
adj[nr].push_back(i);
}
dfs(1);
n = euler.size();
build(1, 1, n);
while (m--)
{
int u, v;
fin >> u >> v;
fout << lca(u, v) << "\n";
}
return 0;
}