#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll inf = 1e18;

ll n, chi[100005], par[20][100005], dep[100005];
ll head[100005], ord[100005], cc;
vector<ll> adj[100005];
vector<pair<ll,ll> > edg;

struct data {
	ll a, b, i;
	data () {a=0; b=0; i=0;}
	data (ll A, ll B, ll I) {a = A; b = B; i = I;}
	data operator + (data &D) {
		data ret;
		ret.a = a + D.a;
		ret.b = b + D.b;
		ret.i = i + D.i;
		return ret;
	}
	bool operator < (const data &D) const {
		if(a != D.a) return a < D.a;
		if(b != D.b) return b < D.b;
		return i < D.i;
	}
};

struct segtree {
	data val[444444], lazy[444444];
	void init (ll SS, ll SE, ll P) {
		if(SS == SE) {
			val[P].i = SS;
			return;
		}
		ll mid = (SS+SE)/2;
		init(SS, mid, 2*P);
		init(mid+1, SE, 2*P+1);
		val[P] = min(val[2*P], val[2*P+1]);
	}
	void lazydown (ll P) {
		val[2*P] = val[2*P] + lazy[P];
		lazy[2*P] = lazy[2*P] + lazy[P];
		val[2*P+1] = val[2*P+1] + lazy[P];
		lazy[2*P+1] = lazy[2*P+1] + lazy[P];
		lazy[P] = data(0, 0, 0);
	}
	void update (ll SS, ll SE, ll S, ll E, ll P, data X) {
		if(S <= SS && SE <= E) {
			val[P] = val[P] + X;
			lazy[P] = lazy[P] + X;
			return;
		}
		if(SE < S || E < SS) return;
		lazydown(P);
		ll mid = (SS+SE)/2;
		update(SS, mid, S, E, 2*P, X);
		update(mid+1, SE, S, E, 2*P+1, X);
		val[P] = min(val[2*P], val[2*P+1]);
	}
	void update (ll S, ll E, data X) {
		update(2, n, S, E, 1, X);
	}
} seg;

void calc (ll cur, ll prv) {
	chi[cur] = 1;
	dep[cur] = dep[prv] + 1;
	par[0][cur] = prv;
	for(auto &nxt : adj[cur]) {
		if(prv == nxt) continue;
		calc(nxt, cur);
		chi[cur] += chi[nxt];
	}
}

bool comp (ll A, ll B) {
	return chi[A] > chi[B];
}

void numb (ll cur, ll prv, ll hd) {
	head[cur] = hd;
	ord[cur] = ++cc;
	sort(adj[cur].begin(), adj[cur].end(), comp);
	bool flag = false;
	for(auto &nxt : adj[cur]) {
		if(prv == nxt) continue;
		if(!flag) {
			numb(nxt, cur, hd);
			flag = true;
		}
		else numb(nxt, cur, nxt);
	}
}

ll getlca (ll A, ll B) {
	if(dep[A] < dep[B]) swap(A, B);
	for(int i=20;i--;) {
		if(dep[A] - dep[B] >= (1<<i)) {
			A = par[i][A];
		}
	}
	if(A == B) return A;
	for(int i=20;i--;) {
		if(par[i][A] != par[i][B]) {
			A = par[i][A];
			B = par[i][B];
		}
	}
	return par[0][A];
}

void update (ll A, ll B, ll X, ll Y) {
	data upd = data(X, Y, 0);
	while(dep[A] > dep[B]) {
		if(dep[head[A]] <= dep[B]) {
			seg.update(ord[B]+1, ord[A], upd);
			break;
		}
		else {
			seg.update(ord[head[A]], ord[A], upd);
			A = par[0][head[A]];
		}
	}
}

int main()
{
	scanf("%lld",&n);
	for(int i=1;i<n;i++) {
		ll A, B;
		scanf("%lld%lld",&A,&B);
		adj[A].push_back(B);
		adj[B].push_back(A);
	}
	calc(1, 0);
	numb(1, 0, 1);
	seg.init(2, n, 1);
	for(int k=1;k<20;k++) {
		for(int i=1;i<=n;i++) {
			par[k][i] = par[k-1][par[k-1][i]];
		}
	}
	for(int i=0;i<n-1;i++) {
		ll A, B;
		scanf("%lld%lld",&A,&B);
		edg.push_back({A, B});
		ll lca = getlca(A, B);
		update(A, lca, 1, i);
		update(B, lca, 1, i);
	}
	for(int i=0;i<n-1;i++) {
		if(seg.val[1].a != 1) {puts("NO"); return 0;}
		ll I = seg.val[1].b;
		seg.update(seg.val[1].i, seg.val[1].i, {inf, 0, 0});
		ll A = edg[I].first, B = edg[I].second;
		ll lca = getlca(A, B);
		update(A, lca, -1, -I);
		update(B, lca, -1, -I);
	}
	puts("YES");
}


Measured memory_bytes: 54516