#include <iostream> #include <cstdio> #include <cstring> #include <stdlib.h> using namespace std; #define M 1001 typedef struct Tree { int data; struct Tree *lson,*rson; } TNode,*ListTree; ListTree built(int n) { int val; ListTree point[M]; memset(point,NULL,sizeof(point)); for(int i=1; i<=n; i++) { scanf("%d",&val); point[i]=(ListTree)malloc(sizeof(TNode)); point[i]->data=val; point[i]->lson=NULL; point[i]->rson=NULL; } for(int i=1; i<=n; i++) { int k; scanf("%d",&k); for(int j=0; j<k; j++) { int tmp; scanf("%d",&tmp); if(j==0) point[i]->lson=point[tmp]; if(j==1) point[i]->rson=point[tmp]; } } return point[1]; } void output(ListTree root)//前序遍历 { if(root!=NULL) { cout<<root->data<<" "; output(root->lson); output(root->rson); } } bool judge(ListTree ra,ListTree rb)//验证rb是不是ra的子树 { if(rb==NULL) return true; if(ra==NULL) return false; if(ra->data!=rb->data) return false; return judge(ra->lson,rb->lson)&&judge(ra->rson,rb->rson); } bool solve(ListTree ra,ListTree rb)//在ra中与rb根节点相同 { bool ans=false; if(ra!=NULL&&rb!=NULL) { if(ra->data==rb->data) ans=judge(ra,rb); if(!ans) ans=solve(ra->lson,rb); if(!ans) ans=solve(ra->rson,rb); } return ans; } int main() { int n,m; while(scanf("%d %d",&n,&m)!=EOF) { ListTree roota=built(n); ListTree rootb=built(m); if(m==0) { printf("NO\n"); continue; } bool result=solve(roota,rootb); if(result) printf("YES\n"); else printf("NO\n"); } return 0; }