#include <bits/stdc++.h>
using namespace std;
#define fo(i,a,b) for(int i=(a);i<(b);i++)
#define MOD 1000000007
#define MP make_pair
#define PB push_back
typedef long long ll;
typedef long double ld;

int N, par[100100];
pair<int, int> l[2][100100];
map<pair<int, int>, int> m[2];
queue<pair<int, int>> q;
bool done[2][100100];

int g (int i) { return par[i] == i ? i : par[i] = g(par[i]); }

struct comp {
        vector<int> v[2];
        int bsz () { return int(v[0].size()) + int(v[1].size()); }
} c[100100];

void add (int i, int x) {
        assert(!m[i].count(l[i][x]));
        m[i][l[i][x]] = x;

        //printf("add edge %d %d (%d %d)\n", i, x, l[i][x].first, l[i][x].second);

        if (!done[i][x]) {
                auto o = m[i^1].find(l[i][x]);
                if (o != m[i^1].end()) {
                        //printf("found overlap between %d and %d\n", x, o->second);
                        done[i][x] = true;
                        done[i^1][o->second] = true;
                        assert(l[i][x] == l[i^1][o->second]);
                        if (i == 0) q.push(MP(x, o->second));
                        else q.push(MP(o->second, x));
                }
        }
}

void fix (int i, int x) {
        auto it = m[i].find(l[i][x]);
        assert(it->second == x);
        m[i].erase(it);

        l[i][x].first = g(l[i][x].first);
        l[i][x].second = g(l[i][x].second);
        if (l[i][x].first > l[i][x].second) {
                swap(l[i][x].first, l[i][x].second);
        }

        if (l[i][x].first != l[i][x].second) add(i, x);
}

void merge (int i, int j) {
        assert(i == g(i));
        assert(j == g(j));

        //printf("merge %d %d\n", i, j);

        if (c[i].bsz() < c[j].bsz()) swap(i, j);

        //union find merge
        par[j] = i;

        fo(p, 0, 2) {
                for (int x : c[j].v[p]) if (g(l[p][x].first) != g(l[p][x].second)) {
                        fix(p, x);
                        c[i].v[p].PB(x);
                }
                c[j].v[p].clear();
        }
}

int main () {
        scanf("%d", &N);
        fo(i, 1, N+1) par[i] = i;
        fo(x, 0, 2) fo(i, 1, N) {
                int a, b; scanf("%d %d", &a, &b);
                if (a > b) swap(a, b);

                l[x][i] = MP(a, b);
                add(x, i);

                c[a].v[x].PB(i);
                c[b].v[x].PB(i);
        }

        int num=0;
        while (q.size()) {
                int xa, xb; tie(xa,xb) = q.front(); q.pop();
                int a = g(l[0][xa].first), b = g(l[0][xa].second);

                num++;

                //printf("onq %d %d (edge id)\n", xa, xb);

                assert(a == g(l[1][xb].first));
                assert(b == g(l[1][xb].second));
                //printf("corresponds to merge %d %d\n", a, b);

                merge(a, b);

                /*
                fo(i, 1, N+1) if (g(i) == i) {
                        printf("component %d alive\n", i);
                        for (int j : c[i].v[0]) printf("0 edges %d\n", j);
                        for (int j : c[i].v[1]) printf("1 edges %d\n", j);
                }
                */
        }

        assert(num <= N-1);

        fo(i, 2, N+1) if (g(i) != g(i-1)) {
                puts("NO");
                return 0;
        }
        puts("YES");

        return 0;
}


Measured memory_bytes: 27776