#include <bits/stdc++.h>
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> pii;
#define fi first
#define se second
#define NMAX 100005
#define MOD 1000000007
#define INF 0x3f3f3f3f
int n, m, cnt = 0, euler[NMAX * 2], adancimi[NMAX * 2], prap[NMAX];
bool visited[NMAX];
vector<int> minlevel(8 * NMAX), eulerST(8 * NMAX);
vector<vector<int>> tree(NMAX);
// minlevel este arbore de intervale - contine minimul adancimilor dintr-un interval in parcurgerea euler
// LCA(a, a) reprezinta minimul din intervalul [a, b] in parcurgerea euler si este Lowest Common Ancestor
// unde a, respectiv b reprezinta prima aparitie a nodurilor x, respectiv y in parcurgerea euler
void read()
{
int root;
in >> n >> m;
for (int i = 2; i <= n; i++) // pt fiecare nod citesc radacina si adaug muchie intre ele
in >> root, tree[root].push_back(i);
}
void Euler(int nod, int level)
{
if (visited[nod])
return;
visited[nod] = 1;
euler[++cnt] = nod;
prap[nod] = cnt; // prima aparitie a fix inainte de a fi vizitat prima data, nu in for
adancimi[cnt] = level; // adancimea corespunzatoare nodului in parcurgerea euler a nodului
for (auto v : tree[nod])
Euler(v, level + 1), euler[++cnt] = nod, adancimi[cnt] = level;
// cand ma intorc dupa ce am parcurs toate nodurile din partea unui fiu il adaug iar
}
void buildLevels(int node = 1, int left = 1, int right = cnt)
{
if (left == right)
{
minlevel[node] = adancimi[left], eulerST[node] = euler[left];
return;
}
int mid = (left + right) / 2;
buildLevels(2 * node, left, mid);
buildLevels(2 * node + 1, mid + 1, right);
if (minlevel[2 * node] < minlevel[2 * node + 1])
minlevel[node] = minlevel[2 * node], eulerST[node] = eulerST[2 * node];
else
minlevel[node] = minlevel[2 * node + 1], eulerST[node] = eulerST[2 * node + 1];
}
pii LCA(int a, int b, int node = 1, int left = 1, int right = cnt)
{
if (a <= left && right <= b) // intervalul verificat acum [left, right] este inclus in [a, b], cel de care avem nevoie
return {minlevel[node], eulerST[node]};
int mid = (left + right) / 2;
pii ans = {INF, 0};
if (a <= mid)
{ // daca mergand in stanga inca ma aflu in interval
pii l = LCA(a, b, 2 * node, left, mid);
if (l.fi < ans.fi)
ans = l;
}
if (mid + 1 <= b)
{ // daca mergand in dreapta inca ma aflu in interval
pii r = LCA(a, b, 2 * node + 1, mid + 1, right);
if (r.fi < ans.fi)
ans = r;
}
return ans;
}
void solve()
{
Euler(1, 1); // parcurgerea Euler a arborelui incepand din radacina (nodul 1)
buildLevels();
for (int i = 1; i <= m; i++)
{
int x, y;
in >> x >> y;
if (prap[x] <= prap[y])
out << LCA(prap[x], prap[y]).se << ' ';
else
out << LCA(prap[y], prap[x]).se << ' ';
}
}
int main()
{
read();
solve();
return 0;
}