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: Time Limit Exceeded)

#include <bits/stdc++.h>

#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define REP(i,a) FOR(i,0,a)

using namespace std;
typedef pair<int,bool> P;

const int MAX_N=1e5;

set<P> G[MAX_N];

int main(){
	int N;
	scanf("%d",&N);
	REP(i,N-1){
		int a,b;
		scanf("%d %d",&a,&b);
		a--;
		b--;
		G[a].insert(P(b,false));
		G[b].insert(P(a,false));
	}
	REP(i,N-1){
		int a,b;
		scanf("%d %d",&a,&b);
		a--;
		b--;
		G[a].insert(P(b,true));
		G[b].insert(P(a,true));
	}
	int c=0;
	REP(i,N){
		int v=i,v2;
		while(1){
			v2=-1;
			for(auto ite=G[v].begin();ite!=G[v].end();){
				auto ite2=ite;
				ite2++;
				if (ite2==G[v].end()) break;
				if (ite->first==ite2->first){
					v2=ite->first;
					if (G[v].size()<G[v2].size()){
						swap(v,v2);
					}
					break;
				}
				ite++;
				if (ite->second){
					ite++;
				}
			}
			if (v2!=-1){
				c++;
				G[v].erase(P(v2,false));
				G[v].erase(P(v2,true));
				G[v2].erase(P(v,false));
				G[v2].erase(P(v,true));
				for(auto ite2=G[v2].begin();ite2!=G[v2].end();){
					G[ite2->first].erase(P(v2,ite2->second));
					G[ite2->first].insert(P(v,ite2->second));
					G[v].insert(*ite2);
					ite2=G[v2].erase(ite2);
				}
			}else{
				break;
			}
		}
	}
	if (c==N-1){
		printf("YES\n");
	}else{
		printf("NO\n");
	}
	return 0;
}