#include<algorithm>
#include<cstring>
#include<cctype>
#include<cstdio>
#include<set>
#define rep(i,x,y) for(int i=x; i<=y; ++i)
#define mid (l+r>>1)
#define lch (rt<<1)
#define rch (rt<<1|1)

using namespace std;
const int N=100005,M=6500005,INF=1000000000;
int n,h[N],cnt,cur[N<<2],H[N<<2];
int son[N],siz[N],fa[N],x,ql,qr;
int dfn[N],pos[N],top[N],dep[N];
struct edge{int v,n;} e[N<<1];
struct data{int u,v;} dat[N];
struct seg{int mn,x;} t[N<<2];
struct Set
{
	int x,id;
	
	bool operator < (const Set &y) const
	{
		return x==y.x?id<y.id:x<y.x;
	}
};
set <Set> st[N];

int getint()
{
	char ch;
	while(!isdigit(ch=getchar()));
	int x=ch-48;
	while(isdigit(ch=getchar())) x=x*10+ch-48;
	return x;
}

seg operator + (seg x,seg y)
{
	return x.mn<y.mn?x:y;
}

void addedge(int u,int v)
{
	e[cnt]=(edge){v,h[u]},h[u]=cnt++;
	e[cnt]=(edge){u,h[v]},h[v]=cnt++;
}

void dfs(int x,int f,int d)
{
	fa[x]=f,dep[x]=d,siz[x]=1;
	for(int i=h[x]; i!=-1; i=e[i].n)
		if(e[i].v!=f)
		{
			dfs(e[i].v,x,d+1);
			siz[x]+=siz[e[i].v];
			if(!son[x] || siz[son[x]]<siz[e[i].v])
				son[x]=e[i].v;
		}
}

void dfs(int x,int t)
{
	top[x]=t,pos[dfn[x]=++*dfn]=x;
	if(son[x]) dfs(son[x],t);
	for(int i=h[x]; i!=-1; i=e[i].n)
		if(e[i].v!=fa[x] && e[i].v!=son[x])
			dfs(e[i].v,e[i].v);
}

void build(int l,int r,int rt)
{
	if(l==r)
	{
		t[rt].x=l,H[rt]=dep[pos[l]];
		return;
	}
	build(l,mid,lch),build(mid+1,r,rch);
	t[rt]=t[lch]+t[rch];
}

void turn(int rt,int x)
{
	t[rt].mn+=x,cur[rt]+=x;
}

void pushdown(int rt)
{
	if(cur[rt]) turn(lch,cur[rt]),turn(rch,cur[rt]),cur[rt]=0;
}

void modify(int l,int r,int rt,int ql,int qr,int x)
{
	if(ql>qr) return;
	if(ql<=l && r<=qr)
	{
		turn(rt,x);
		return;
	}
	pushdown(rt);
	if(ql<=mid) modify(l,mid,lch,ql,qr,x);
	if(mid<qr) modify(mid+1,r,rch,ql,qr,x);
	t[rt]=t[lch]+t[rch];
}

int ins(int x,int y,int tp)
{
	while(top[x]!=top[y])
		if(dep[top[x]]>dep[top[y]]) modify(2,n,1,dfn[top[x]],dfn[x],tp),x=fa[top[x]];
		else modify(2,n,1,dfn[top[y]],dfn[y],tp),y=fa[top[y]];
	if(dep[x]>dep[y]) swap(x,y);
	modify(2,n,1,dfn[x]+1,dfn[y],tp);
	return x;
}

void ins(int l,int r,int rt,int T,int id,bool tp=0)
{
	if(x==1) return;
	if(l==r)
	{
		if(tp) st[l].erase((Set){dep[T],id});
		else st[l].insert((Set){dep[T],id});
		H[rt]=st[l].empty()?dep[pos[l]]:st[l].begin()->x;
		return;
	}
	if(x<=mid) ins(l,mid,lch,T,id,tp);
	else ins(mid+1,r,rch,T,id,tp);
	H[rt]=min(H[lch],H[rch]);
}

int query(int l,int r,int rt,int d)
{
	if(H[rt]>=d) return 0;
	if(l==r) return st[l].begin()->id;
	if(H[lch]<d && ql<=mid)
	{
		int ret=query(l,mid,lch,d);
		if(ret) return ret;
	}
	return query(mid+1,r,rch,d);
}

bool query()
{
	if(t[1].mn>1)
	{
		puts("NO");
		return 0;
	}
	int ret=t[1].x;
	modify(2,n,1,ret,ret,INF);
	ql=ret,qr=ql+siz[pos[ret]]-1;
	int p=query(2,n,1,dep[pos[ret]]);
	int t=ins(dat[p].u,dat[p].v,-1);
	x=dfn[dat[p].u],ins(2,n,1,t,p,1);
	x=dfn[dat[p].v],ins(2,n,1,t,p,1);
	return 1;
}

int main()
{
	n=getint();
	memset(h,-1,sizeof(h));
	rep(i,1,n-1) addedge(getint(),getint());
	dfs(1,0,1),dfs(1,1),build(2,n,1);
	rep(i,1,n-1)
	{
		dat[i].u=getint(),dat[i].v=getint();
		int t=ins(dat[i].u,dat[i].v,1);
		x=dfn[dat[i].u],ins(2,n,1,t,i);
		x=dfn[dat[i].v],ins(2,n,1,t,i);
	}
	rep(i,1,n-1)
		if(!query())
			return 0;
	puts("YES");
	return 0;
}

Measured memory_bytes: 30208