#include <cstdio>
#include <vector>

#define INF 1000000000

#define MAXN 100000

int h[MAXN + 1], s[MAXN + 1], fiuMare[MAXN + 1], unde[MAXN + 1];
int t[MAXN + 1], hMare[MAXN + 1], sef[MAXN + 1], zop[MAXN + 1];
std::vector < int > g[MAXN + 1];

int d[MAXN], heap[MAXN], lung[MAXN], a[MAXN], b[MAXN], hop[MAXN];

struct node {
    int best, lazy, poz, val;
} *aint[MAXN];

int m, q, poz, val, add, left, right;

inline void mySwap(int p, int q) {
    int aux = heap[p];
    heap[p] = heap[q];
    heap[q] = aux;
    hop[heap[p]] = p;
    hop[heap[q]] = q;
}

inline void urcare(int p) {
    while (p > 1 && d[heap[p]] < d[heap[p / 2]]) {
        mySwap(p, p / 2);
        p = p / 2;
    }
}

inline void coborare(int p) {
    int q;
    bool f = 1;
    while (f && (q = 2 * p) <= m) {
        if (q < m && d[heap[2 * p + 1]] <= d[heap[q]])
            q = 2 * p + 1;
        if (d[heap[q]] < d[heap[p]]) {
            mySwap(p, q);
            p = q;
        } else
            f = 0;
    }
}

inline void propag(node &n, node &a, node &b) {
    if (n.lazy) {
        a.best += n.lazy;
        a.lazy += n.lazy;
        b.best += n.lazy;
        b.lazy += n.lazy;
        n.lazy = 0;
    }
}

inline void comb(node &n, node a, node b) {
    if (a.best < b.best) {
        n.best = a.best;
        n.poz = a.poz;
    } else {
        n.best = b.best;
        n.poz = b.poz;
    }
}

void prep(int p, int st, int dr) {
    aint[q][p].best = aint[q][p].lazy = aint[q][p].val = 0;
    aint[q][p].poz = dr;
    if (st < dr) {
        int m = (st + dr) / 2;
        prep(2 * p, st, m);
        prep(2 * p + 1, m + 1, dr);
    }
}

void query(int p, int st, int dr) {
    val ^= aint[q][p].val;
    if (st == dr)
        aint[q][p].best = INF;
    else {
        propag(aint[q][p], aint[q][2 * p], aint[q][2 * p + 1]);
        int m = (st + dr) / 2;
        if (poz <= m) query(2 * p , st, m);
        else query(2 * p + 1, m + 1, dr);
        comb(aint[q][p], aint[q][2 * p], aint[q][2 * p + 1]);
    }
}

void update(int p, int st, int dr) {
    if (left <= st && dr <= right) {
        aint[q][p].best += add;
        aint[q][p].lazy += add;
        aint[q][p].val ^= val;
    } else {
        propag(aint[q][p], aint[q][2 * p], aint[q][2 * p + 1]);
        int m = (st + dr) / 2;
        if (left <= m) update(2 * p, st, m);
        if (m < right) update(2 * p + 1, m + 1, dr);
        comb(aint[q][p], aint[q][2 * p], aint[q][2 * p + 1]);
    }
}

void dfs(int x) {
    s[x] = 1;
    for (auto &y : g[x]) {
        if (s[y] == 0) {
            h[y] = h[x] + 1;
            t[y] = x;
            dfs(y);
            s[x] += s[y];
            if (s[y] > s[fiuMare[x]])
                fiuMare[x] = y;
        }
    }
    if (s[x] == 1) {
        fiuMare[x] = x;
        hMare[x] = h[x];
    } else
        hMare[x] = hMare[fiuMare[x]];
}

void hpd(int x) {
    if (sef[x] == 0) {
        unde[x] = ++m;
        zop[x] = (x != 1);
        lung[m] = hMare[x] - h[x] + zop[x];
        aint[m] = new node[4 * lung[m]];
        q = m;
        prep(1, 1, lung[m]);
        sef[x] = x;
    } else {
        unde[x] = unde[t[x]];
        zop[x] = zop[t[x]] + 1;
    }

    for (auto &y : g[x]) {
        if (t[y] == x) {
            if (y == fiuMare[x])
                sef[y] = sef[x];
            hpd(y);
        }
    }
}

inline void check() {
    d[q] = aint[q][1].best;
    urcare(hop[q]);
    coborare(hop[q]);

}

inline void baga(int w, int f) {
    add = w;
    val = f;
    int x = a[f], y = b[f];

    while (unde[x] != unde[y]) {
        if (h[sef[x]] < h[sef[y]])
            std::swap(x, y);
        q = unde[x];
        left = 1;
        right = zop[x];
        update(1, 1, lung[q]);
        check();
        x = t[sef[x]];
    }

    if (zop[x] < zop[y])
        std::swap(x, y);

    if (zop[x] != zop[y]) {
        q = unde[x];
        left = zop[y] + 1;
        right = zop[x];
        update(1, 1, lung[q]);
        check();
    }
}

int main() {
    int n;
    scanf("%d", &n);

    for (int i = 1; i < n; i++) {
        int x, y;
        scanf("%d%d", &x, &y);

        g[x].push_back(y);
        g[y].push_back(x);
    }

    dfs(1);
    hpd(1);

    for (int i = 1; i <= m; i++) {
        heap[i] = i;
        hop[i] = i;
    }

    for (int i = 1; i < n; i++) {
        scanf("%d%d", &a[i], &b[i]);

        baga(1, i);
    }

    for (int i = 1; i < n; i++) {
        q = heap[1];
        if (d[q] != 1) {
            printf("NO\n");
            return 0;
        }
        poz = aint[q][1].poz;
        val = 0;
        query(1, 1, lung[q]);
        baga(-1, val);
    }

    printf("YES\n");

    return 0;
}


Measured memory_bytes: 19840