#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXSIZE=10000020;
int bufpos;
char buf[MAXSIZE];
#define NEG 0
void init(){
	#ifdef LOCAL
		freopen("E.txt","r",stdin);
	#endif
	buf[fread(buf,1,MAXSIZE,stdin)]='\0';
	bufpos=0;
}
#if NEG
int readint(){
	bool isneg;
	int val=0;
	for(;!isdigit(buf[bufpos]) && buf[bufpos]!='-';bufpos++);
	bufpos+=(isneg=buf[bufpos]=='-');
	for(;isdigit(buf[bufpos]);bufpos++)
		val=val*10+buf[bufpos]-'0';
	return isneg?-val:val;
}
#else
int readint(){
	int val=0;
	for(;!isdigit(buf[bufpos]);bufpos++);
	for(;isdigit(buf[bufpos]);bufpos++)
		val=val*10+buf[bufpos]-'0';
	return val;
}
#endif
char readchar(){
	for(;isspace(buf[bufpos]);bufpos++);
	return buf[bufpos++];
}
int readstr(char* s){
	int cur=0;
	for(;isspace(buf[bufpos]);bufpos++);
	for(;!isspace(buf[bufpos]);bufpos++)
		s[cur++]=buf[bufpos];
	s[cur]='\0';
	return cur;
}
const int maxn=100005;
struct segtree{
	int n;
	int mn[maxn*4],tag[maxn*4];
	int lst[maxn*100],nxt[maxn*100];
	void qwq(int o){
		nxt[lst[o]]=nxt[o];
		lst[nxt[o]]=lst[o];
	}
	int tot;
	int ul,ur;
	void pu(int o){
		mn[o]=min(mn[o*2],mn[o*2+1])+tag[o];
	}
	void add(int o,int l,int r){
		if (ul<=l && ur>=r){
			mn[o]++;
			tag[o]++;
			tot++;
			nxt[tot]=nxt[o];
			lst[nxt[o]]=tot;
			nxt[o]=tot;
			lst[tot]=o;
			return;
		}
		int mid=(l+r)/2;
		if (ul<=mid)
			add(o*2,l,mid);
		if (ur>mid)
			add(o*2+1,mid+1,r);
		pu(o);
	}
	void add(int l,int r){
		// printf("add %d %d\n",l,r);
		ul=l,ur=r;
		add(1,1,n);
	}
	void del(int o,int l,int r){
		if (ul<=l && ur>=r){
			mn[o]--;
			tag[o]--;
			return;
		}
		int mid=(l+r)/2;
		if (ul<=mid)
			del(o*2,l,mid);
		if (ur>mid)
			del(o*2+1,mid+1,r);
		pu(o);
	}
	void del(int l,int r){
		// printf("del %d %d\n",l,r);
		ul=l,ur=r;
		del(1,1,n);
	}
	int pop(int o,int l,int r){
		if (l==r){
			mn[o]=maxn;
			tag[o]=0;
			return nxt[o];
		}
		int mid=(l+r)/2;
		int ans=nxt[o];
		if (mn[o*2]<=mn[o*2+1])
			ans|=pop(o*2,l,mid);	
		else ans|=pop(o*2+1,mid+1,r);
		pu(o);
		return ans;
	}
	int pop(){
		return pop(1,1,n);
	}
}t;
struct graph{
	int n,m;
	struct edge{
		int to,next;
	}e[maxn*2];
	int first[maxn];
	void addedge(int from,int to){
		e[++m]=(edge){to,first[from]};
		first[from]=m;
	}
	int fa[maxn],top[maxn],dep[maxn],sz[maxn],id[maxn],son[maxn],cl;
	void dfs(int u){
		sz[u]=1;
		for(int i=first[u];i;i=e[i].next){
			int v=e[i].to;
			if (fa[u]==v)
				continue;
			fa[v]=u;
			dep[v]=dep[u]+1;
			dfs(v);
			sz[u]+=sz[v];
			if (sz[v]>sz[son[u]])
				son[u]=v;
		}
	}
	void dfs2(int u,int tp){
		top[u]=tp;
		id[u]=cl++;
		if (son[u])
			dfs2(son[u],tp);
		for(int i=first[u];i;i=e[i].next){
			int v=e[i].to;
			if (!top[v])
				dfs2(v,v);
		}
	}
	void prepare(){
		dfs(1);
		dfs2(1,1);
		t.n=n-1;
		t.tot=n*4;
	}
	int fst[maxn];
	pair<int,int> w[maxn];
	void add(int u,int v,int p){
		fst[p]=t.tot+1;
		w[p]=make_pair(u,v);
		for(;top[u]!=top[v];u=fa[top[u]]){
			if (dep[top[u]]<dep[top[v]])
				swap(u,v);
			t.add(id[top[u]],id[u]);
		}
		if (dep[u]>dep[v])
			swap(u,v);
		if (u!=v)
			t.add(id[u]+1,id[v]);
	}
	void del(int u,int v){
		for(;top[u]!=top[v];u=fa[top[u]]){
			if (dep[top[u]]<dep[top[v]])
				swap(u,v);
			t.del(id[top[u]],id[u]);
		}
		if (dep[u]>dep[v])
			swap(u,v);
		if (u!=v)
			t.del(id[u]+1,id[v]);
	}
	bool work(){
		fst[n]=t.tot+1;
		int T=n-1;
		// puts("WTF");
		while(T--){
			if (t.mn[1]!=1){
				// printf("mn=%d on %d\n",t.mn[1],T);
				return false;
			}
			// printf("%d\n",T);
			int o=t.pop(),p=upper_bound(fst+1,fst+n,o)-fst-1;
			for(int i=fst[p];i<fst[p+1];i++)
				t.qwq(i);
			// printf("p=%d\n",p);
			del(w[p].first,w[p].second);
		}
		return true;
	}
}g;
int main(){
	init();
	// puts("WTF");
	int n=g.n=readint();
	// puts("WTF");
	for(int i=1;i<n;i++){
		int u=readint(),v=readint();
		g.addedge(u,v);
		g.addedge(v,u);
	}
	// puts("WTF");
	g.prepare();
	// puts("WTF");
	for(int i=1;i<n;i++){
		int u=readint(),v=readint();
		g.add(u,v,i);
	}
	puts(g.work()?"YES":"NO");
}


Measured memory_bytes: 40704