#include <bits/stdc++.h>
using namespace std;
#define iinf 2000000000
#define linf 1000000000000000000LL
#define ulinf 10000000000000000000ull
#define MOD1 1000000007LL
#define mpr make_pair
typedef long long LL;
typedef unsigned long long ULL;
typedef unsigned long UL;
typedef unsigned short US;
typedef pair < int , int > pii;
clock_t __stt;
inline void TStart(){__stt=clock();}
inline void TReport(){printf("\nTaken Time : %.3lf sec\n",(double)(clock()-__stt)/CLOCKS_PER_SEC);}
template < typename T > T MIN(T a,T b){return a<b?a:b;}
template < typename T > T MAX(T a,T b){return a>b?a:b;}
template < typename T > T ABS(T a){return a>0?a:(-a);}
template < typename T > void UMIN(T &a,T b){if(b<a) a=b;}
template < typename T > void UMAX(T &a,T b){if(b>a) a=b;}
struct node{
	int l,r;
	set < pii > vs;
	node(){
		vs.clear();
	}
};
struct segT_edge{
	node arr[400005];
	void init(int p,int l,int r){
		arr[p].l=l;
		arr[p].r=r;
		if(l<r){
			int M=((l+r)>>1);
			init((p<<1),l,M);
			init(((p<<1)|1),M+1,r);
		}
	}
	void insert(int p,int d,pii v){
		arr[p].vs.insert(v);
		if(arr[p].l<arr[p].r){
			int M=((arr[p].l+arr[p].r)>>1);
			if(d<=M) insert((p<<1),d,v);
			else 	 insert(((p<<1)|1),d,v);
		}
	}
	void erase(int p,int d,pii v){
		arr[p].vs.erase(arr[p].vs.find(v));
		if(arr[p].l<arr[p].r){
			int M=((arr[p].l+arr[p].r)>>1);
			if(d<=M) erase((p<<1),d,v);
			else 	 erase(((p<<1)|1),d,v);
		}
	}
	pii query(int p,int L,int R){
		if(arr[p].l>=L && arr[p].r<=R){
			if(arr[p].vs.empty()) return mpr(-1,-1);
			if(arr[p].vs.begin()->first<L) return *arr[p].vs.begin();
			if(arr[p].vs.rbegin()->first>R) return *arr[p].vs.rbegin();
			return mpr(-1,-1);
		}
		int M=((arr[p].l+arr[p].r)>>1);
		pii ret=mpr(-1,-1);
		if(L<=M) ret=query((p<<1),L,R);
		if(R>M) UMAX(ret,query(((p<<1)|1),L,R));
		return ret;
	}
}segt_edge;
struct segT_ver{
	int l[400005],r[400005],d[400005];
	pii v[400005];
	void init(int p,int L,int R){
		l[p]=L;
		r[p]=R;
		d[p]=v[p].first=0;
		v[p].second=L;
		if(L<R){
			int M=((L+R)>>1);
			init((p<<1),L,M);
			init(((p<<1)|1),M+1,R);
		}
	}
	void push(int p){
		v[p].first+=d[p];
		if(l[p]<r[p]){
			d[p<<1]+=d[p];
			d[(p<<1)|1]+=d[p];
		}
		d[p]=0;
	}
	void add(int p,int L,int R,int V){
	//	if(p==1)printf("add %d %d %d %d\n",p,L,R,V);
		if(l[p]>=L && r[p]<=R){
			d[p]+=V;
			push(p);
			return;
		}
		push(p);
		int M=((l[p]+r[p])>>1);
		if(L<=M) add((p<<1),L,R,V); else push(p<<1);
		if(R>M) add(((p<<1)|1),L,R,V); else push((p<<1)|1);
		v[p]=MIN(v[p<<1],v[(p<<1)|1]);
	}
	pii query(int p,int L,int R){
		push(p);
		if(l[p]>=L && r[p]<=R)
			return v[p];
		int M=((l[p]+r[p])>>1);
		pii ret=mpr(iinf,-1);
		if(L<=M) ret=query((p<<1),L,R);
		if(R>M) UMIN(ret,query(((p<<1)|1),L,R));
	//	if(p==1) printf("qry %d %d %d %d  %d\n",p,L,R,ret.first,ret.second);
		return ret;
	}
}segt_ver;
int n,tick,lv[100005],fa[20][100005],c[100005],d[100005],sz[100005],rk[100005],id[100005],rid[100005],tpver[100005],mxson[100005];
bool vis[100005];
map < pii , int > mp;
vector < int > adj[100005];
queue < int > Q;
void dfs(int ver,int f){
	int i;
	fa[0][ver]=f;
	sz[ver]=1;
	rk[ver]=(f==-1?0:(rk[f]+1));
	mxson[ver]=-1;
	for(i=0;i<(int)adj[ver].size();++i){
		if(adj[ver][i]!=f) {
			dfs(adj[ver][i],ver);
			sz[ver]+=sz[adj[ver][i]];
			if(mxson[ver]==-1 || sz[adj[ver][i]]>sz[mxson[ver]])
				mxson[ver]=adj[ver][i];
		}
	}
}
void rdfs(int ver,int tpv){
	tpver[ver]=tpv;
	id[ver]=tick;
	rid[tick++]=ver;
	int i;
	if(mxson[ver]!=-1) rdfs(mxson[ver],tpv);
	for(i=0;i<(int)adj[ver].size();++i){
		if(adj[ver][i]!=fa[0][ver] && adj[ver][i]!=mxson[ver]){
			rdfs(adj[ver][i],adj[ver][i]);
		}
	}
	lv[ver]=tick;
}
void build(){
	int i,j;
	for(i=1;i<20;++i){
		for(j=0;j<n;++j){
			if(fa[i-1][j]==-1)
				fa[i][j]=-1;
			else
				fa[i][j]=fa[i-1][fa[i-1][j]];
		}
	}
}
int lca(int u,int v){
	if(rk[u]<rk[v]) swap(u,v);
	int i;
	for(i=19;i>=0;--i) 
		if(fa[i][u]!=-1 && rk[fa[i][u]]>=rk[v]) u=fa[i][u];
	if(u==v) return u;
	for(i=19;i>=0;--i){
		if(fa[i][u]!=fa[i][v]){
			u=fa[i][u];
			v=fa[i][v];
		}
	}
	return fa[0][u];
}
int queryt(int u,int v){// [u,v)
	pii ret=mpr(iinf,-1);
	while(tpver[u]!=tpver[v]){
		int tp=tpver[u];
		UMIN(ret,segt_ver.query(1,id[tp],id[u]));
		u=fa[0][tp];
	}
	if(rk[u]>rk[v]) UMIN(ret,segt_ver.query(1,id[v]+1,id[u]));
	if(ret.first==1) return rid[ret.second];
	//assert(ret.first!=0);
	return -1;
}
void modifyt(int u,int v,int d){// [u,v)
	//printf("modify %d %d %d\n",u,v,d);
	while(tpver[u]!=tpver[v]){
		int tp=tpver[u];
		segt_ver.add(1,id[tp],id[u],d);
		u=fa[0][tp];
	}
	if(rk[u]>rk[v]) segt_ver.add(1,id[v]+1,id[u],d);
}
int main(){
    // inputting start
    // 数据结构记得初始化！ n，m别写反！
    scanf("%d",&n);
	int i,j,k;
	for(i=0;i<n-1;++i){
		scanf("%d%d",&j,&k);
		--j;--k;
		adj[j].push_back(k);
		adj[k].push_back(j);
	}
    #ifdef LOCAL
        TStart();
    #endif
    // calculation start
    // 数据结构记得初始化！ n，m别写反！
	segt_ver.init(1,0,n+1);
	segt_edge.init(1,0,n+1);
    dfs(0,-1);
	rdfs(0,0);
	build();
	for(i=0;i<n-1;++i){
		scanf("%d%d",c+i,d+i);
		--c[i];--d[i];
		modifyt(c[i],lca(c[i],d[i]),1);
		modifyt(d[i],lca(c[i],d[i]),1);
		mp[mpr(c[i],d[i])]=mp[mpr(d[i],c[i])]=i;
		segt_edge.insert(1,id[c[i]],mpr(id[d[i]],id[c[i]]));
		segt_edge.insert(1,id[d[i]],mpr(id[c[i]],id[d[i]]));
	}
	//for(i=1;i<n;++i) printf(" %d\n",queryt(i,fa[0][i]));
	for(i=0;i<n-1;++i){
		int v=MAX(queryt(c[i],lca(c[i],d[i])),queryt(d[i],lca(c[i],d[i])));
		if(v!=-1){
			Q.push(i);
			vis[i]=1;
			while(v!=-1){
			//	printf("%d\n",v);
				modifyt(v,fa[0][v],iinf);
				v=MAX(queryt(c[i],lca(c[i],d[i])),queryt(d[i],lca(c[i],d[i])));
			}
		}
	}
	while(!Q.empty()){
		int C=c[Q.front()],D=d[Q.front()],LCA;
		Q.pop();
		segt_edge.erase(1,id[C],mpr(id[D],id[C]));
		segt_edge.erase(1,id[D],mpr(id[C],id[D]));
		LCA=lca(C,D);
		modifyt(C,LCA,-1);
		modifyt(D,LCA,-1);
		int la=queryt(C,LCA);
		while(la!=-1){
			modifyt(la,fa[0][la],iinf);
			pii nv=segt_edge.query(1,id[la],lv[la]-1);
			nv.first=rid[nv.first];
			nv.second=rid[nv.second];
			if(nv.second!=-1 && !vis[mp[nv]]){
				Q.push(mp[nv]);
				vis[mp[nv]]=1;
			}
			la=queryt(C,LCA);
		}
		la=queryt(D,LCA);
		while(la!=-1){
			modifyt(la,fa[0][la],iinf);
			pii nv=segt_edge.query(1,id[la],lv[la]-1);
			nv.first=rid[nv.first];
			nv.second=rid[nv.second];
			if(nv.second!=-1 && !vis[mp[nv]]) {
				Q.push(mp[nv]);
				vis[mp[nv]]=1;
			}
			la=queryt(D,LCA);
		}
	}
	for(i=0;i<n-1;++i){
		if(!vis[i]){
			printf("NO");
			return 0;
		}
	}
	printf("YES");
    #ifdef LOCAL
        TReport();
    #endif
    return 0;
}

Measured memory_bytes: 232192