#include <bits/stdc++.h>
const int N = 5e5 + 10;
int ri() {
  char c = getchar();
  int x = 0, f = 1;
  for (; c < '0' || c > '9'; c = getchar())
    if (c == '-') f = -1;
  for (; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) - '0' + c;
  return x * f;
}
struct Edge {
  int nx[N << 1], to[N << 1], pr[N], fa[N], tp;
  void add(int u, int v) {
    to[++tp] = v;
    nx[tp] = pr[u];
    pr[u] = tp;
  }
  void adds(int u, int v) {
    add(u, v);
    add(v, u);
  }
} A, B;
int g[N], tp, n;
struct Data {
  int a, b, c, d;
  Data() {}
  Data(int _a, int _b, int _c, int _d) {
    a = _a;
    b = _b;
    c = _c;
    d = _d;
  }
} ans[N];
int F(int x) { return g[x] == x ? x : g[x] = F(g[x]); }
void Dfs(Edge &T, int u, int f) {
  T.fa[u] = f;
  for (int i = T.pr[u]; i; i = T.nx[i])
    if (T.to[i] != f) Dfs(T, T.to[i], u);
}
void Dfs2(int u, int f) {
  for (int i = A.pr[u], v; i; i = A.nx[i])
    if ((v = A.to[i]) != f) {
      Dfs2(v, u);
      if (v != B.fa[u] && u != B.fa[v])
        ans[++tp] = Data(v, u, F(v), B.fa[F(v)]);
    }
}
int main() {
  n = ri();
  for (int i = 1; i < n; ++i) A.adds(ri(), ri());
  for (int i = 1; i < n; ++i) B.adds(ri(), ri());
  Dfs(A, 1, 0);
  Dfs(B, 1, 0);
  g[1] = 1;
  for (int v = 2; v <= n; ++v) {
    int u = B.fa[v];
    if (u == A.fa[v] || v == A.fa[u])
      g[v] = u;
    else
      g[v] = v;
  }
  tp = 0;
  Dfs2(1, 0);
  printf("%d\n", tp);
  for (int i = 1; i <= tp; ++i)
    printf("%d %d %d %d\n", ans[i].a, ans[i].b, ans[i].c, ans[i].d);
  return 0;
}
