#pragma GCC optimize("O3", "unroll-loops")
#pragma GCC target("avx2", "popcnt")
#include <bits/stdc++.h>
// v.erase( unique(all(v)) , v.end() ) -----> removes duplicates and resizes the vector as so
using namespace std;
#define IO_file freopen("output.txt","w",stdout), freopen("input.txt","r",stdin);
#define ll long long
#define lld long double
const lld pi = 3.14159265358979323846;
#define pb push_back
#define pf push_front
#define all(a) a.begin(),a.end()
#define rall(a) a.rbegin(),a.rend()
#define getunique(v) {sort(v.begin(), v.end()); v.erase(unique(v.begin(), v.end()), v.end());}
constexpr int mod = (int)(1e9 + 7);
#define log(x) (31^__builtin_clz(x)) // Easily calculate log2 on GNU G++ compilers
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int rand(int x, int y) {
return uniform_int_distribution<int>(x, y)(rng);
}
const int N = 2e5 + 1;
struct HLD {
int n; // the number of nodes
vector<int> sub, top, depth, parent, in, out, seq;
vector<vector<int> > adj;
vector<int> dep; // for the lift tree
vector<int> up[4]; // for the lift tree
int tick;
HLD() {}
HLD(int n) {
init(n);
}
void init(int n) {
this->n = n;
sub.resize(n + 1);
top.resize(n + 1);
depth.resize(n + 1);
parent.resize(n + 1);
in.resize(n + 1);
out.resize(n + 1);
seq.resize(n + 1);
adj.resize(n + 1, {});
dep.resize(n + 1);
for(int i = 0 ; i < 4 ; i++){
up[i].resize(n + 1);
}
tick = 0;
}
void add_edge(int u, int v) {
adj[u].push_back(v);
adj[v].push_back(u);
}
void build_HLD(int root = 1) {
top[root] = root;
depth[root] = 0;
parent[root] = -1;
up[0][root] = root;
dfs1(root);
dfs2(root);
}
void dfs1(int v) {
if(parent[v] != -1){
adj[v].erase(std::find(adj[v].begin(), adj[v].end(), parent[v]));
}
sub[v] = 1;
for(auto &u : adj[v]){
parent[u] = v;
depth[u] = depth[v] + 1;
dfs1(u);
sub[v] += sub[u];
if(sub[u] > sub[adj[v][0]]){
std::swap(u, adj[v][0]);
}
}
}
void dfs2(int v) {
in[v] = ++tick;
seq[in[v]] = v;
for(auto u : adj[v]){
top[u] = u == adj[v][0] ? top[v] : u;
if(top[u] != top[v]){
dep[u] = dep[top[v]] + 1;
up[0][u] = top[v];
for(int c = 1 ; c < 4 ; c++){
up[c][u] = up[c - 1][up[c - 1][u]];
}
}
dfs2(u);
}
out[v] = tick;
}
// is u an ancestor of v ?
bool is_ancestor(int u, int v) {
return in[u] <= in[v] && in[v] <= out[u];
}
// kth ancestor of u
int lift(int u, int k) {
if(k < 0 || k > depth[u]) return -1;
int t = top[u];
if(depth[t] <= depth[u] - k){
return seq[in[t] + depth[u] - k - depth[t]];
}
for(int c = 3 ; c >= 0 ; c--){
if(depth[up[c][t]] <= depth[u] - k) continue;
t = up[c][t];
}
t = up[0][t];
return seq[in[t] + depth[u] - k - depth[t]];
}
// lowest common ancestor of u and v
int LCA(int u, int v) {
if(depth[u] > depth[v]) swap(u, v);
if(is_ancestor(u, v)) return u;
int tu = top[u];
int tv = top[v];
if(dep[tu] > dep[tv]) swap(tu, tv);
if(is_ancestor(tu, tv)){
for(int c = 3 ; c >= 0 ; c--){
if(dep[up[c][tv]] <= dep[tu]) continue;
tv = up[c][tv];
}
return parent[tv];
}
int k = dep[tv] - dep[tu];
while(k){
int c = log(k);
tv = up[c][tv];
k ^= (1 << c);
}
for(int c = 3 ; c >= 0 ; c--){
if(up[c][tu] == up[c][tv]) continue;
tu = up[c][tu];
tv = up[c][tv];
}
return depth[tu] < depth[tv] ? parent[tu] : parent[tv];
}
};
int main()
{ios_base::sync_with_stdio(0),cin.tie(0);
int n, q; cin>>n>>q;
HLD t(n);
for(int i = 2 ; i <= n ; i++){
int p; cin>>p;
t.add_edge(p, i);
}
t.build_HLD();
while(q--){
int x, y; cin>>x>>y;
cout<<t.LCA(x, y)<<'\n';
}
return 0;
}