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: Runtime Error)

//by yjz
#include<bits/stdc++.h>
using namespace std;
#define FF first
#define SS second
#define PB push_back
#define MP make_pair
typedef long long ll;
const int Imx=2147483647;
const int mod=1000000007;
const ll Lbg=2e18;
//My own input/output stream
#define geti(x) x=getnum()
#define getii(x,y) geti(x),geti(y)
#define getiii(x,y,z) getii(x,y),geti(z)
#define puti(x) putnum(x),putsp()
#define putii(x,y) puti(x),putnum(y),putsp()
#define putiii(x,y,z) putii(x,y),putnum(z),putsp()
#define putsi(x) putnum(x),putendl()
#define putsii(x,y) puti(x),putnum(y),putendl()
#define putsiii(x,y,z) putii(x,y),putnum(z),putendl()
inline ll getnum()
{
	register ll r=0;register bool ng=0;register char c;c=getchar();
	while(c!='-'&&(c<'0'||c>'9'))c=getchar();
	if(c=='-')ng=1,c=getchar();
	while(c>='0'&&c<='9')r=r*10+c-'0',c=getchar();
	if(ng)r=-r;return r;
}
template <class T> inline void putnum(T x)
{
	if(x<0)putchar('-'),x=-x;
	register short a[20]={},sz=0;
	while(x>0)a[sz++]=x%10,x/=10;
	if(sz==0)putchar('0');
	for(int i=sz-1;i>=0;i--)putchar('0'+a[i]);
}
inline void putsp(){putchar(' ');}
inline void putendl(){putchar('\n');}
inline char mygetchar(){register char c=getchar();while(c==' '||c=='\n')c=getchar();return c;}
int n,f[100111],sz[100111];
int gf(int x){return f[x]==x?x:f[x]=gf(f[x]);}
vector<int>con[100111],con2[100111];
bool hs[100111];
const int magic=5000000;
void un(int x,int y)
{
	x=gf(x);
	y=gf(y);
	f[x]=y;
	sz[y]+=sz[x];
}
bool redo[100111];
int tmp[100111],tmpsz;
void dfs(int x,int p=-1)
{
	for(int i=0;i<con2[x].size();i++)hs[gf(con2[x][i])]=1,tmp[tmpsz++]=gf(con2[x][i]);
	for(int i=0;i<con[x].size();i++)
	{
		if(con[x][i]==p)continue;
		if(gf(x)==gf(con[x][i]))
		{
			dfs(con[x][i],x);
		}
		else if(hs[gf(con[x][i])])
		{
			if(sz[gf(con[x][i])]>magic)
			{
				redo[gf(con[x][i])]=1;
			}
			else
			{
				un(con[x][i],x);
				dfs(con[x][i],x);
			}
		}
	}
}
void dfs2(int x,int p=-1)
{
	for(int i=0;i<con2[x].size();i++)hs[gf(con2[x][i])]=1,tmp[tmpsz++]=gf(con2[x][i]);
	for(int i=0;i<con[x].size();i++)
	{
		if(con[x][i]==p)continue;
		if(gf(x)==gf(con[x][i]))
		{
			dfs2(con[x][i],x);
		}
		else if(hs[gf(con[x][i])])
		{
			{
				un(con[x][i],x);
				dfs2(con[x][i],x);
			}
		}
	}
	for(int i=0;i<con2[x].size();i++)hs[gf(con2[x][i])]=0;
}

void add(int x)
{
	dfs(x);
	for(int i=0;i<tmpsz;i++)hs[tmp[i]]=0;
}
void add2(int x)
{
	dfs2(x);
	for(int i=0;i<tmpsz;i++)hs[tmp[i]]=0;
}
int main()
{
	geti(n);
	for(int i=1;i<=n;i++)f[i]=i,sz[i]=1;
	for(int i=1;i<n;i++)
	{
		int x,y;
		getii(x,y);
		con[x].PB(y);
		con[y].PB(x);
	}
	for(int i=1;i<n;i++)
	{
		int x,y;
		getii(x,y);
		con2[x].PB(y);
		con2[y].PB(x);
	}
	for(int i=1;i<=n;i++)
	{
		add(i);
	}
	for(int i=1;i<=n;i++)
	{
		if(redo[i])
		{
			dfs2(i,-1);
		}
	}
	if(sz[gf(1)]==n)puts("YES");else puts("NO");
	return 0;
}