#include <bits/stdc++.h>
using namespace std;
const int maxn = 500010;
struct Edge {
  int x, y;
} Ed[maxn];
map<long long, int> M;
int head[maxn], nxt[maxn << 1], E[maxn << 1], Ecnt;
int Ehead[maxn], Enext[maxn << 1], Etail[maxn << 1], EE[maxn << 1], EEcnt;
int fa[maxn];
int n, m;
void Add_Edge(int x, int y) {
  nxt[++Ecnt] = head[x];
  head[x] = Ecnt;
  E[Ecnt] = y;
  nxt[++Ecnt] = head[y];
  head[y] = Ecnt;
  E[Ecnt] = x;
}
void Add_EdgeE(int x, int y, int p) {
  Enext[++EEcnt] = Ehead[x];
  if (Ehead[x] == 0) Etail[x] = EEcnt;
  Ehead[x] = EEcnt;
  EE[EEcnt] = p;
  Enext[++EEcnt] = Ehead[y];
  if (Ehead[y] == 0) Etail[y] = EEcnt;
  Ehead[y] = EEcnt;
  EE[EEcnt] = p;
}
int Find(int x) { return fa[x] == x ? x : fa[x] = Find(fa[x]); }
void DFS(int x, int father) {
  for (int i = head[x]; i; i = nxt[i])
    if (E[i] != father) DFS(E[i], x);
  if (x == 1) return;
  if (Find(x) == Find(father)) return;
  int now = Ehead[Find(x)];
  while (Ehead[Find(x)] && Find(Ed[EE[now]].x) == Find(Ed[EE[now]].y))
    now = Ehead[Find(x)] = Enext[Ehead[Find(x)]];
  if (!now) return;
  int u = Ed[EE[now]].x, v = Ed[EE[now]].y;
  printf("%d %d %d %d\n", father, x, u, v);
  Enext[Etail[Find(u)]] = Ehead[Find(v)];
  Etail[Find(u)] = Etail[Find(v)];
  fa[Find(v)] = Find(u);
}
int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) fa[i] = i;
  for (int i = 1, x, y; i < n; i++) {
    scanf("%d%d", &x, &y);
    if (x > y) swap(x, y);
    M[(long long)x * n + y] = 1;
    Add_Edge(x, y);
  }
  for (int i = 1, x, y; i < n; i++) {
    scanf("%d%d", &x, &y);
    if (x > y) swap(x, y);
    if (M[(long long)x * n + y] == 1) {
      fa[Find(x)] = Find(y);
      continue;
    }
    Ed[++m].x = x, Ed[m].y = y;
  }
  for (int i = 1; i <= m; i++) Add_EdgeE(Find(Ed[i].x), Find(Ed[i].y), i);
  printf("%d\n", m);
  DFS(1, 0);
  return 0;
}
