// what could go wrong
// first time coding hld
// I though it was useless...

#include <bits/stdc++.h>
using namespace std;

const int INF = 1000000;

struct node
{
	node *l, *r;
	int lo, hi, va;
	set<int> all;
	node(int L, int H) : l(NULL), r(NULL), lo(L), hi(H), va(0) { }
	void add(int rlo, int rhi, int v)
	{
		if (lo == rlo && hi == rhi)
		{
			va++;
			all.insert(v);
		} else
		{
			int mid = (lo+hi) / 2;
			if (rhi <= mid) l->add(rlo, rhi, v);
			else if (rlo >= mid) r->add(rlo, rhi, v);
			else
			{
				l->add(rlo, mid, v);
				r->add(mid, rhi, v);
			}
			va = min(l?l->va:INF, r?r->va:INF)+all.size();
		}
	}
	void init(int loc)
	{
		if (lo+1 == hi) return;
		int mid = (lo+hi) / 2;
		if (loc < mid) (l?l:(l=new node(lo, mid)))->init(loc);
		else (r?r:(r=new node(mid, hi)))->init(loc);
	}
	void del(int rlo, int rhi, int v)
	{
		if (lo == rlo && hi == rhi)
		{
			all.erase(v);
			va--;
		} else
		{
			int mid = (lo+hi) / 2;
			if (rhi <= mid) l->del(rlo, rhi, v);
			else if (rlo >= mid) r->del(rlo, rhi, v);
			else
			{
				l->del(rlo, mid, v);
				r->del(mid, rhi, v);
			}
			va = min(l?l->va:INF, r?r->va:INF)+all.size();
		}
	}
	void destroy(int loc)
	{
		if (lo+1 == hi)
		{
			va = INF;
			return;
		}
		int mid = (lo+hi) / 2;
		if (loc < mid) l->destroy(loc);
		else r->destroy(loc);
		va = min(l?l->va:INF, r?r->va:INF);
	}
};

set<pair<int, int> > pq;
vector<int> ch[100005];
int traffic[100005];
int par[20][100005];
node *tr[100005];
int head[100005];
int dep[100005];
int sz[100005];
int A[100005];
int B[100005];
int n;

int dfs1(int at)
{
	sz[at] = 1;
	for (int u: ch[at]) if (u != par[0][at])
	{
		par[0][u] = at;
		dep[u] = dep[at] + 1;
		sz[at] += dfs1(u);
	}
	return sz[at];
}

void dfs2(int at, int _h)
{
	head[at] = _h;
	if (at == _h) tr[at] = new node(0, 131072);
	if (at) tr[_h]->init(dep[at]-dep[_h]);
	int hi = -1;
	for (int u: ch[at]) if (u != par[0][at])
		hi = max(hi, sz[u]);
	for (int u: ch[at]) if (u != par[0][at])
	{
		if (sz[u] == hi)
		{
			hi = -1;
			dfs2(u, _h);
		} else
			dfs2(u, u);
	}
}

int lca(int a, int b)
{
	if (dep[a] > dep[b]) swap(a, b);
	for (int i = 19;i >= 0;i--) if (dep[b]-(1<<i) >= dep[a])
		b = par[i][b];
	if (a == b) return a;
	for (int i = 19;i >= 0;i--) if (par[i][a] != par[i][b])
		a = par[i][a], b = par[i][b];
	return par[0][a];
}

void add(int a, int b, int v)
{
	if (a == b) return;
	if (head[a] == head[b])
	{
		tr[head[a]]->add(dep[a]-dep[head[a]]+1, dep[b]-dep[head[b]]+1, v);
	} else
	{
		tr[head[b]]->add(0, dep[b]-dep[head[b]]+1, v);
		add(a, par[0][head[b]], v);
	}
}

void destroy_requirement(int a, int b, int v)
{
	if (a == b) return;
	if (head[a] == head[b])
	{
		pq.erase(make_pair(tr[head[a]]->va, head[a]));
		tr[head[a]]->del(dep[a]-dep[head[a]]+1, dep[b]-dep[head[b]]+1, v);
		pq.emplace(tr[head[a]]->va, head[a]);
	} else
	{
		pq.erase(make_pair(tr[head[b]]->va, head[b]));
		tr[head[b]]->del(0, dep[b]-dep[head[b]]+1, v);
		pq.emplace(tr[head[b]]->va, head[b]);
		destroy_requirement(a, par[0][head[b]], v);
	}
}

void destroy_requirement(int e_id)
{
	int g = lca(A[e_id], B[e_id]);
	destroy_requirement(g, A[e_id], e_id);
	destroy_requirement(g, B[e_id], e_id);
}

void foo(int h)
{
	int who = -1;
	node *at = tr[h];
	while (at->lo+1 < at->hi)
	{
		if (at->all.size()) who = *at->all.begin();
		if (at->r == NULL) at = at->l;
		else if (at->l == NULL) at = at->r;
		else if (at->l->va < at->r->va) at = at->l;
		else at = at->r;
	}
	if (at->all.size()) who = *at->all.begin();
	destroy_requirement(who);
	pq.erase(make_pair(tr[h]->va, h));
	tr[h]->destroy(at->lo);
	pq.emplace(tr[h]->va, h);
}

int main()
{
	scanf("%d", &n);
	for (int i = 1;i < n;i++)
	{
		int a, b; scanf("%d%d", &a, &b);
		--a, --b;
		ch[a].push_back(b);
		ch[b].push_back(a);
	}
	par[0][0] = -1; dfs1(0);
	for (int i = 0;i < n;i++) head[i] = -1;
	dfs2(0, 0);
	for (int j = 1;j < 20;j++) for (int i = 0;i < n;i++) par[j][i] = (par[j-1][i]!=-1)?par[j-1][par[j-1][i]]:-1;
	for (int i = 1;i < n;i++)
	{
		scanf("%d%d", A+i, B+i);
		--A[i], --B[i];
		int g = lca(A[i], B[i]);
		add(g, A[i], i);
		add(g, B[i], i);
	}
	for (int i = 0;i < n;i++) if (i == head[i]) pq.emplace(tr[i]->va, i);
	int done = 0;
	while (done < n-1)
	{
		auto u = *pq.begin();
		if (u.first != 1)
		{
			printf("NO\n");
			return 0;
		}
		foo(u.second);
		done++;
	}
	if (done == n-1) printf("YES\n");
	else printf("NO\n");
	return 0;
}


Measured memory_bytes: 165376