#include <set>
#include <cstdio>
#include <cstring>
#include <cassert>
#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

#define TRACE(x) cerr << #x << " = " << x << endl
#define REP(i, n) for (int i=0; i<n; i++)
#define FOR(i, a, b) for (int i=(a); i<(b); i++)
#define _ << " " <<

typedef long long ll;
typedef pair<int, int> P;
#define X first
#define Y second

const int MAX = 1<<17, TOUR = 1<<17;

int sub[MAX], root[MAX], par[MAX], dub[MAX], poz[MAX], vr=0;
vector <int> V[MAX];

int dfs_sub(int x, int pr) {
  sub[x] = 1;
  par[x] = pr;
  if (x) dub[x] = dub[pr] + 1;

  REP(i, (int) V[x].size()) {
    if (V[x][i] != pr) sub[x] += dfs_sub(V[x][i], x);
    else V[x].erase(V[x].begin() + i--);
  }

  return sub[x];
}

void hld(int x, int kor) {
  poz[x] = vr++;
  root[x] = kor;

  int mx = -1, ind = -1;
  for (auto it : V[x]) {
    if (sub[it] > mx) {
      mx = sub[it];
      ind = it;
    }
  }

  if (ind != -1)
    hld(ind, kor);

  for (auto it : V[x])
    if (it != ind)
      hld(it, it);
}

struct tour {
  set <int> S;
  P mn; //val, indnode
  int prop;  
} t[2*TOUR];

void propagiraj(int pos) {
  FOR(i, 2*pos, 2*pos+2) {
    t[i].prop += t[pos].prop;
    t[i].mn.X += t[pos].prop;
  }
  t[pos].prop = 0;
}

void upd(int pos) {
  assert(pos < TOUR);
  t[pos].mn = min(t[2*pos].mn, t[2*pos+1].mn);
}

void tour_insert(int pos, int lo, int hi, int begin, int end, int val) {
  if (lo >= end || hi <= begin) return;
  if (lo >= begin && hi <= end) {
    t[pos].S.insert(val);
    t[pos].mn.X++;
    t[pos].prop++;
    return;
  }

  propagiraj(pos);
  tour_insert(2*pos+0, lo, (lo+hi)/2, begin, end, val);
  tour_insert(2*pos+1, (lo+hi)/2, hi, begin, end, val);
  upd(pos);
}

void tour_erase(int pos, int lo, int hi, int begin, int end, int val) {
  if (lo >= end || hi <= begin) return;
  if (lo >= begin && hi <= end) {
    auto it = t[pos].S.find(val);
    assert(it != t[pos].S.end());
    t[pos].S.erase(it);
    t[pos].mn.X--;
    t[pos].prop--;
    return;
  }

  propagiraj(pos);
  tour_erase(2*pos+0, lo, (lo+hi)/2, begin, end, val);
  tour_erase(2*pos+1, (lo+hi)/2, hi, begin, end, val);
  upd(pos);
}

void ubij(int pos, int lo, int hi, int begin) {
  if (lo >= begin + 1 || hi <= begin) return;
  if (lo >= begin && hi <= begin + 1) {
    t[pos].mn.X = 1<<25;
    return;
  }
  propagiraj(pos);
  ubij(2*pos+0, lo, (lo+hi)/2, begin);
  ubij(2*pos+1, (lo+hi)/2, hi, begin);
  upd(pos);
}

void ubaci(int a, int b, int ind) {
  for (;;) {
    if (root[a] == root[b]) {
      if (dub[a] > dub[b]) swap(a, b); //b dublje
      tour_insert(1, 0, TOUR, poz[a] + 1, poz[b] + 1, ind);
      break;
    }
    if (dub[root[a]] > dub[root[b]]) swap(a, b); //bov root dublje
    tour_insert(1, 0, TOUR, poz[root[b]], poz[b] + 1, ind);
    b = par[root[b]];
  }
}

void izbaci(int a, int b, int ind) {
  for (;;) {
    if (root[a] == root[b]) {
      if (dub[a] > dub[b]) swap(a, b); //b dublje
      tour_erase(1, 0, TOUR, poz[a] + 1, poz[b] + 1, ind);
      break;
    }
    if (dub[root[a]] > dub[root[b]]) swap(a, b); //bov root dublje
    tour_erase(1, 0, TOUR, poz[root[b]], poz[b] + 1, ind);
    b = par[root[b]];
  }
}

void nope() {
  printf("NO\n");
  exit(0);
}

int ea[MAX], eb[MAX];
int n;

int nadi_koji(int pos) {
  int ret = -1;
  pos += TOUR;
  for (; pos; pos/=2) {
    if (!t[pos].S.empty()) {
      assert((int) t[pos].S.size() == 1 && ret == -1);
      ret = *t[pos].S.begin();
    }
  }

  return ret;
}

void solve() {
  REP(i, n-1) {
    P tmp = t[1].mn;
    if (!tmp.X) {
      ubij(1, 0, TOUR, tmp.Y);
      i--;
      continue;
    }
    if (tmp.X > 1) nope();

    int ind = nadi_koji(tmp.Y);
    izbaci(ea[ind], eb[ind], ind);
  }  
}

void init() {
  REP(i, n) t[i+TOUR].mn = P(0, i);
  FOR(i, n, TOUR) t[i+TOUR].mn = P(1<<25, 1<<25);
  for (int i=TOUR-1; i; i--) upd(i);
}

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

  REP(i, n-1) {
    int a, b;
    scanf("%d%d", &a, &b); a--; b--;
    V[a].push_back(b);
    V[b].push_back(a);
  }

  dfs_sub(0, -1);
  hld(0, 0);

  REP(i, n-1) {
    int a, b;
    scanf("%d%d", &a, &b); a--; b--;
    ea[i] = a; eb[i] = b;
    ubaci(a, b, i);
  }

  solve();
  printf("YES\n");

  return 0;
}


Measured memory_bytes: 135936