// tzl ak IOI! 
 
#include<bits/stdc++.h>
 
#define HEAP priority_queue
#define rep(i, n) for(int i = 0, _end_ = (n); i < _end_; ++i)
#define per(i, n) for(int i = (n) - 1; i >= 0 ; --i)
#define forn(i, l, r) for(int i = (l), _end_ = (r); i <= _end_; ++i)
#define nrof(i, r, l) for(int i = (r), _end_ = (l); i >= _end_; --i)
#define FOR(a, b) for(auto (a): (b))
#define mp make_pair
#define mt make_tuple
#define pb push_back
#define X first
#define Y second
#define eps 1e-6
#define pi 3.1415926535897932384626433832795
#define SZ(x) (int)x.size()
#define ALL(x) x.begin(), x.end()
#define FILL(a, b) memset((a), (b), sizeof((a)))
#define MCPY(a, b) memcpy((a), (b), sizeof((b)))
 
using namespace std;
 
typedef long long LL;
typedef double flt;
typedef vector<int> vi;
typedef vector<LL> vl;
typedef pair<int,int> pii;
typedef pair<int,LL> pil;
typedef pair<LL,int> pli;
typedef pair<LL,LL> pll;
typedef vector<pil> vil;
typedef vector<pii> vii;
typedef vector<pli> vli;
typedef vector<pll> vll;
 
const int iinf = 1e9 + 7;
const LL linf = 1ll << 60;
const flt dinf = 1e60;
 
template <typename T>
inline void scf(T &x)
{
	bool f = 0; x = 0; char c = getchar();
	while((c < '0' || c > '9') && c != '-') c = getchar();
	if(c == '-') { f = 1; c = getchar(); }
	while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
	if(f) x = -x; return;
}
 
template <typename T1, typename T2>
void scf(T1 &x, T2 &y) { scf(x); return scf(y); }
 
template <typename T1, typename T2, typename T3>
void scf(T1 &x, T2 &y, T3 &z) { scf(x); scf(y); return scf(z); }
 
template <typename T1, typename T2, typename T3, typename T4>
void scf(T1 &x, T2 &y, T3 &z, T4 &w) { scf(x); scf(y); scf(z); return scf(w); }
 
inline char mygetchar(){ char c = getchar(); while(c == ' ' || c == '\n') c = getchar(); return c; }
 
template <typename T>
void chkmax(T &x, const T &y){ if(y > x) x = y; return; }
 
template <typename T>
void chkmin(T &x, const T &y){ if(y < x) x = y; return; }
 
#define ONLINE_JUDGE
 
#ifdef ONLINE_JUDGE
#define debug(x,c) ;
#else
#define DEBUG
#define debug(x,c) cerr<<#x<<"="<<x<<c;
#endif
 
void TZL();
 
void RANK1();
 
#define tzl int
#define ak main
#define IOI ()
tzl ak IOI
{
#undef tzl
#undef ak
#undef IOI
 
	TZL();
	RANK1();
 
#define tzl return
#define caisi 0
#define myy ;
	tzl caisi myy
#undef tzl
#undef caisi
#undef myy
}
 
//---------------------------head----------------------------
 
const int N = 1e5 + 100;
 
int n, tot;
vi g[N];
int dep[N], par[N], son[N], siz[N], hs[N], anc[N], dfn[N], End[N], M[N];

struct fuck1 
{
	set<pii> num[N << 2];

	int L(int i){ return i << 1; }
	int R(int i){ return (i << 1) | 1; }

	void ins(int i, int x, int l = 1, int r = n, int k = 1)
	{
		num[k].insert({x, i});
		if(l == r) return;

		int mid = l + r >> 1;
		if(i <= mid) ins(i, x, l, mid, L(k));
		else ins(i, x, mid + 1, r, R(k));
		return;
	}
	
	void del(int i, int x, int l = 1, int r = n, int k = 1)
	{
		num[k].erase({x, i});
		if(l == r) return;
		
		int mid = l + r >> 1;
		if(i <= mid) del(i, x, l, mid, L(k));
		else del(i, x, mid + 1, r, R(k));
		return;
	}

	pii ans;

