#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline bool chkmax(T &x, const T &y) {
  return x < y ? x = y, 1 : 0;
}
template <typename T>
inline bool chkmin(T &x, const T &y) {
  return x > y ? x = y, 1 : 0;
}
template <typename T>
inline T geti() {
  register T xi = 0;
  register char ch = getchar();
  bool f = 0;
  while (!isdigit(ch)) ch == '-' ? f = 1 : f, ch = getchar();
  while (isdigit(ch)) xi = xi * 10 + ch - 48, ch = getchar();
  return f ? -xi : xi;
}
template <typename T>
inline void pi(T k, char ch = 0) {
  if (k < 0) k = -k, putchar('-');
  if (k >= 10) pi(k / 10);
  putchar(k % 10 + '0');
  if (ch) putchar(ch);
}
const int N = 5e5 + 7;
struct data {
  int u, v, x, y;
};
vector<data> ans;
struct Tree {
  struct edge {
    int v, nxt;
  } e[N << 1];
  int head[N], cnt, fa[N];
  inline void add(int u, int v) {
    e[++cnt] = (edge){v, head[u]}, head[u] = cnt;
  }
  inline void init() { memset(head, cnt = -1, sizeof head); }
  Tree() { init(); }
  inline void dfs(int x, int f = 0) {
    fa[x] = f;
    for (int i = head[x], v; ~i && (v = e[i].v); i = e[i].nxt)
      if (v != f) dfs(v, x);
  }
} T1, T2;
int fa[N];
int find(int x) { return x == fa[x] ? x : (fa[x] = find(fa[x])); }
inline void solve(int x) {
  for (int i = T1.head[x], v; ~i && (v = T1.e[i].v); i = T1.e[i].nxt)
    if (v != T1.fa[x]) {
      solve(v);
      if (x != T2.fa[v] && v != T2.fa[x])
        ans.push_back((data){v, x, find(v), T2.fa[find(v)]});
    }
}
int n;
int main(void) {
  n = geti<int>();
  for (int i = 1; i < n; ++i) {
    int u = geti<int>(), v = geti<int>();
    T1.add(u, v), T1.add(v, u);
  }
  for (int i = 1; i < n; ++i) {
    int u = geti<int>(), v = geti<int>();
    T2.add(u, v), T2.add(v, u);
  }
  T1.dfs(1), T2.dfs(1);
  for (int i = 2; i <= n; ++i) {
    int u = T2.fa[i];
    if (u == T1.fa[i] || i == T1.fa[u])
      fa[i] = u;
    else
      fa[i] = i;
  }
  solve(1);
  pi(ans.size(), '\n');
  for (auto i : ans) printf("%d %d %d %d\n", i.u, i.v, i.x, i.y);
  return 0;
}
