#include <iostream>
using namespace std;
#include <fstream>
#include <algorithm>
#include <list>
#include <vector>
namespace e_040_lca_
{
void build_tree(int N, int* parents, vector<list<int>>& tree)
{
tree.resize(N + 1);
//create the tree
for (int i = 2; i <= N; i++) {
int p = parents[i];
tree[p].push_back(i); //add the child
}
}
void dfs_euler_depth(int node, int depth, int N, vector<list<int>>& tree, int& eid, int* er, vector<vector<int>>& er_pos, int* depths)
{
depths[node] = depth;
er_pos[node].push_back(eid);
er[eid++] = node;
for (auto& child : tree[node]) {
dfs_euler_depth(child, depth + 1, N, tree, eid, er, er_pos, depths);
er_pos[node].push_back(eid);
er[eid++] = node;
}
}
void build_rmq_data(int N, int* v, vector<vector<int>>& ids_min)
{
ids_min.resize(N + 1);
for (int i = 1; i < N; i++) {
ids_min[i].resize((int)log2(N - i) + 1);
ids_min[i][0] = v[i] <= v[i + 1] ? i : i + 1;
}
int logN = (int) log2(N);
for (int k = 1; k <= logN; k++) {
int km1 = k - 1, two_km1 = (1 << km1), two_k = two_km1 << 1;
for (int i = 1; i <= N - two_k; i++) {
int id_min1 = ids_min[i][km1];
int id_min2 = ids_min[i + two_km1][km1];
ids_min[i][k] = v[id_min1] <= v[id_min2] ? id_min1 : id_min2;
}
}
}
int rmq(int x, int y, int* v, vector<vector<int>>& ids_min)
{
if (x == y) return x;
int k = (int)log2(y - x);
int id_min1 = ids_min[x][k];
int id_min2 = ids_min[y - (1 << k)][k];
return v[id_min1] <= v[id_min2] ? id_min1 : id_min2;
}
int lca(int u, int v, int* er, int* depths_er, vector<vector<int>>& er_pos, vector<vector<int>>& ids_min)
{
if (u == v) return u;
//who appears first and who second
if (er_pos[u].front() > er_pos[v].front()) swap(u, v); //ensure u is the first and v the second
int pos_v = er_pos[v].front();
unsigned int i = 1;
while (i < er_pos[u].size() && er_pos[u][i] < pos_v) i++;
int pos_u = er_pos[u][i - 1];
//range minimum query for minimum
int id_min = rmq(pos_u, pos_v, depths_er, ids_min);
return er[id_min];
////int the range idf and ids find the node with the minimum depth
//int id_min = pos_u;
//for (int i = pos_u + 1; i <= pos_v; i++) {
// if (depths[er[i]] < depths[er[id_min]]) id_min = i;
//}
////return the lca of the nodes u and v
//return er[id_min];
}
}
//int e_040_lca()
int main()
{
using namespace e_040_lca_;
int N, M;
ifstream ifs("lca.in");
ofstream ofs("lca.out");
ifs >> N >> M;
int* parents = new int[N + 1];
int* depths = new int[N + 1];
for (int i = 2; i <= N; i++) {
int p;
ifs >> p;
parents[i] = p;
}
vector<list<int>> tree;
build_tree(N, parents, tree);
//count the number of childs
int no_ch = 0;
for (int i = 1; i <= N; i++) {
no_ch += tree[i].size();
}
//euler representation
int* er = new int[no_ch + N + 1];
int* depths_er = new int[no_ch + N + 1];
vector<vector<int>> er_pos;
er_pos.resize(N + 1);
int eid = 1;
dfs_euler_depth(1, 0, N, tree, eid, er, er_pos, depths);
for (int i = 1; i <= no_ch + N; i++) depths_er[i] = depths[er[i]];
vector<vector<int>> ids_min;
build_rmq_data(no_ch + N, depths_er, ids_min);
for (int i = 1; i <= M; i++) {
int u, v;
ifs >> u >> v;
ofs << lca(u, v, er, depths_er, er_pos, ids_min) << "\n";
}
ifs.close();
ofs.close();
delete[] parents; delete[] depths; delete[] er;
return 0;
}