#include <bits/stdc++.h>
using namespace std;
ifstream in;
ofstream out;
struct Node{
int key;
struct Node *left,*right;
};
Node new_node(int key)
{
Node *temp = new Node;
temp->key = key;
temp->left = temp->right = NULL;
return (*temp);
};
void createNode(int parent[], int i, Node *created[], Node **root)
{
if(created[i]!=NULL)
return;
if(parent[i]==-1)
{
*root=created[i];
return;
}
if (created[parent[i]] == NULL)
createNode(parent, parent[i], created, root);
Node *p = created[parent[i]];
if (p->left == NULL)
p->left = created[i];
else
p->right = created[i];
}
Node *createTree(int parent[], int n)
{
Node *created[n];
for (int i=0; i<n; i++)
created[i] = NULL;
Node *root = NULL;
for (int i=0; i<n; i++)
createNode(parent, i, created, &root);
return root;
}
struct Node *findLCAUtil(struct Node* root, int n1, int n2, bool &v1, bool &v2)
{
// Base case
if (root == NULL) return NULL;
// If either n1 or n2 matches with root's key, report the presence
// by setting v1 or v2 as true and return root (Note that if a key
// is ancestor of other, then the ancestor key becomes LCA)
if (root->key == n1)
{
v1 = true;
return root;
}
if (root->key == n2)
{
v2 = true;
return root;
}
// Look for keys in left and right subtrees
Node *left_lca = findLCAUtil(root->left, n1, n2, v1, v2);
Node *right_lca = findLCAUtil(root->right, n1, n2, v1, v2);
// If both of the above calls return Non-NULL, then one key
// is present in once subtree and other is present in other,
// So this node is the LCA
if (left_lca && right_lca) return root;
// Otherwise check if left subtree or right subtree is LCA
return (left_lca != NULL)? left_lca: right_lca;
}
// Returns true if key k is present in tree rooted with root
bool find(Node *root, int k)
{
// Base Case
if (root == NULL)
return false;
// If key is present at root, or in left subtree or right subtree,
// return true;
if (root->key == k || find(root->left, k) || find(root->right, k))
return true;
// Else return false
return false;
}
// This function returns LCA of n1 and n2 only if both n1 and n2 are present
// in tree, otherwise returns NULL;
Node *findLCA(Node *root, int n1, int n2)
{
// Initialize n1 and n2 as not visited
bool v1 = false, v2 = false;
// Find lca of n1 and n2 using the technique discussed above
Node *lca = findLCAUtil(root, n1, n2, v1, v2);
// Return LCA only if both n1 and n2 are present in tree
if (v1 && v2 || v1 && find(lca, n2) || v2 && find(lca, n1))
return lca;
// Else return NULL
return NULL;
}
int parent[100001],n,m;
Node *created[100001];
int main() {
in.open("lca.in");
out.open("lca.out");
in>>n>>m;
parent[1]=-1;
for(int i=2;i<=n;i++)
{
in>>parent[i];
}
Node *root = createTree(parent, n);
for(int i=1;i<=m;i++)
{
int n1,n2;
in>>n1>>n2;
out<<findLCA(root, n1, n2)->key<<'\n';
}
return 0;
}