#include<bits/stdc++.h>
#define reg register
#define maxn 240007
#define inf 1000000007
using namespace std;
inline int read(){
    reg int s = 0, t = 0; reg char ch = getchar();
    while(ch > '9' || ch < '0') t |= ch == '-', ch = getchar();
    while(ch >= '0' && ch <= '9') s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();
    return t ? -s : s;
}
struct node{int x, y;} a[maxn];
int  n, nt[maxn << 1], fi[maxn], go[maxn << 1], top[maxn], dep[maxn], p, f[maxn], minn_id[maxn << 2], cnt;
int dfn[maxn], id[maxn], son[maxn], siz[maxn], tag[maxn << 2], minn[maxn << 2], sum_xor[maxn << 2]; 
void add(int u, int v){
    nt[++cnt] = fi[u]; fi[u] = cnt; go[cnt] = v;
}
void dfs_1(int u, int fa){
    dep[u] = dep[fa] + 1; siz[u] = 1; f[u] = fa;
    for(int i = fi[u]; i; i = nt[i]){
        int v = go[i]; if(v == fa) continue;
        dfs_1(v, u); siz[u] += siz[v]; 
        if(siz[v] > siz[son[u]]) son[u] = v;
    }
}
void dfs_2(int u, int top_fa){
    top[u] = top_fa;  dfn[u] = ++cnt;  id[cnt] = u;
    if(!son[u]) return; dfs_2(son[u], top_fa); 
    for(int i = fi[u]; i; i = nt[i]){
        int v = go[i]; 
        if(v == f[u] || v == son[u]) continue;
        dfs_2(v, v);
    }
}
void pushdown(int k, int len){
    tag[k << 1] += tag[k]; tag[k << 1 | 1] += tag[k];
    minn[k << 1] += tag[k]; minn[k << 1 | 1] += tag[k]; tag[k] = 0;
}
void update(int k, int l, int r, int L, int R, int opt, int x_id){
    if(L <= l && r <= R){
        minn[k] += opt; tag[k] += opt;
        sum_xor[k] ^= x_id;
        return; 
    }
    int mid = l + r >> 1;
    if(tag[k] != 0) pushdown(k, r - l + 1);
    if(L <= mid) update(k << 1, l, mid, L, R, opt, x_id);
    if(R > mid) update(k << 1 | 1, mid + 1, r, L, R, opt, x_id);
    minn[k] = min(minn[k << 1], minn[k << 1 | 1]);
    if(minn[k] == minn[k << 1]) minn_id[k] = minn_id[k << 1];
    else minn_id[k] = minn_id[k << 1 | 1]; 
    int pp = 0; 
}
void update_range(int x, int y, int opt, int x_id){
    while(top[x] != top[y]){
        if(dep[top[x]] < dep[top[y]]) swap(x, y);
        update(1, 1, n, dfn[top[x]], dfn[x], opt, x_id);
        x = f[top[x]];
    }
    if(dep[x] > dep[y]) swap(x, y);
    if(x != y) update(1, 1, n, dfn[x] + 1, dfn[y], opt, x_id);
}
void query_xor(int k, int l, int r, int pos){
    int mid = l + r >> 1;
    p ^= sum_xor[k];
    if(l == r) {
        minn[k] = 1e9; return;
    }
    if(tag[k]) pushdown(k, r - l + 1);
    if(pos <= mid)  query_xor(k << 1, l, mid, pos);
    else query_xor(k << 1 | 1, mid + 1, r, pos);
    minn[k] = min(minn[k << 1], minn[k << 1 | 1]);   
    if(minn[k] == minn[k << 1]) minn_id[k] = minn_id[k << 1];
    else minn_id[k] = minn_id[k << 1 | 1]; 
}
bool cmp(node g, node h){
    if(g.y != h.y) return dfn[g.y] < dfn[h.y];
    return dfn[g.x] < dfn[h.x];  
}
void build(int k, int l, int r){
    int mid = l + r >> 1;
    if(l == r) {minn[k] = (l == 1) ? inf : 0; minn_id[k] = id[l]; return; } 
    build(k << 1, l, mid); build(k << 1 | 1, mid + 1, r);  
    minn_id[k] = minn_id[k << 1 | 1];
    minn[k] = min(minn[k << 1], minn[k << 1 | 1]);
}
int main()
{
    n = read(); 
    for(int i = 1; i < n; i++){
        int x = read(), y = read();
        add(x, y); add(y, x);
    }
    cnt = 0; dfs_1(1, 0); dfs_2(1, 1);
    build(1, 1, n);
    for(int i = 1; i < n; i++){
        a[i].x = read(), a[i].y = read();
        update_range(a[i].x, a[i].y, 1, i);
    }
    int t = n - 1;
    while(t--){
        if(minn[1] != 1) {cout << "NO\n"; return 0;}
        int x = minn_id[1]; p = 0;
        query_xor(1, 1, n, dfn[x]);
        update_range(a[p].x, a[p].y, -1, p); 
    }
    cout << "YES\n";
}

Measured memory_bytes: 28416