#include <bits/stdc++.h>
using namespace std;
const int MAXN = 250005;
template <typename T>
inline void read(T &AKNOI) {
  T x = 0, flag = 1;
  char ch = getchar();
  while (!isdigit(ch)) {
    if (ch == '-') flag = -1;
    ch = getchar();
  }
  while (isdigit(ch)) {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  AKNOI = flag * x;
}
int n, U[MAXN], V[MAXN], m, f[MAXN];
vector<int> e[MAXN];
int getf(int u) { return (f[u] == u) ? u : f[u] = getf(f[u]); }
inline void Merge(int u, int v) {
  u = getf(u), v = getf(v);
  if (u ^ v) f[u] = v;
}
void DFS(int u, int ff) {
  for (auto v : e[u]) {
    if (v == ff) continue;
    DFS(v, u);
    U[++m] = u;
    V[m] = v;
  }
}
struct LinkCutTree {
  int fa[MAXN], ch[MAXN][2], rev[MAXN];
  inline int dir(int x) { return (ch[fa[x]][1] == x); }
  inline bool nroot(int x) { return (ch[fa[x]][0] == x || ch[fa[x]][1] == x); }
  inline void pushdown(int x) {
    if (rev[x]) {
      rev[ch[x][0]] ^= 1;
      rev[ch[x][1]] ^= 1;
      swap(ch[x][0], ch[x][1]);
      rev[x] = 0;
    }
  }
  void pushrev(int x) {
    if (nroot(x)) pushrev(fa[x]);
    pushdown(x);
  }
  inline void Rotate(int x) {
    int y = fa[x], z = fa[y];
    int t = dir(x), c = ch[x][t ^ 1];
    if (nroot(y)) ch[z][dir(y)] = x;
    ch[x][t ^ 1] = y;
    ch[y][t] = c;
    fa[x] = z;
    fa[y] = x;
    fa[c] = y;
  }
  inline void Splay(int x) {
    pushrev(x);
    while (nroot(x)) {
      if (nroot(fa[x])) {
        Rotate((dir(x) ^ dir(fa[x])) ? x : fa[x]);
      }
      Rotate(x);
    }
  }
  inline void Access(int x) {
    for (int i = 0; x; i = x, x = fa[x]) {
      Splay(x);
      ch[x][1] = i;
    }
  }
  inline void Evert(int x) {
    Access(x);
    Splay(x);
    rev[x] ^= 1;
  }
  inline void Split(int x, int y) {
    Evert(x);
    Access(y);
    Splay(y);
  }
  void Link(int x, int y) {
    Evert(x);
    fa[x] = y;
  }
  void Cut(int x, int y) {
    Split(x, y);
    fa[x] = ch[y][0] = 0;
  }
  int Match(int x, int y) {
    Split(x, y);
    int fr = 0, to = 0;
    while (y) {
      pushdown(y);
      if (getf(x) == getf(y)) {
        y = ch[fr = y][1];
      } else {
        to = y;
        y = ch[to = y][0];
      }
    }
    printf("%d %d\n", fr, to);
    return to;
  }
} lct;
void init() {
  read(n);
  for (int i = 1, u, v; i < n; ++i) {
    read(u);
    read(v);
    e[u].push_back(v);
    e[v].push_back(u);
  }
  DFS(1, 0);
  for (int i = 1, u, v; i < n; ++i) {
    read(u);
    read(v);
    lct.Link(u, v);
  }
}
void solve() {
  printf("%d\n", n - 1);
  for (int i = 1; i <= n; ++i) {
    f[i] = i;
  }
  for (int i = 1; i < n; ++i) {
    printf("%d %d ", U[i], V[i]);
    lct.Cut(V[i], lct.Match(V[i], U[i]));
    lct.Link(V[i], U[i]);
    Merge(V[i], U[i]);
  }
}
int main() {
  init();
  solve();
  return 0;
}