	void Q(int a, int b, int l, int r, int k)
	{
		if(a == l && b == r)
		{
			if(SZ(num[k])) chkmax(ans, *(--num[k].end()));
			return;
		}

		int mid = l + r >> 1;
		if(a > mid) Q(a, b, mid + 1, r, R(k));
		else if(b <= mid) Q(a, b, l, mid, L(k));
		else Q(a, mid, l, mid, L(k)), Q(mid + 1, b, mid + 1, r, R(k));
		return;
	}

	pii Q(int a, int b)
	{
		ans = {-1, -1};
		Q(a, b, 1, n, 1);
		return ans;
	}
}s1;
 
struct fuck2 
{
	set<pii> num[N << 2];

	int L(int i){ return i << 1; }
	int R(int i){ return (i << 1) | 1; }

	void ins(int i, int x, int l = 1, int r = n, int k = 1)
	{
		num[k].insert({x, i});
		if(l == r) return;

		int mid = l + r >> 1;
		if(i <= mid) ins(i, x, l, mid, L(k));
		else ins(i, x, mid + 1, r, R(k));
		return;
	}
	
	void del(int i, int x, int l = 1, int r = n, int k = 1)
	{
		num[k].erase({x, i});
		if(l == r) return;
		
		int mid = l + r >> 1;
		if(i <= mid) del(i, x, l, mid, L(k));
		else del(i, x, mid + 1, r, R(k));
		return;
	}

	pii ans;

	void Q(int a, int b, int l, int r, int k)
	{
		if(a == l && b == r)
		{
			if(SZ(num[k])) chkmin(ans, *num[k].begin());
			return;
		}

		int mid = l + r >> 1;
		if(a > mid) Q(a, b, mid + 1, r, R(k));
		else if(b <= mid) Q(a, b, l, mid, L(k));
		else Q(a, mid, l, mid, L(k)), Q(mid + 1, b, mid + 1, r, R(k));
		return;
	}

	pii Q(int a, int b)
	{
		ans = {iinf, iinf};
		Q(a, b, 1, n, 1);
		return ans;
	}
}s2;
 
void dfs0(int u = 1, int fa = 0)
{
	dep[u] = dep[fa] + 1; par[u] = fa; siz[u] = 1;
	for(int v: g[u]) if(v != fa)
	{
		dfs0(v, u);
		siz[u] += siz[v];
		if(siz[v] > hs[u]) hs[u] = siz[v], son[u] = v;
	}
	return;
}
 
void dfs1(int u = 1, int fa = 1)
{
	anc[u] = fa; M[dfn[u] = (++tot)] = u;
	if(son[u]) dfs1(son[u], fa);
 
	for(int v: g[u]) if(v != par[u] && v != son[u])
	{
		dfs1(v, v);
	}
	End[u] = tot;
	return;
}
 
int fuck[N];
 
void add(int u, int v)
{
	int mn = min(dfn[u], dfn[v]), mx = max(dfn[u], dfn[v]);
	s1.ins(mn, mx);
	s2.ins(mx, mn);
 
	while(anc[u] != anc[v])
	{
		if(dep[anc[u]] < dep[anc[v]]) swap(u, v);
#ifdef DEBUG
		printf("M(%d, %d, 1)\n", dfn[anc[u]], dfn[u]);
#endif
		++fuck[dfn[anc[u]]];
		--fuck[dfn[u] + 1];
		u = par[anc[u]];
	}
 
	if(dep[u] < dep[v]) swap(u, v);
	if(u != v)
	{
#ifdef DEBUG
		printf("M(%d, %d, 1)\n", dfn[v] + 1, dfn[u]);
#endif
		++fuck[dfn[v] + 1];
		--fuck[dfn[u] + 1];
	}
	return;
}
 
namespace seg
{
	int tag[N << 2];
	pii num[N << 2];
 
	int L(int i){ return i << 1; }
	int R(int i){ return (i << 1) | 1; }
 
	void pull(int i)
	{
		num[i] = min(num[L(i)], num[R(i)]);
		return;
	}
 
