#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> P;
template<typename T> inline void chkmin(T &a, const T &b) { a = a < b ? a : b; }
template<typename T> inline void chkmax(T &a, const T &b) { a = a > b ? a : b; }

const int MAXN = 100005, MAXT = 1 << 18;
vector<int> gra[MAXN];
int wson[MAXN], siz[MAXN], dfn[MAXN], dep[MAXN], par[MAXN], n, tot;
int top[MAXN], val[MAXN], cnt[MAXN], fr[MAXN], to[MAXN];

namespace ST {
	int mn[MAXT], sum[MAXT], tag[MAXT], tn;
	
	void build() {
		for (tn = 1; tn < n; tn <<= 1);
		memset(mn, 0x3f, sizeof(mn));
		for (int i = 1; i <= n; i++) mn[dfn[i] + tn - 1] = cnt[i];
		for (int i = tn - 1; i > 0; i--)
			mn[i] = min(mn[i << 1], mn[i << 1 | 1]);
	}
	
	inline void push_down(int k) {
		if (!tag[k]) return;
		int &t = tag[k];
		mn[k << 1] += t, mn[k << 1 | 1] += t;
		tag[k << 1] += t, tag[k << 1 | 1] += t, t = 0;
	}
	
	void sub(int a, int b, int l = 1, int r = tn, int k = 1) {
		if (a > r || b < l) return;
		if (a <= l && b >= r) { --tag[k], --mn[k]; return; }
		push_down(k);
		int mid = (l + r) >> 1;
		sub(a, b, l, mid, k << 1);
		sub(a, b, mid + 1, r, k << 1 | 1);
		mn[k] = min(mn[k << 1], mn[k << 1 | 1]);
	}
	
	void refresh(int l = 1, int r = tn, int k = 1) {
		if (l == r) { mn[k] = 1e9; return; }
		int mid = (l + r) >> 1;
		push_down(k);
		if (!mn[k << 1]) refresh(l, mid, k << 1);
		if (!mn[k << 1 | 1]) refresh(mid + 1, r, k << 1 | 1);
		mn[k] = min(mn[k << 1], mn[k << 1 | 1]);
	}
	
	int query(int l = 1, int r = tn, int k = 1) {
		if (l == r) return l;
		int mid = (l + r) >> 1;
		push_down(k);
		if (mn[k << 1] == 1) return query(l, mid, k << 1);
		if (mn[k << 1 | 1] == 1) return query(mid + 1, r, k << 1 | 1);
		assert(false);
		return -1;
	}
	
	void add(int p, int x) {
		for (; p <= n; p += p & -p) sum[p] ^= x;
	}
	
	int ask(int p) {
		int res = 0;
		for (; p; p -= p & -p) res ^= sum[p];
		return res;
	}
}

void dfs1(int u, int fa) {
	par[u] = fa, siz[u] = 1;
	for (int v : gra[u]) if (v != fa) {
		dep[v] = dep[u] + 1;
		dfs1(v, u);
		siz[u] += siz[v];
		if (siz[v] > siz[wson[u]]) wson[u] = v;
	}
}

void dfs2(int u, int fa, int t) {
	dfn[u] = ++tot, top[u] = t;
	if (wson[u]) dfs2(wson[u], u, t);
	for (int v : gra[u])
		if (v != fa && v != wson[u]) dfs2(v, u, v);
}

int get_lca(int u, int v) {
	while (top[u] != top[v]) {
		if (dep[top[u]] > dep[top[v]]) swap(u, v);
		v = par[top[v]];
	}
	return dep[u] > dep[v] ? v : u;
}

void dfs3(int u, int fa) {
	for (int v : gra[u]) if (v != fa) {
		dfs3(v, u);
		cnt[u] += cnt[v];
		val[u] ^= val[v];
	}
	ST::add(dfn[u], val[u]);
	ST::add(dfn[u] + 1, val[u]);
}

void modify(int u, int v, int id) {
	for (int tu = top[u]; tu != top[v]; u = par[tu], tu = top[u]) {
		ST::sub(dfn[tu], dfn[u]);
		ST::add(dfn[tu], id);
		ST::add(dfn[u] + 1, id);
	}
	if (u != v) {
		ST::sub(dfn[v] + 1, dfn[u]);
		ST::add(dfn[v] + 1, id);
		ST::add(dfn[u] + 1, id);
	}
}

int main() {
	scanf("%d", &n);
	for (int i = 1; i < n; i++) {
		int u, v; scanf("%d%d", &u, &v);
		gra[u].push_back(v), gra[v].push_back(u);
	}
	dfs1(1, 0);
	dfs2(1, 0, 1);
	for (int i = 1; i < n; i++) {
		int u, v; scanf("%d%d", &u, &v);
		int l = get_lca(u, v);
		val[u] ^= i, val[v] ^= i;
		++cnt[u], ++cnt[v], cnt[l] -= 2;
		fr[i] = u, to[i] = v;
	}
	cnt[1] = 1e9;
	dfs3(1, 0);
	ST::build();
	for (int i = 1; i < n; i++) {
		if (ST::mn[1] > 1) return puts("NO"), 0;
		int p = ST::query();
		p = ST::ask(p);
		int l = get_lca(fr[p], to[p]);
		modify(fr[p], l, p);
		modify(to[p], l, p);
		ST::refresh();
	}
	puts("YES");
	return 0;
}

Measured memory_bytes: 18944