#include <bits/stdc++.h>
 
using namespace std;
 
 
int const N = 123456;
int const K = 18;
int const INF = 1 << 30;

int cc;
 
struct segmenttree {
    vector<int> d;
    vector<pair<int, int> > a;
    int n;
    int sid;
   
    void init(int sz) {
        sid = cc++;
        n = 1;
        while (n < sz) n *= 2;
        d.assign(2 * n, 0);
        a.assign(2 * n, make_pair(0, 0));
        for (int i = n; i < 2 * n; i++) {
          a[i].second = i - n;
        }
        for (int i = n - 1; i > 0; i--) {
          a[i].second = a[2 * i].second;
        }
    }

    void relax(int v) {
      if (d[v] == 0) return;
      a[v].first += d[v];
      d[2 * v] += d[v];
      d[2 * v + 1] += d[v];
      d[v] = 0;
    }

    void add(int v, int l, int r, int left, int right, int val) {
      if (r <= left || right <= l) {
        return;
      }
      if (left <= l && r <= right) {
        d[v] += val;
        return;
      }
      relax(v);
      int m = (l + r) / 2;
      add(v * 2, l, m, left, right, val);
      add(v * 2 + 1, m, r, left, right, val);
      a[v] = std::min(make_pair(a[v * 2].first + d[v * 2], a[v * 2].second), 
                      make_pair(a[v * 2 + 1].first + d[v * 2 + 1], a[v * 2 + 1].second));
    }
   
    void add(int l, int r, int val) {
      add(1, 0, n, l, r, val);
    }

    pair<int, int> getmin(int v, int l, int r, int left, int right) {
      if (r <= left || right <= l) {
        return {INF, -1};
      }
      if (left <= l && r <= right) {
        return {a[v].first + d[v], a[v].second};
      }
      relax(v);
      int m = (l + r) / 2;
      return std::min(getmin(v * 2, l, m, left, right), getmin(v * 2 + 1, m, r, left, right));
    }

    pair<int, int> getmin(int l, int r) {
      return getmin(1, 0, n, l, r);
    }
   
    // pair<int, int> getmin(int l, int r) {
    //     printf("%d getmin %d %d\n", sid, l, r);
    //     pair<int, int> ret = {INF, -1};
    //     for (int i = l; i < r; i++) {
    //       ret = std::min(ret, make_pair(d[i], i));
    //     }
    //     return ret;
    // }
};

// struct segmenttree {
//     vector<int> d;
//     vector<pair<int, int> > a;
//     int n;
//     int sid;
   
//     void init(int sz) {
//         sid = cc++;
//         n = 1;
//         while (n < sz) n *= 2;
//         d.assign(2 * n, 0);
//     }

//     void add(int l, int r, int v) {
//       for (int i = l; i < r; i++) d[i] += v;
//     }

//     pair<int, int> getmin(int l, int r) {
//         // printf("%d getmin %d %d\n", sid, l, r);
//         pair<int, int> ret = {INF, -1};
//         for (int i = l; i < r; i++) {
//           ret = std::min(ret, make_pair(d[i], i));
//         }
//         return ret;
//     }
// };

 
segmenttree tree[N];
vector<int> hpath[N];
vector<int> edges[N];
int pp[K][N];
int T;
int en[N], ex[N], depth[N], up[N], heavy[N], sz[N], parent[N];
 
void godown(int root) {
    int d = 0;
    for (int v = root; v >= 0; v = heavy[v]) {
        depth[v] = d++;
        up[v] = root;
        hpath[root].push_back(v);
    }
    tree[root].init(d);
}
 
void dfs(int v, int p) {
    sz[v] = 1;
    en[v] = T++;
    heavy[v] = -1;
    parent[v] = p;
    for (int to : edges[v]) {
        if (to == p) continue;
        dfs(to, v);
        sz[v] += sz[to];
        if (heavy[v] < 0 || sz[heavy[v]] < sz[to]) heavy[v] = to;
    }
    for (int to : edges[v]) {
        if (to == p || to == heavy[v])
            continue;
        godown(to);
    }
    ex[v] = T;
    if (p < 0) godown(v);
}
 
