#include <fstream>
using namespace std;
int t[100100], n, m,
v[300100], h[300100], le,
arb[300100];
void reprezEuler(int r = 1, int hc = 1)
{
for(int i = 1; i <= n; i++)
if(t[i] == r)
{
v[le] = r;
h[le++] = hc;
reprezEuler(i, hc + 1);
}
v[le] = r;
h[le++] = hc;
}
void update(int poz, int st, int dr, int k = 1)
{
if(st == dr)
{
arb[k] = poz;
return;
}
if(poz <= (st + dr) / 2)
update(poz, st, (st + dr) / 2, k * 2);
else
update(poz, (st + dr) / 2 + 1, dr, k * 2 + 1);
if(h[arb[k * 2]] <= h[arb[k * 2 + 1]])
arb[k] = arb[k * 2];
else
arb[k] = arb[k * 2 + 1];
}
int query(int a, int b, int st, int dr, int k = 1)
{
int rez = -1, q;
if(a <= st && b >= dr)
return arb[k];
if(a <= (st + dr) / 2)
{
q = query(a, b, st, (st + dr) / 2, k * 2);
if(rez == -1 || (h[q] < h[rez]))
rez = q;
}
if(b > (st + dr) / 2)
{
q = query(a, b, (st + dr) / 2 + 1, dr, k * 2 + 1);
if(rez == -1 || (h[q] < h[rez]))
rez = q;
}
return rez;
}
void constrArbInterv()
{
for(int i = 0; i < le; i++)
update(i, 0, le - 1);
}
int lca(int a, int b)
{
int i = -1, j = -1, k = 0;
while((i == -1 || j == -1) && k < le)
{
if(i == -1 && v[k] == a)
i = k;
if(j == -1 && v[k] == b)
j = k;
k++;
}
if(i > j)
swap(i, j);
return v[query(i, j, 0, le - 1)];
}
int main()
{
ifstream in("lca.in");
ofstream out("lca.out");
int x, y;
in >> n >> m;
for(int i = 2; i <= n; i++)
in >> t[i];
reprezEuler();
constrArbInterv();
for(int i = 0; i < m; i++)
{
in >> x >> y;
out << lca(x, y) << endl;
}
in.close();
out.close();
}