	void push(int i)
	{
		if(tag[i])
		{
			int l = L(i), r = R(i);
			tag[l] += tag[i], tag[r] += tag[i];
			num[l].X += tag[i], num[r].X += tag[i];
			tag[i] = 0;
		}
		return;
	}
 
	void M(int a, int b, int x, int l = 1, int r = n, int k = 1)
	{
		if(a == l && b == r)
		{
			num[k].X += x;
			tag[k] += x;
			return;
		}
 
		int mid = l + r >> 1; push(k);
		if(a > mid) M(a, b, x, mid + 1, r, R(k));
		else if(b <= mid) M(a, b, x, l, mid, L(k));
		else M(a, mid, x, l, mid, L(k)), M(mid + 1, b, x, mid + 1, r, R(k));
		return pull(k);
	}
 
	pii Q()
	{
		return num[1];
	}
 
	void B(int *a, int l = 1, int r = n, int k = 1)
	{
		tag[k] = 0;
		if(l == r)
		{
			num[k] = {a[l], l};
			return;
		}
 
		int mid = l + r >> 1;
		B(a, l, mid, L(k)); B(a, mid + 1, r, R(k));
		return pull(k);
	}
 
	void out(int l = 1, int r = n, int k = 1, int tab = 1)
	{
		if(l == r)
		{
			rep(i, tab) putchar('\t'); printf("[%d, %d]:\t{%d, %d} %d\n", l, r, num[k].X, num[k].Y, tag[k]);
			return;
		}
		int mid = l + r >> 1;
		out(l, mid, L(k), tab + 1);
		rep(i, tab) putchar('\t'); printf("[%d, %d]:\t{%d, %d} %d\n", l, r, num[k].X, num[k].Y, tag[k]);
		out(mid + 1, r, R(k), tab + 1);
		return;
	}
}
 
void TZL()
{
	scf(n);
	rep(i, n - 1)
	{
		int u, v; scf(u, v);
		g[u].pb(v); g[v].pb(u);
	}
	dfs0(); dfs1();
#ifdef DEBUG
	forn(i, 1, n) printf("%d %d\t[%d, %d]\n", i, son[i], dfn[i], End[i]);
#endif
	rep(i, n - 1)
	{
		int u, v; scf(u, v);
		add(u, v);
	}
	forn(i, 1, n) fuck[i] += fuck[i - 1];
	seg::B(fuck);
	return;
}
 
void del(int u, int v)
{
	int mn = min(dfn[u], dfn[v]), mx = max(dfn[u], dfn[v]);
	s1.del(mn, mx);
	s2.del(mx, mn);
 
	while(anc[u] != anc[v])
	{
		if(dep[anc[u]] < dep[anc[v]]) swap(u, v);
#ifdef DEBUG
		printf("M(%d, %d, -1)\n", dfn[anc[u]], dfn[u]);
#endif
		seg::M(dfn[anc[u]], dfn[u], -1);
		u = par[anc[u]];
	}
 
	if(dep[u] < dep[v]) swap(u, v);
	if(u != v)
	{
#ifdef DEBUG
		printf("M(%d, %d, -1)\n", dfn[v] + 1, dfn[u]);
#endif
		seg::M(dfn[v] + 1, dfn[u], -1);
	}
	return;
}
 
void RANK1()
{
	//seg::out();
	rep(i, n - 1)
	{
		pii foo = seg::Q(), bar;
		while(!foo.X)
		{
			int i = foo.Y;
			seg::M(i, i, 1000000);
			foo = seg::Q();
		}
		/*
		puts("===================================================================================================================");
		seg::out();
		*/
 
		if(foo.X != 1)
		{
			puts("NO");
			return;
		}
 
		int u = M[foo.Y];
		int a = dfn[u], b = End[u];
		foo = s1.Q(a, b), bar = s2.Q(a, b);
		int x, y;
		if(foo.X != -1 && foo.X > b) x = foo.X, y = foo.Y;
		else x = bar.X, y = bar.Y;
 
		x = M[x], y = M[y];
		del(x, y);
		/*
		puts("-------------------------------------------------------------------------------------------------------------------");
		seg::out();
		*/
	}
	puts("YES");
	return;
}

Measured memory_bytes: 223360