Problem: There are N cities in Bob's country connected by roads. Some pairs of cities are connected by public transport. There are two competing transport companies — Boblines operating buses and Bobrail running trains. When traveling from A to B, a passenger always first selects the mode of transport (either bus or train), and then embarks on a journey. For every pair of cities, there are exactly two ways of how to travel between them without visiting any city more than once — one using only bus routes, and the second using only train routes. Furthermore, there is no pair of cities that is directly connected by both a bus route and a train route.

You obtained the plans of each of the networks. Unfortunately, each of the companies uses different names for the same cities. More precisely, the bus company numbers the cities using integers from 1 to N, while the train company uses integers between N + 1 and 2N. Find one possible mapping between those two numbering schemes, such that no pair of cities is connected directly by both a bus route and a train route. Note that this mapping has to map different cities to different cities.

Input

The first line contains an integer N (2 ≤ N ≤ 10000), the number of cities.

N - 1 lines follow, representing the network plan of Boblines. Each contains two integers u and v (1 ≤ u, v ≤ N), meaning that there is a bus route between cities u and v.

N - 1 lines follow, representing the network plan of Bobrail. Each contains two integers u and v (N + 1 ≤ u, v ≤ 2N), meaning that there is a train route between cities u and v.

Output

If there is no solution, output a single line with the word "No".

If a solution exists, output two lines. On the first line, there should be the word "Yes". On the second line, there should be N integers P1, P2, ..., PN (N + 1 ≤ Pi ≤ 2N) — the mapping between the two numbering schemes. More precisely, for i ≠ j it should be Pi ≠ Pj, and for every direct bus route (i, j), there is no direct train route between (Pi, Pj).

If there are multiple solutions, you may print any of them.

Examples

Input

4
1 2
2 3
3 4
5 6
6 7
7 8


Output

Yes
6 8 5 7


Input

4
1 2
2 3
3 4
5 6
5 7
5 8


Output

No


Input

7
1 2
1 3
1 4
1 5
5 6
6 7
8 9
9 10
10 11
11 12
12 13
13 14


Output

Yes
9 14 11 12 13 10 8

Note

The first sample (bus lines in red and rail lines in blue):

