#include <bits/stdc++.h>
using namespace std;
int tot = 0, h[500005], cnt;
int read() {
  char c = getchar();
  int res = 0;
  while (c < '0' || c > '9') c = getchar();
  while (c >= '0' && c <= '9')
    res = (res << 1) + (res << 3) + (c ^ 48), c = getchar();
  return res;
}
struct edge {
  int x, y;
} a[300005], b[300005];
struct Tree {
  int fa, ch[2];
  int size, v;
  int rev, aus;
} tree[1000005];
struct Edge {
  int to, next;
} w[500005];
void add(int x, int y) {
  w[++cnt] = (Edge){y, h[x]};
  h[x] = cnt;
}
int whoson(int x) { return (tree[tree[x].fa].ch[0] == x ? 0 : 1); }
void Connect(int x, int fa, int son) {
  tree[x].fa = fa;
  tree[fa].ch[son] = x;
}
void push_up(int x) {
  tree[x].size =
      tree[tree[x].ch[0]].size + tree[tree[x].ch[1]].size + tree[x].v;
}
void rotate(int x) {
  int y = tree[x].fa, z = tree[y].fa;
  int yson = whoson(x), zson = whoson(y);
  int B = tree[x].ch[yson ^ 1];
  Connect(B, y, yson);
  Connect(y, x, yson ^ 1);
  tree[x].fa = z;
  if (tree[y].aus)
    tree[z].ch[zson] = x;
  else
    swap(tree[y].aus, tree[x].aus);
  push_up(y);
  push_up(x);
}
void push_down(int x) {
  if (tree[x].rev) {
    int l = tree[x].ch[0], r = tree[x].ch[1];
    swap(tree[x].ch[0], tree[x].ch[1]);
    tree[l].rev ^= 1, tree[r].rev ^= 1;
    tree[x].rev = 0;
  }
}
void Splay(int x) {
  push_down(x);
  while (tree[x].aus) {
    int y = tree[x].fa, z = tree[y].fa;
    if (tree[y].aus) push_down(z);
    push_down(y);
    push_down(x);
    if (tree[y].aus) {
      if (whoson(x) ^ whoson(y))
        rotate(x);
      else
        rotate(y);
    }
    rotate(x);
  }
}
void Access(int x) {
  int y = 0;
  while (x) {
    Splay(x);
    tree[tree[x].ch[1]].aus = 0;
    tree[x].ch[1] = 0;
    tree[x].ch[1] = y;
    tree[y].aus = 1;
    tree[y].fa = x;
    push_up(x);
    y = x, x = tree[x].fa;
  }
}
void Evert(int x) {
  Access(x);
  Splay(x);
  tree[x].rev ^= 1;
}
void Link(int x, int y) {
  Evert(x);
  tree[x].fa = y;
}
void Cut(int x, int y) {
  Evert(x);
  Access(y);
  Splay(x);
  if (tree[x].ch[1] != y) return;
  tree[x].ch[1] = 0;
  tree[y].aus = 0;
  tree[y].fa = 0;
  push_up(x);
}
int n, prt[500005], rd[500005];
void dfs(int x, int fa) {
  prt[x] = fa;
  for (int i = h[x]; i; i = w[i].next) {
    int to = w[i].to;
    if (to == fa) continue;
    dfs(to, x);
  }
}
int find(int x) {
  push_down(x);
  if (tree[tree[x].ch[0]].size)
    return find(tree[x].ch[0]);
  else {
    if (tree[x].v) return x;
    return find(tree[x].ch[1]);
  }
}
int main() {
  n = read();
  tot = n;
  for (int i = 1; i < n; i++)
    a[i].x = read(), a[i].y = read(), add(a[i].x, a[i].y), add(a[i].y, a[i].x);
  for (int i = 1; i < n; i++) b[i].x = read(), b[i].y = read();
  for (int i = 1; i < n; i++) {
    tot++;
    tree[tot].v = tree[tot].size = 1;
    int x = b[i].x, y = b[i].y;
    Link(x, tot);
    Link(y, tot);
  }
  dfs(1, 0);
  for (int i = 2; i <= n; i++) rd[prt[i]]++;
  queue<int> q;
  for (int i = 1; i <= n; i++)
    if (!rd[i]) q.push(i);
  printf("%d\n", n - 1);
  for (int i = 1; i < n; i++) {
    int x = q.front();
    q.pop();
    if (!(--rd[prt[x]])) q.push(prt[x]);
    Evert(x);
    Access(prt[x]);
    Splay(x);
    int z = find(tree[x].ch[1]);
    printf("%d %d %d %d\n", x, prt[x], b[z - n].x, b[z - n].y);
    Cut(b[z - n].x, z);
    Cut(b[z - n].y, z);
    tot++;
    Link(x, tot);
    Link(prt[x], tot);
  }
}
