#include <cstdio>
#include <iostream>
#include <set>
#include <map>
#include <vector>
using namespace std;
struct node{
int data;
node *lchild,*rchild;
node *parent;
};
typedef node* BiTree;
int n,m;
const int maxn=100010;
int pre[maxn];
int inorder[maxn];
map<int,BiTree> mps;
set<int> s;
BiTree root=NULL;
//根据先序和中序建立二叉树,同时每个节点中设置一个指向父亲节点的指针
BiTree create(int low1,int high1,int low2,int high2,BiTree parent){
if(low1>high1)return NULL;
else{
BiTree t = new node;
t->data=pre[low1];
mps[t->data]=t;//节点数据和对应的指针建立映射
t->parent=parent;
int k;
for( k=low2;k<=high2;k++){
if(inorder[k] == pre[low1])
break;
}
int len=k-low2;
t->lchild=create(low1+1,low1+len,low2,k-1,t);
t->rchild=create(low1+len+1,high1,k+1,high2,t);
return t;
}
}
//得到两个节点的根节点
void check(int a,int b){
vector<int> path1;
vector<int> path2;
BiTree t1=mps[a];
BiTree t2=mps[b];
//找到所要查询的两个节点的路径上所有的祖先节点,包括自己
while(t1!=NULL){
path1.push_back(t1->data);
t1=t1->parent;
}
while(t2!=NULL){
path2.push_back(t2->data);
t2=t2->parent;
}
//从根节点开始搜索,遇到的最后一个相同的节点即为最深的祖先节点。
int i=path1.size()-1;
int j=path2.size()-1;
while(i>=0&&j>=0&&path1[i]==path2[j]){
i--;
j--;
}
int data=path1[i+1];
if(data!=a && data != b){
printf("LCA of %d and %d is %d.\n",a,b,data);
}else if(data ==a ){
printf("%d is an ancestor of %d.\n",data,b);
}else {
printf("%d is an ancestor of %d.\n",data,a);
}
}
int main(){
scanf("%d%d",&m,&n);
for(int i=0;i<n;i++){
scanf("%d",&inorder[i]);
s.insert(inorder[i]);
}
for(int i=0;i<n;i++){
scanf("%d",&pre[i]);
}
root = create(0,n-1,0,n-1,NULL);
for(int i=0;i<m;i++){
int v1,v2;
scanf("%d%d",&v1,&v2);
vector<int> errors;
bool flag =true;
set<int>::iterator it1=s.find(v1);
if(it1 == s.end()){
errors.push_back(v1);
flag= false;
}
set<int>::iterator it2=s.find(v2);
if(it2 == s.end()){
errors.push_back(v2);
flag= false;
}
if(flag == true){
check(v1,v2);
}else{
if(errors.size() ==1 ){
printf("ERROR: %d is not found.\n",errors[0]);
}else{
printf("ERROR: %d and %d are not found.\n",errors[0],errors[1]);
}
}
}
return 0;
}