<image>

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
long long gcd(long long a, long long b) { return b == 0 ? a : gcd(b, a % b); }
const int MAXN = 10000;
struct T {
  int n;
  vector<int> adj[MAXN];
  bool alive[MAXN];
  int nalive;
  int deg[MAXN];
  int afst[MAXN], alst[MAXN], anxt[MAXN], aprv[MAXN];
  int bfst, blst, bnxt[MAXN], bprv[MAXN];
  priority_queue<pair<int, int> > pq;
  void init() {
    nalive = n;
    for (int i = (0); i < (n); ++i)
      alive[i] = true, deg[i] = ((int)(adj[i]).size()), afst[i] = alst[i] = -1;
    bfst = blst = -1;
    for (int at = (0); at < (n); ++at)
      if (deg[at] == 1) aappend(at, adj[at][0]);
    for (int at = (0); at < (n); ++at)
      if (afst[at] != -1) bappend(at);
    pq = priority_queue<pair<int, int> >();
    for (int i = (0); i < (n); ++i) pq.push(make_pair(deg[i], i));
  }
  void killleaf(int at) {
    assert(deg[at] == 1);
    alive[at] = false;
    --nalive;
    int to = -1;
    for (int i = (0); i < (((int)(adj[at]).size())); ++i)
      if (alive[adj[at][i]]) {
        assert(to == -1);
        to = adj[at][i];
      }
    assert(to != -1);
    --deg[at];
    if (deg[at] == 0) {
      aremove(at, to);
      if (afst[to] == -1) bremove(to);
    }
    --deg[to];
    pq.push(make_pair(deg[to], to));
    if (deg[to] == 0) {
      aremove(to, at);
      if (afst[at] == -1) bremove(at);
    }
    if (deg[to] == 1) {
      int oth = -1;
      for (int i = (0); i < (((int)(adj[to]).size())); ++i)
        if (alive[adj[to][i]]) {
          assert(oth == -1);
          oth = adj[to][i];
        }
      assert(oth != -1);
      aappend(to, oth);
      if (afst[oth] == to && anxt[to] == -1) bappend(oth);
    }
  }
  void aappend(int at, int to) {
    aprv[at] = alst[to], anxt[at] = -1;
    if (aprv[at] == -1)
      afst[to] = at;
    else
      anxt[aprv[at]] = at;
    alst[to] = at;
  }
  void aremove(int at, int to) {
    if (aprv[at] == -1)
      afst[to] = anxt[at];
    else
      anxt[aprv[at]] = anxt[at];
    if (anxt[at] == -1)
      alst[to] = aprv[at];
    else
      aprv[anxt[at]] = aprv[at];
  }
  void bappend(int at) {
    bprv[at] = blst, bnxt[at] = -1;
    if (bprv[at] == -1)
      bfst = at;
    else
      bnxt[bprv[at]] = at;
    blst = at;
  }
  void bremove(int at) {
    if (bprv[at] == -1)
      bfst = bnxt[at];
    else
      bnxt[bprv[at]] = bnxt[at];
    if (bnxt[at] == -1)
      blst = bprv[at];
    else
      bprv[bnxt[at]] = bprv[at];
  }
  bool getleavesatleastthreeapart(pair<int, int> &u, pair<int, int> &v) {
    if (bfst == -1 || bnxt[bfst] == -1) return false;
    int x = bfst, y = bnxt[bfst], r = maxdeg().second;
    if (afst[r] != -1 && x != r) y = r;
    u = make_pair(afst[x], x), v = make_pair(afst[y], y);
    assert(u.first != -1 && v.first != -1);
    return true;
  }
  pair<int, int> maxdeg() {
    while (!pq.empty() &&
           (!alive[pq.top().second] || deg[pq.top().second] != pq.top().first))
      pq.pop();
    return !pq.empty() ? pq.top() : make_pair(0, -1);
  }
  bool isstar() { return maxdeg().first == nalive - 1; }
  bool issemistar() { return maxdeg().first == nalive - 2; }
  bool ispath() { return maxdeg().first <= 2; }
  bool getsemistar1(vector<int> &rem) {
    if (!issemistar()) return false;
    assert(bfst != -1 && bnxt[bfst] != -1 && bnxt[bnxt[bfst]] == -1);
    int w = maxdeg().second;
    assert(bfst == w || bnxt[bfst] == w);
    int v = bfst + bnxt[bfst] - w;
    assert(afst[v] != -1 && anxt[afst[v]] == -1);
    int u = afst[v];
    rem.clear();
    rem.push_back(u);
    rem.push_back(v);
    rem.push_back(w);
    for (int i = (0); i < (n); ++i)
      if (alive[i] && i != u && i != v && i != w) rem.push_back(i);
    return true;
  }
  bool getsemistar2(vector<int> &rem) {
    if (isstar()) return false;
    assert(bfst != -1 && bnxt[bfst] != -1);
    int u = bfst, w = afst[u], v = afst[bnxt[bfst]];
    assert(w != -1 && u != -1);
    rem.clear();
    rem.push_back(u);
    rem.push_back(v);
    rem.push_back(w);
    for (int i = (0); i < (n); ++i)
      if (alive[i] && i != u && i != v && i != w) rem.push_back(i);
    return true;
  }
  bool getpath1(vector<int> &rem) {
    if (!ispath()) return false;
    int at = -1;
    for (int i = (0); i < (n); ++i)
      if (alive[i] && deg[i] <= 1) {
        at = i;
        break;
      }
    assert(at != -1);
    rem.push_back(at);
    while (true) {
      int to = -1;
      for (int i = (0); i < (((int)(adj[at]).size())); ++i)
        if (alive[adj[at][i]] && (((int)(rem).size()) == 1 ||
                                  adj[at][i] != rem[((int)(rem).size()) - 2])) {
          assert(to == -1);
          to = adj[at][i];
        }
      if (to == -1) break;
      at = to;
      rem.push_back(at);
    }
    return ((int)(rem).size()) == 5;
  }
  bool getpath2(vector<int> &rem) {
    if (!getpath1(rem)) return false;
    swap(rem[0], rem[2]);
    swap(rem[0], rem[4]);
    swap(rem[0], rem[3]);
    swap(rem[0], rem[1]);
    return true;
  }
};
int n;
T a, b;
int mp[MAXN];
struct Op {
  pair<int, int> au, av, bu, bv;
};
vector<Op> ops;
void run() {
  scanf("%d", &n);
  a.n = n;
  for (int i = (0); i < (n - 1); ++i) {
    int u, v;
    scanf("%d%d", &u, &v);
    --u, --v;
    a.adj[u].push_back(v);
    a.adj[v].push_back(u);
  }
  a.init();
  b.n = n;
  for (int i = (0); i < (n - 1); ++i) {
    int u, v;
    scanf("%d%d", &u, &v);
    --u, --v;
    u -= n;
    v -= n;
    b.adj[u].push_back(v);
    b.adj[v].push_back(u);
  }
  b.init();
  if (a.isstar() || b.isstar()) {
    printf("No\n");
    return;
  }
  for (int i = (0); i < (n); ++i) mp[i] = -1;
  ops.clear();
  while (true) {
    if (a.issemistar()) {
      vector<int> arem;
      assert(a.getsemistar1(arem));
      vector<int> brem;
      assert(b.getsemistar2(brem));
      assert(a.nalive == b.nalive && ((int)(arem).size()) == a.nalive &&
             ((int)(brem).size()) == b.nalive);
      for (int i = (0); i < (((int)(arem).size())); ++i) mp[arem[i]] = brem[i];
      break;
    }
    if (b.issemistar()) {
      vector<int> arem;
      assert(a.getsemistar2(arem));
      vector<int> brem;
      assert(b.getsemistar1(brem));
      assert(a.nalive == b.nalive && ((int)(arem).size()) == a.nalive &&
             ((int)(brem).size()) == b.nalive);
      for (int i = (0); i < (((int)(arem).size())); ++i) mp[arem[i]] = brem[i];
      break;
    }
    if (a.nalive == 5 || b.nalive == 5) {
      assert(a.nalive == 5 && b.nalive == 5 && a.ispath() && b.ispath());
      vector<int> arem;
      assert(a.getpath1(arem));
      vector<int> brem;
      assert(b.getpath2(brem));
      assert(a.nalive == b.nalive && ((int)(arem).size()) == a.nalive &&
             ((int)(brem).size()) == b.nalive);
      for (int i = (0); i < (((int)(arem).size())); ++i) mp[arem[i]] = brem[i];
      break;
    }
    assert(a.nalive >= 6 && b.nalive >= 6);
    pair<int, int> au, av;
    assert(a.getleavesatleastthreeapart(au, av));
    pair<int, int> bu, bv;
    assert(b.getleavesatleastthreeapart(bu, bv));
    a.killleaf(au.first);
    a.killleaf(av.first);
    b.killleaf(bu.first);
    b.killleaf(bv.first);
    Op op;
    op.au = au, op.av = av, op.bu = bu, op.bv = bv;
    ops.push_back(op);
  }
  for (int i = ((int)(ops).size()) - 1; i >= 0; --i) {
    pair<int, int> au = ops[i].au, av = ops[i].av, bu = ops[i].bu,
                   bv = ops[i].bv;
    if (mp[au.second] != bu.second && mp[av.second] != bv.second) {
      mp[au.first] = bu.first;
      mp[av.first] = bv.first;
      continue;
    }
    if (mp[au.second] != bv.second && mp[av.second] != bu.second) {
      mp[au.first] = bv.first;
      mp[av.first] = bu.first;
      continue;
    }
    assert(false);
  }
  printf("Yes\n");
  for (int i = (0); i < (n); ++i) {
    if (i != 0) printf(" ");
    printf("%d", mp[i] == -1 ? -1 : mp[i] + n + 1);
  }
  puts("");
}
int main() {
  run();
  return 0;
}