#include <bits/stdc++.h>
using namespace std;
int n, cb[250005], dp[250005], mii[250005], ia[250005], ib[250005],
    ca = 1, pi[250005], par[250005], d[250005], at;
bool gb[250005], ga[250005];
vector<int> va[250005], vb[250005], vc[250005];
vector<pair<int, int>> seg[250005];
queue<int> q;
void dfs1(int a, int b) {
  dp[a] = 1;
  for (int i : va[a])
    if (i != b) {
      d[i] = d[a] + 1;
      par[i] = a;
      dfs1(i, a);
      dp[a] += dp[i];
      if (dp[i] > dp[mii[a]]) mii[a] = i;
    }
}
void dfs2(int a, int b) {
  ib[a] = vc[ia[a]].size();
  vc[ia[a]].push_back(a);
  if (mii[a] == 0) return;
  ia[mii[a]] = ia[a];
  dfs2(mii[a], a);
  for (int i : va[a])
    if (i != b && i != mii[a]) {
      pi[ca] = a;
      ia[i] = ca++;
      dfs2(i, a);
    }
}
pair<int, int> operator+(const pair<int, int>& a, const pair<int, int>& b) {
  return {d[a.first] < d[b.first] ? a.first : b.first,
          d[a.second] > d[b.second] ? a.second : b.second};
}
void build(int l, int r, int i) {
  if (l + 1 == r) {
    seg[at][i] = {vc[at][l], vc[at][l]};
    return;
  }
  int mi = (l + r) / 2;
  build(l, mi, i * 2);
  build(mi, r, i * 2 + 1);
  seg[at][i] = seg[at][i * 2] + seg[at][i * 2 + 1];
}
pair<int, int> query(int a, int b, int l, int r, int i) {
  if (a == l && b == r) return seg[at][i];
  int mi = (l + r) / 2;
  if (b <= mi) return query(a, b, l, mi, i * 2);
  if (a >= mi) return query(a, b, mi, r, i * 2 + 1);
  return query(a, mi, l, mi, i * 2) + query(mi, b, mi, r, i * 2 + 1);
}
void kill(int a, int l, int r, int i) {
  if (a == l && a + 1 == r) {
    seg[at][i] = {n + 2, n + 1};
    return;
  }
  int mi = (l + r) / 2;
  if (a < mi)
    kill(a, l, mi, i * 2);
  else
    kill(a, mi, r, i * 2 + 1);
  seg[at][i] = seg[at][i * 2] + seg[at][i * 2 + 1];
}
int main() {
  scanf("%d", &n);
  for (int i = 1; i < n; i++) {
    int ta, tb;
    scanf("%d%d", &ta, &tb);
    va[ta].push_back(tb);
    va[tb].push_back(ta);
  }
  for (int i = 1; i < n; i++) {
    int ta, tb;
    scanf("%d%d", &ta, &tb);
    vb[ta].push_back(tb);
    vb[tb].push_back(ta);
  }
  d[n + 1] = INT_MIN;
  d[n + 2] = INT_MAX;
  dfs1(1, 0);
  dfs2(1, 0);
  for (at = 0; at < ca; at++) {
    seg[at].resize((vc[at].size() + 5) * 4);
    build(0, vc[at].size(), 1);
  }
  printf("%d\n", n - 1);
  for (int i = 1; i <= n; i++) {
    cb[i] = vb[i].size();
    if (cb[i] == 1) q.push(i);
  }
  while (!q.empty()) {
    int tmp = q.front();
    q.pop();
    gb[tmp] = 1;
    if (cb[tmp] == 1)
      for (int i : vb[tmp])
        if (!gb[i]) {
          int ta = tmp, tb = i;
          while (ia[ta] != ia[tb]) {
            if (ia[ta] < ia[tb]) swap(ta, tb);
            ta = pi[ia[ta]];
          }
          if (d[ta] < d[tb]) swap(ta, tb);
          int ki = 0, lca = tb;
          if (tmp != lca) {
            ta = tmp;
            while (ia[ta] != ia[lca]) {
              at = ia[ta];
              auto p = query(0, ib[ta] + 1, 0, vc[at].size(), 1);
              if (p.second != n + 1) {
                ki = p.second;
                break;
              }
              ta = pi[ia[ta]];
            }
            if (ki == 0 && ta != lca) {
              at = ia[ta];
              auto p = query(ib[lca] + 1, ib[ta] + 1, 0, vc[at].size(), 1);
              if (p.second != n + 1) ki = p.second;
            }
          }
          if (!ki) {
            ta = i;
            while (ia[ta] != ia[lca]) {
              at = ia[ta];
              auto p = query(0, ib[ta] + 1, 0, vc[at].size(), 1);
              if (p.first != n + 2) ki = p.first;
              ta = pi[ia[ta]];
            }
            if (ta != lca) {
              at = ia[ta];
              auto p = query(ib[lca] + 1, ib[ta] + 1, 0, vc[at].size(), 1);
              if (p.first != n + 2) ki = p.first;
            }
          }
          at = ia[ki];
          kill(ib[ki], 0, vc[at].size(), 1);
          printf("%d %d %d %d\n", ki, par[ki], tmp, i);
          cb[i]--;
          if (cb[i] == 1) q.push(i);
          break;
        }
  }
}
