#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> II;

const int N = (int) 1e5 + 10;
const int INF = 0x3f3f3f3f;
int n, red[N][2];
vector<int> adj[N];

int h[N], c[N], p[N][21];
int chain[N], head[N], nChain;
int pos[N], nPos;

void DFS(int u) {
    c[u] = 1;
    for (int i = 1; i <= 20; ++i) p[u][i] = p[p[u][i - 1]][i - 1];
    for (int i = 0; i < (int) adj[u].size(); ++i) {
        int v = adj[u][i];
        if (v != p[u][0]) {
            h[v] = h[u] + 1;
            p[v][0] = u;
            DFS(v);
            c[u] += c[v];
        }
    }
}

void HLD(int u) {
    if (head[nChain] == 0) head[nChain] = u;
    chain[u] = nChain;
    pos[u] = ++nPos;
    int heavy = -1;
    for (int i = 0; i < (int) adj[u].size(); ++i) {
        int v = adj[u][i]; if (v == p[u][0]) continue;
        if (heavy == -1 || c[heavy] < c[v]) heavy = v;
    }
    if (heavy != -1) HLD(heavy);
    for (int i = 0; i < (int) adj[u].size(); ++i) {
        int v = adj[u][i]; if (v == p[u][0]) continue;
        if (v != heavy) {
            nChain++;
            HLD(v);
        }
    }
}

int LCA(int u, int v) {
    if (h[u] < h[v]) swap(u, v);
    for (int i = 20; i >= 0; --i) if (h[u] - (1 << i) >= h[v]) u = p[u][i];
    if (u == v) return u;
    for (int i = 20; i >= 0; --i) if (p[u][i] != p[v][i]) {
        u = p[u][i];
        v = p[v][i];
    }
    return p[u][0];
}

#define m ((l + r) >> 1)
struct Node {
    int Min, Lazy;
    set<int> Set;
};
struct SegTree {
    Node S[N * 5];
    void Propagate(int k) {
        int v = S[k].Lazy; S[k].Lazy = 0;
        S[k << 1 | 0].Min += v; S[k << 1 | 0].Lazy += v;
        S[k << 1 | 1].Min += v; S[k << 1 | 1].Lazy += v;
    }
    void Assign(int k, int l, int r, int i, int v) {
        if (l == r) {
            S[k].Min = v;
            return;
        }
        Propagate(k);
        if (i <= m) Assign(k << 1, l, m, i, v);
        else Assign(k << 1 | 1, m + 1, r, i, v);
        S[k].Min = min(S[k << 1].Min, S[k << 1 | 1].Min);
    }
    void Update(int k, int l, int r, int i, int j, int v) {
        if (l > j || r < i) return;
        if (i <= l && r <= j) {
            if (v > 0) {
                S[k].Set.insert(v);
                S[k].Min += 1;
                S[k].Lazy += 1;
            }
            else {
                S[k].Set.erase(-v);
                S[k].Min -= 1;
                S[k].Lazy -= 1;
            }
            return;
        }
        Propagate(k);
        Update(k << 1 | 0, l, m, i, j, v);
        Update(k << 1 | 1, m + 1, r, i, j, v);
        S[k].Min = min(S[k << 1].Min, S[k << 1 | 1].Min);
    }
    int MinElement(int k, int l, int r) {
        if (l == r) return l;
        Propagate(k);
        if (S[k << 1].Min == S[k].Min) return MinElement(k << 1, l, m);
        return MinElement(k << 1 | 1, m + 1, r);
    }
    int Find(int k, int l, int r, int i) {
        if (S[k].Set.size()) return *S[k].Set.begin();
        if (i <= m) return Find(k << 1, l, m, i);
        return Find(k << 1 | 1, m + 1, r, i);
    }
} ST;
#undef m

void UpdatePath(int w, int u, int i) {
    while (1) {
        if (chain[u] == chain[w]) {
            if (u != w) ST.Update(1, 1, n, pos[w] + 1, pos[u], i);
            break;
        }
        int t = head[chain[u]];
        ST.Update(1, 1, n, pos[t], pos[u], i);
        u = p[t][0];
    }
}

void UpdateRed(int u, int v, int i) {
    int w = LCA(u, v);
    UpdatePath(w, u, i);
    UpdatePath(w, v, i);
}

int main() {
#ifdef LOCAL
    freopen("inp", "r", stdin);
    freopen("out", "w", stdout);
#endif
    scanf("%d", &n);
    for (int i = 1; i <= n - 1; ++i) {
        int u, v; scanf("%d%d", &u, &v);
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    for (int i = 1; i <= n - 1; ++i) scanf("%d%d", &red[i][0], &red[i][1]);

    DFS(1);
    HLD(1);
    ST.Assign(1, 1, n, pos[1], INF);
    for (int i = 1; i <= n - 1; ++i) {
        UpdateRed(red[i][0], red[i][1], i);
    }

    for (int i = 1; i <= n - 1; ++i) {
        if (ST.S[1].Min != 1) {
            puts("NO");
            return 0;
        }
        int u = ST.MinElement(1, 1, n);
        int x = ST.Find(1, 1, n, u);
        UpdateRed(red[x][0], red[x][1], -x);
        ST.Assign(1, 1, n, u, INF);
    }
    puts("YES");
    return 0;
}


Measured memory_bytes: 148608