Problem:
Score : 1400 points

Problem Statement

There is a tree with N vertices numbered 1 through N.
The i-th of the N-1 edges connects vertices a_i and b_i.

Initially, each edge is painted blue.
Takahashi will convert this blue tree into a red tree, by performing the following operation N-1 times:

Select a simple path that consists of only blue edges, and remove one of those edges.

Then, span a new red edge between the two endpoints of the selected path.

His objective is to obtain a tree that has a red edge connecting vertices c_i and d_i, for each i.

Determine whether this is achievable.

Constraints

2 ≤ N ≤ 10^5

1 ≤ a_i,b_i,c_i,d_i ≤ N

a_i ≠ b_i

c_i ≠ d_i

Both input graphs are trees.

Input

Input is given from Standard Input in the following format:

N
a_1 b_1
:
a_{N-1} b_{N-1}
c_1 d_1
:
c_{N-1} d_{N-1}

Output

Print YES if the objective is achievable; print NO otherwise.

Sample Input 1

3
1 2
2 3
1 3
3 2

Sample Output 1

YES

The objective is achievable, as below:

First, select the path connecting vertices 1 and 3, and remove a blue edge 1-2. Then, span a new red edge 1-3.

Next, select the path connecting vertices 2 and 3, and remove a blue edge 2-3. Then, span a new red edge 2-3.

Sample Input 2

5
1 2
2 3
3 4
4 5
3 4
2 4
1 4
1 5

Sample Output 2

YES

Sample Input 3

6
1 2
3 5
4 6
1 6
5 1
5 3
1 4
2 6
4 3
5 6

Sample Output 3

NO

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
#define Rep(i,a,b) for(register int i=(a);i<=int(b);++i)
#define Dep(i,a,b) for(register int i=(a);i>=int(b);--i)
#define rep(i,a,b) for(register int i=(a);i<int(b);++i)
#define mem(x,v) memset(x,v,sizeof(x))
#define gc getchar
#define pc putchar
#define fi first
#define queue QQQ
#define se second
#define debug(x) cout << #x" = " << x << endl;
#define pp(x,y) cout << "pp: " << x << " " << y << endl;
#define rank __RAnK
inline ll read(){
	register ll x=0,f=1;register char c=gc();
	for(;!isdigit(c);c=gc())if(c=='-')f=-1;
	for(;isdigit(c);c=gc())x=(x<<1)+(x<<3)+(c^48);
	return x*f;
}
#define rd read
void write(ll x){if(x<0)x=-x,pc('-');if(x>=10)write(x/10);putchar(x%10+'0');}
void writeln(ll x){write(x);puts("");}
const int maxn = 100005;
multiset<int> s[maxn];
map<pii,int> mp;
pii q[maxn*2];
int front,rear,fa[maxn],n;
inline int find(int x){
	return fa[x] == x?x : fa[x] = find(fa[x]);
}
int main(){
	n = rd();
	Rep(i,1,n) fa[i] = i;
	front = rear = 0;
	Rep(i,1,2*n-2){
		int x,y;
		x = rd(),y = rd();
		s[x] . insert(y);
		s[y] . insert(x);
		mp[make_pair(x,y)]++;
		mp[make_pair(y,x)]++;
		if(mp[make_pair(x,y)]==2) q[rear++] = make_pair(x,y);
	}
	multiset<int>::iterator it;
	while(front < rear){
		int x = q[front].fi,y = q[front].se;front++;
		x = find(x),y = find(y);
		if(x==y) continue;
		s[x] . erase(y);
		s[y] . erase(x);
		if(s[x] . size() < s[y] . size()) swap(x,y);
		for(it = s[y].begin();it != s[y].end();it++){
			int i=*it;
			s[i].erase(y);
			s[i].insert(x);
			++mp[pii(i,x)];
			++mp[pii(x,i)];
			if(mp[pii(x,i)] == 2) q[rear++] = pii(x,i);
			s[x] . insert(i);
		}
		fa[y] = x;
		s[y].clear();
	}
	Rep(i,1,n) if(find(i) != find(1)){
		puts("NO");
		return 0;
	}
	puts("YES");
	return 0;
}