/*
#include <vector>
#include <fstream>
#include <iostream>
using namespace std;
#define MAX_N 100005
#define INF 0x3f3f3f3f
#define foreach(V) for(typeof (V).begin() it = (V).begin(); it != (V).end(); ++it)
#define nst (nod << 1)
#define ndr (nst | 1)
#define mij ((li + lf) >> 1)
int K, N, M, P;
int L[MAX_N << 1], H[MAX_N << 1],Lg[MAX_N << 1], First[MAX_N];
int A[MAX_N << 4], st, dr, sol, hsol;
vector <int> G[MAX_N];
ifstream fin ("lca.in");
ofstream fout ("lca.out");
void citire()
{
fin >> N >> M;
for(int i = 2; i <= N; ++i)
{
int x;
fin >> x;
G[x].push_back(i);
}
}
void dfs(int nod, int lev)
{
H[++K] = nod;
L[K] = lev;
First[nod] = K;
foreach(G[nod])
{
dfs(*it, lev+1);
H[++K] = nod;
L[K] = lev;
}
}
void build(int nod, int li, int lf)
{
if(li == lf)
{
A[nod] = li;
return;
}
build(nst, li, mij);
build(ndr, mij+1, lf);
if(L[A[nst]] <= L[A[ndr]])
A[nod] = A[nst];
else
A[nod] = A[ndr];
}
void query(int nod, int li, int lf)
{
if(st <= li && lf <= dr)
{
if(L[A[nod]] < hsol)
sol = H[A[nod]],
hsol = L[A[nod]];
return;
}
if(st <= mij) query(nst, li, mij);
if(mij < dr) query(ndr, mij+1, lf);
}
int lca(int x, int y)
{
st = First[x], dr = First[y];
if(st > dr) swap(st, dr);
sol = hsol = INF;
query(1, 1, K);
return sol;
}
int main()
{
citire();
dfs(1, 0);
build(1, 1, K);
for(int i = 1; i <= K; i++) {
cout<<A[i]<<' ';
}
while(M--)
{
int x, y;
fin >> x >> y;
fout << lca(x, y) << "\n";
}
}
*/
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#define NMax 100001
#define MAXNR 999999999
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
vector <int> v [NMax];
vector <pair <int, int> > rEuler;
int x, y, n, m, pos, nr = 1;
int First[NMax];
pair <int, int> val;
pair <int, int> A[NMax << 4];
void DF(int R, int nivel) {
rEuler.push_back(make_pair(R, nivel));
First[R] = nr;
nr++;
for(int i = 0; i < v[R].size(); i++) {
DF(v[R][i], nivel + 1);
rEuler.push_back(make_pair(R, nivel));
nr++;
}
}
pair <int, int> sol;
void adauga(int nod, int st, int dr) {
if(st == dr) {
A[nod] = val;
} else{
int mij = (st + dr) / 2;
if(pos > mij) {
adauga(2 * nod + 1, mij + 1, dr);
} else {
adauga(2 * nod, st, mij);
}
if(A[2*nod].second > A[2*nod + 1].second) {
A[nod] = A[2 * nod + 1];
} else {
A[nod] = A[2 * nod];
}
}
}
int Left, Right;
void query(int nod, int st, int dr) {
if (st >= Left && dr <= Right) {
if(sol.second > A[nod].second) {
sol = A[nod];
}
} else {
int mij = (st + dr) / 2;
if (mij >= Left) query(2 * nod, st, mij);
if (mij < Right) query(2 * nod + 1, mij + 1, dr);
}
}
int main()
{
fin>>n>>m;
for(int i = 2; i <= n; i++) {
fin>>x;
v[x].push_back(i);
}
rEuler.push_back(make_pair(0, 0));
DF(1, 0);
for(int i = 1 ; i <= nr; i++) {
val = rEuler[i];
pos = i;
adauga(1, 1, nr);
}
nr--;
for(int i = 1; i <= nr; i++) {
cout<<A[i].second<<" ";
}
for(int i = 1; i <= m; i++) {
fin>>x>>y;
Left = First[x];
Right = First[y];
if(First[x] > First[y]) {
Left = First[y];
Right = First[x];
}
sol.first = MAXNR;
sol.second = MAXNR;
query(1, 1, nr);
fout<<sol.first<<'\n';
}
fin.close();
fout.close();
return 0;
}