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++ (GCC 5.4.1) (judge verdict: Time Limit Exceeded)

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 1;
typedef pair<int,int> pii;
set<int> B[MAXN] , R[MAXN];
map<pii,int> Bm , Rm;
int n , f[MAXN] , he , ta;
pii que[MAXN << 4];
int find( const int & x ) { return x == f[x] ? x : f[x] = find( f[x] ); }
pii get( int u , int v ) { if( u > v ) swap( u , v ); return make_pair( u , v ); }
int main( void ) {
  scanf("%d",&n) , he = 1 , ta = 0;
  for( int i = 1 ; i <= n ; ++i ) f[i] = i;
  for( int i = 1 , u , v ; i < n ; ++i ) {
    scanf( "%d%d" , &u , &v );
    B[u].insert( v ) , B[v].insert( u );
    Bm[get( u , v )] = 1;
  }
  for( int i = 1 , u , v ; i < n ; ++i ) {
    scanf( "%d%d" , &u , &v );
    R[u].insert( v ) , R[v].insert( u );
    Rm[get( u , v )] = 1;
    if( Bm[get( u , v )] ) que[++ta] = pii( u , v );
  }
  int u , v , cnt = 0;
  while( he <= ta ) {
    u = que[he].first , v = que[he].second; ++he;
    if( ( u = find( u ) ) == ( v = find( v ) ) ) continue;
    ++cnt;
    if( B[u].size() + R[u].size() < B[v].size() + R[v].size() ) swap( u , v );
    B[u].erase( v ) , B[v].erase( u );
    for( int pt : B[v] ) {
      B[u].insert( pt );
      Bm[get( v , pt )] = 0 , Bm[get( u , pt )] = 1;
      if( Rm[get( u , pt )] ) que[++ta] = pii( u , pt );
      B[u].insert( pt ) , B[pt].insert( u ) , B[pt].erase( v );
    }
    R[u].erase( v ) , R[v].erase( u );
    for( int pt : R[v] ) {
      R[u].insert( pt );
      Rm[get( v , pt )] = 0 , Rm[get( u , pt )] = 1;
      if( Bm[get( u , pt )] ) que[++ta] = pii( u , pt );
      R[u].insert( pt ) , R[pt].insert( u ) , R[pt].erase( v );
    }
    f[v] = u;
  }
  puts( cnt == n - 1 ? "YES" : "NO" );
  return 0;
}