int anc(int v, int u) {
    return en[v] <= en[u] && ex[u] <= ex[v];
}
 
int glca(int v, int u) {
    if (anc(v, u)) return v;
    for (int i = K - 1; i >= 0; i--)
        if (!anc(pp[i][v], u)) v = pp[i][v];
    return parent[v];
}
 
// int getpath(int v, int p) {
//     int ans = -INF;
//     while (true) {
//         if (up[v] == up[p]) {
//             ans = max(ans, tree[up[v]].getmax(depth[p], depth[v] + 1));
//             break;
//         }
//         ans = max(ans, tree[up[v]].getmax(0, depth[v] + 1));
//         v = parent[up[v]];
//     }
//     return ans;
// }

int head = 0;
int tail = 0;
int q[N];

void addcpath(segmenttree &tree, vector<int> &hpath, int dl, int dr, int value) {
  tree.add(dl, dr, value);
  if (value < 0) {
    while (true) {
      pair<int, int> e = tree.getmin(dl, dr);
      if (e.first == 1) {
        q[tail++] = hpath[e.second];
        tree.add(e.second, e.second + 1, N);
      } else break;
    }
  }
}

void addpath(int v, int p, int add) {
    while (true) {
        if (up[v] == up[p]) {
          addcpath(tree[up[v]], hpath[up[v]], depth[p] + 1, depth[v] + 1, add);
            // tree[up[v]].addpath(depth[p] + 1, depth[v] + 1, add);
            break;
        }
        addcpath(tree[up[v]], hpath[up[v]], 0, depth[v] + 1, add);
        // tree[up[v]].addpath(0, depth[v] + 1, add);
        v = parent[up[v]];
    }
}

int fx[N];

void mxor(int x, int y) {
  for (int i = x; i < N; i |= i + 1) {
    fx[i] ^= y;
  }
}

int gxor(int x) {
  int ret = 0;
  for (int i = x; i >= 0; i = (i & (i + 1)) - 1) {
    ret ^= fx[i];
  }
  return ret;
}

int gxor(int left, int right) {
  return gxor(right - 1) ^ gxor(left - 1);
}
 

int qu[N], qv[N];
int waspath[N];

int main() {
    int n;
    scanf("%d", &n);
    for (int i = 0; i + 1 < n; i++) {
        int v, u;
        scanf("%d%d", &v, &u);
        --v;
        --u;
        edges[v].push_back(u);
        edges[u].push_back(v);
    }
    T = 0;
    dfs(0, -1);
    for (int v = 0; v < n; v++) pp[0][v] = parent[v] >= 0 ? parent[v] : v;
    for (int i = 1; i < K; i++) {
        for (int v = 0; v < n; v++) {
            pp[i][v] = pp[i - 1][pp[i - 1][v]];
        }
    }
    for (int i = 0; i + 1 < n; i++) {
      scanf("%d%d", qv + i, qu + i);
      --qv[i];
      --qu[i];
      mxor(en[qv[i]], i);
      mxor(en[qu[i]], i);
      int lc = glca(qv[i], qu[i]);
      addpath(qv[i], lc, 1);
      addpath(qu[i], lc, 1);
    }
    for (int i = 1; i < n; i++) {
      // printf("%d\n", tree[up[i]].getmin(depth[i], depth[i] + 1).first);
      if (tree[up[i]].getmin(depth[i], depth[i] + 1).first == 1) {
        tree[up[i]].add(depth[i], depth[i] + 1, N);
        q[tail++] = i;
      }
    }
    while (head < tail) {
      int v = q[head++];
      int pid = gxor(en[v], ex[v]);
      assert(!waspath[pid]);
      waspath[pid] = true;
      mxor(en[qv[pid]], pid);
      mxor(en[qu[pid]], pid);
      int lc = glca(qv[pid], qu[pid]);
      addpath(qv[pid], lc, -1);
      addpath(qu[pid], lc, -1);
    }
    puts(head == n - 1 ? "YES" : "NO");
}


Measured memory_bytes: 41080