#include <stdio.h>
#include <vector>
using namespace std;
int min(int x, int y) {
if (x <= y) {
return x;
}
return y;
}
int find_root(const std::vector<std::vector<int>>& graph, const int num_nodes) {
int entry_level[num_nodes + 1] = {0};
for (register int i = 0; i < num_nodes; ++i) {
for (int son : graph[i]) {
entry_level[son]++;
}
}
for (register int i = 0; i < num_nodes; ++i) {
if (entry_level[i] == 0) {
return i;
}
}
return -1;
}
void compute_euler(const std::vector<std::vector<int>>& graph,\
std::vector<int> &euler, int *first_appearance,\
int *node_order, int node, bool *visited, int &counter) {
if (visited[node] == false) {
visited[node] = true;
int node_id = counter;
node_order[counter++] = node;
first_appearance[node] = euler.size();
euler.push_back(node_id);
for (int son : graph[node]) {
compute_euler(graph, euler, first_appearance, node_order,\
son, visited, counter);
euler.push_back(node_id);
}
}
}
void compute_rmq(const std::vector<int>& log, std::vector<std::vector<int> >& rmq,\
const std::vector<int>& euler, const int size) {
for (register int i = 0; i < size; ++i) {
rmq[i][0] = euler[i];
}
int power = 2;
for (register int step = 1; power <= size; ++step, power <<= 1) {
int put = power >> 1;
for (register int i = 0; i + put < size; ++i) {
rmq[i][step] = min(rmq[i][step - 1], rmq[i + put][step - 1]);
}
}
}
int query_rmq(const std::vector<int>& log, const std::vector<std::vector<int> >& rmq,\
int x, int y, int *first_appearance, int *node_order) {
int l = first_appearance[x];
int r = first_appearance[y];
if (r < l) {
int aux = l;
l = r;
r = aux;
}
int step = log[r - l + 1];
return node_order[min(rmq[l][step], rmq[r - (1 << step) + 1][step])];
}
void compute_log(std::vector<int>& log, int size) {
for (register int i = 1; (1 << i) <= size; ++i) {
log[1 << i] = 1;
}
for (register int i = 1; i <= size ; ++i) {
log[i] += log[i - 1];
}
}
std::vector<int> lca(const std::vector<std::vector<int>>& graph, int m, FILE *out, FILE *in) {
std::vector<int> euler;
int num_nodes = graph.size() - 1;
bool visited[num_nodes + 1] = {false};
int first_appearance[num_nodes + 1] = {0};
int node_order[num_nodes + 1] = {0};
int counter = 0;
int root = 1;
compute_euler(graph, euler, first_appearance, node_order, root, visited, counter);
std::vector<int> log(euler.size(), 0);
compute_log(log, euler.size());
std::vector<std::vector<int> > rmq(euler.size(), std::vector<int>(log[euler.size()]));
compute_rmq(log, rmq, euler, euler.size());
for (register int i = 0; i < m; ++i){
int x, y;
fscanf(in, "%d%d", &x, &y);
int sol = query_rmq(log, rmq, x, y, first_appearance, node_order);
fprintf(out, "%d\n", sol);
}
return std::vector<int>();
}
int main() {
int n, m;
FILE *in, *out;
in = fopen("lca.in", "r");
out = fopen("lca.out", "w");
fscanf(in, "%d %d", &n, &m);
vector< vector<int> > *graph = new vector< vector<int> >(n + 1, vector<int>(0));
// vector < pair<int, int> > *queries = new vector < pair<int, int> >(0);
for (register int i = 1; i < n; ++i) {
int x;
fscanf(in, "%d", &x);
graph -> at(x).push_back(i + 1);
}
lca(*graph, m, out, in);
return 0;
}