#include <iostream>
#include <cstdio>
#include <cstring>
#include <set>
#include <queue>
#define N 100005
using namespace std;
struct edge{
	int k,next;
}e[N<<1];
int n,home[N],cnt=-1;
void add(int x,int y){
	cnt++;
	e[cnt].k=y;
	e[cnt].next=home[x];
	home[x]=cnt;
}
int fa[N],dep[N],son[N],siz[N],id[N],id1[N],cc,top[N];
void dfs1(int k,int F){
	fa[k]=F;dep[k]=dep[F]+1;
	siz[k]=1;
	for(int i=home[k];~i;i=e[i].next) if(e[i].k!=F){
		dfs1(e[i].k,k);
		siz[k]+=siz[e[i].k];
		if(siz[e[i].k]>siz[son[k]]) son[k]=e[i].k;
	}
}
void dfs2(int k,int tp){
	top[k]=tp;id[k]=++cc;id1[cc]=k;
	if(son[k]) dfs2(son[k],tp);
	for(int i=home[k];~i;i=e[i].next) if(e[i].k!=fa[k]&&e[i].k!=son[k]){
		dfs2(e[i].k,e[i].k);
	}
}
struct trie{
	set<int> s;
	//priority_queue<int,vector<int>,greater<int> > q;
	bool f0,f1;
	int sum;
	trie(){
		f0=1;
		//q.push(1e9);
	}
}t[N<<2];
struct query{
	int x,y;
}q[N];
/*void pwd(int k,int l,int r){
	if(l==r) return;
	l=k<<1;r=k<<1|1;
	if(t[k].add){
		t[l].add+=t[k].add;
		t[r].add+=t[k].add;
		t[l].sum+=t[k].add;
		t[r].sum+=t[k].add;
		t[k].add=0;
	//	while(t[l].q.top()<=t[l].sum) t[l].q.pop();
	//	while(t[r].q.top()<=t[r].sum) t[r].q.pop();
	}
}*/
void pup(int k,int l,int r){
	if(t[k].sum>1){
		t[k].f1=t[k].f0=0;
		return;
	}
	if(l==r){
		if(t[k].sum==1) t[k].f1=1,t[k].f0=0;
		if(t[k].sum==0) t[k].f1=0,t[k].f0=1;
		return;
	}
	if(t[k].sum==1){
		t[k].f1=t[k<<1].f0|t[k<<1|1].f0;
		t[k].f0=0;
	}
	if(t[k].sum==0){
		t[k].f1=t[k<<1].f1|t[k<<1|1].f1;
		t[k].f0=t[k<<1].f0|t[k<<1|1].f0;
	}

}
void update(int k,int l,int r,int L,int R,int val,int x){
	//pwd(k,l,r);
	if(L>R) return;
	if(L<=l&&R>=r){
		if(val==-1){
			t[k].sum--;
			t[k].s.erase(x);
			//while(t[k].q.top()<=t[k].sum) t[k].q.pop();
		}else{
			t[k].sum++;
			t[k].s.insert(x);
		}
		pup(k,l,r);
		return;
	}
	int mid=l+r>>1;
	if(L<=mid) update(k<<1,l,mid,L,R,val,x);
	if(R>mid) update(k<<1|1,mid+1,r,L,R,val,x);
	pup(k,l,r);
}
int w[N];
void upd(int x,int y,int val,int pos){
	if(val==1) w[x]++,w[y]++;
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		update(1,1,n,id[top[x]],id[x],val,pos);
		x=fa[top[x]];
	}
	if(dep[x]<dep[y]) swap(x,y);
	update(1,1,n,id[y]+1,id[x],val,pos);
	if(val==1) w[y]-=2;
}
void init(int k){
	for(int i=home[k];~i;i=e[i].next) if(e[i].k!=fa[k]){
		init(e[i].k);
		w[k]+=w[e[i].k];
	}
}
void build(int k,int l,int r){
	if(l==r){
		if(w[id1[l]]==1) t[k].f1=1;
		if(w[id1[l]]==0) t[k].f0=1;
		return;
	}
	int mid=l+r>>1;
	build(k<<1,l,mid);
	build(k<<1|1,mid+1,r);
}
int dfs(int k,int l,int r){
	//pwd(k,l,r);
	//if(t[k].q.top()!=t[k].sum+1) return 0;
	if(!t[k].f1) return 0;
	if(t[k].s.size()) return *(t[k].s.begin());
	if(l==r) return 0;
	int mid=l+r>>1,x;
	if(x=dfs(k<<1,l,mid)) return x;
	return dfs(k<<1|1,mid+1,r);
}
bool solve(){
	int x=dfs(1,1,n);
	if(!x) return 0;
	upd(q[x].x,q[x].y,-1,x);
	return 1;
}
int main(){
	memset(home,-1,sizeof(home));
	scanf("%d",&n);
	for(int i=1,x,y;i<n;i++){
		scanf("%d%d",&x,&y);
		add(x,y);add(y,x);
	}
	dfs1(1,0);
	dfs2(1,1);
	for(int i=1,x,y;i<n;i++){
		scanf("%d%d",&x,&y);
		upd(x,y,1,i);
		q[i].x=x;q[i].y=y;
	}
	//init(1);
	//build(1,1,n);
	int tot=0;
	while(solve()) tot++;
	if(tot==n-1) puts("YES");
	else puts("NO");
	return 0;
}

Measured memory_bytes: 130688