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: Wrong Answer)

#include <iostream>
#include <vector>
#include <map>
#include <queue>
#include <set>
using namespace std;
int N;
vector <int> G[100005], G2[100005];
map <int, int> M[100005];
bool Use[100005], InQ[100005];
multiset <int> S[100005];
queue <pair <int, int> > Q;
int TT[100005];
int Father(int x)
{
    int init = x;
    while(TT[x] != x)
    {
        x = TT[x];
    }
    while(init != x)
    {
        int next = TT[init];
        TT[init] = x;
        init = next;
    }
    return x;
}

void Unite(int x, int y)
{
        TT[y] = x;
}
void Read()
{
    cin >> N;
    for(int i = 1; i < N; i++)
    {
        int x, y;
        cin >> x >> y;
        TT[i] = i;
        G[x].push_back(y);
        G[y].push_back(x);
        M[x][y]++;
        M[y][x]++;
        S[x].insert(y);
        S[y].insert(x);
    }
    TT[N] = N;
    for(int i = 1; i < N; i++)
    {
        int x, y;
        cin >> x >> y;
        S[x].insert(y);
        S[y].insert(x);
        M[x][y]++;
        M[y][x]++;
        if(M[x][y] == 2)
            Q.push(make_pair(x, y));
    }
}

void Solve()
{
    int cnt = 0;
    while(!Q.empty() && cnt < N - 1)
    {

        pair <int, int> p = Q.front();
        Q.pop();
        int x = p.first, y = p.second;
        x = Father(x);
        y = Father(y);
        if(x == y)
        {
            continue;
        }
        ++cnt;
        M[x][y] -= 2;
        M[y][x] -= 2;
        if(M[x][y] >= 2)
            Q.push(make_pair(x, y));
        if(S[x].size() < S[y].size())
            swap(x, y);
        for(auto it = S[y].begin(); it != S[y].end(); it = next(it))
        {

            int neighb = *it;
            if(neighb == x)
                continue;
            auto it2 = S[neighb].find(y);
            if(it2 != S[neighb].end())
                S[neighb].erase(it2);
            S[neighb].insert(x);
            M[y].erase(neighb);
            M[neighb].erase(y);
            M[x][neighb]++;
            M[neighb][x]++;
            if(M[x][neighb] == 2)
                Q.push(make_pair(x, neighb));
        }
        S[y].clear();
        Unite(x, y);
    }
    if(cnt == N - 1)
        cout << "YES\n";
    else
        cout << "NO\n";
}
int main()
{
    Read();
    Solve();
    return 0;
}