#include <bits/stdc++.h>
using namespace std;
namespace thecold {
inline int read() {
  int res = 0;
  bool flag = false;
  char c = getchar();
  while (!isdigit(c)) flag = (c == '-'), c = getchar();
  while (isdigit(c)) res = res * 10 + (c ^ 48), c = getchar();
  return !flag ? res : -res;
}
const int Max_n = 3e5 + 5;
struct node {
  int to, ty;
  node(int a, int b) { to = a, ty = b; }
  node() {}
};
vector<node> v[2][Max_n];
int fa[20][Max_n], logm[Max_n], n, bcj[Max_n], d[Max_n], dep[Max_n], tot,
    fty[Max_n];
inline void add_edge(const int x, const int y, const int ty) {
  v[ty][x].push_back(node(y, 0));
  v[ty][y].push_back(node(x, 1));
}
void dfs_tree(const int now, const int from, const int ty) {
  fa[0][now] = from, dep[now] = dep[from] + 1;
  for (int i = 1; i <= 18; ++i) fa[i][now] = fa[i - 1][fa[i - 1][now]];
  int sz = v[ty][now].size();
  for (int i = 0; i < sz; ++i) {
    int nex = v[ty][now][i].to;
    if (nex ^ from)
      dfs_tree(nex, now, ty);
    else
      fty[now] = v[ty][now][i].ty;
  }
}
int find(const int x) { return bcj[x] == x ? x : bcj[x] = find(bcj[x]); }
inline void merge(const int x, const int y) { bcj[find(x)] = find(y); }
queue<int> zzz;
bool vis[Max_n];
struct Node {
  int ai, bi, ci, di;
  Node(int a, int b, int c, int d, int ty1, int ty2) {
    ai = a, bi = b, ci = c, di = d;
    if (ty1) swap(ai, bi);
    if (ty2) swap(ci, di);
  }
  Node() {}
  inline void print() { printf("%d %d %d %d\n", ci, di, ai, bi); }
} ans[Max_n];
inline int lca(int x, int y) {
  if (dep[y] > dep[x]) swap(x, y);
  while (dep[x] > dep[y]) x = fa[logm[dep[x] - dep[y]]][x];
  if (x == y) return x;
  for (int i = 18; ~i; --i)
    if (fa[i][x] != fa[i][y]) x = fa[i][x], y = fa[i][y];
  return fa[0][x];
}
inline void solve(const int now, const int nex, const int ty) {
  int bel = find(now), l = lca(now, nex);
  if (dep[bel] > dep[l]) {
    ans[++tot] = Node(now, nex, bel, fa[0][bel], ty, fty[bel]);
    merge(now, fa[0][bel]);
  } else {
    int pos = nex;
    for (int i = 18; ~i; --i)
      if (fa[i][pos])
        if (dep[find(fa[i][pos])] > dep[l]) pos = fa[i][pos];
    ans[++tot] = Node(now, nex, pos, fa[0][pos], ty, fty[pos]);
    merge(pos, fa[0][pos]);
  }
}
int ai[Max_n], bi[Max_n], ci[Max_n], di[Max_n];
inline void main() {
  n = read();
  for (int i = 1; i < n; ++i) {
    ai[i] = read(), bi[i] = read();
    add_edge(ai[i], bi[i], 0);
  }
  for (int i = 1; i < n; ++i) {
    ci[i] = read(), di[i] = read();
    add_edge(ci[i], di[i], 1);
    ++d[ci[i]], ++d[di[i]];
  }
  for (int i = 2; i <= n; ++i) logm[i] = logm[i >> 1] + 1;
  dfs_tree(1, 0, 0);
  for (int i = 1; i <= n; ++i) bcj[i] = i;
  for (int i = 1; i <= n; ++i)
    if (d[i] == 1) zzz.push(i);
  int cnt = n - 1;
  printf("%d\n", cnt);
  while (cnt--) {
    int now = zzz.front();
    zzz.pop();
    vis[now] = true;
    int sz = v[1][now].size();
    for (int i = 0; i < sz; ++i)
      if (!vis[v[1][now][i].to]) {
        int nex = v[1][now][i].to;
        if (--d[nex] == 1) zzz.push(nex);
        solve(now, nex, v[1][now][i].ty);
      }
  }
  for (int i = 1; i < n; ++i) ans[i].print();
}
}  // namespace thecold
int main() {
  thecold::main();
  return 0;
}
