#include <bits/stdc++.h>
using namespace std;
bool SR(int &x) { return scanf("%d", &x) == 1; }
bool SR(long long &x) { return scanf("%lld", &x) == 1; }
bool SR(double &x) { return scanf("%lf", &x) == 1; }
bool SR(char *s) { return scanf("%s", s) == 1; }
bool RI() { return true; }
template <typename I, typename... T>
bool RI(I &x, T &...tail) {
  return SR(x) && RI(tail...);
}
void SP(const int x) { printf("%d", x); }
void SP(const long long x) { printf("%lld", x); }
void SP(const double x) { printf("%.16lf", x); }
void SP(const char *s) { printf("%s", s); }
void PL() { puts(""); }
template <typename I, typename... T>
void PL(const I x, const T... tail) {
  SP(x);
  if (sizeof...(tail)) putchar(' ');
  PL(tail...);
}
const int maxn = 5e5 + 5;
vector<int> e[2][maxn];
int n;
void read() {
  RI(n);
  for (int r = 0; r < int(2); r++)
    for (int i = 0; i < int(n - 1); i++) {
      int a, b;
      RI(a, b);
      e[r][a].push_back(b);
      e[r][b].push_back(a);
    }
}
int par[2][maxn];
void dfs1(int r, int u, int p) {
  par[r][u] = p;
  for (auto v : e[r][u])
    if (v != p) dfs1(r, v, u);
}
bool chk(int u, int v) {
  if (!u || !v) return 0;
  return par[0][u] == v || par[0][v] == u;
}
vector<array<int, 4> > ans;
int s[maxn];
int find(int x) { return x == s[x] ? x : s[x] = find(s[x]); }
void dfs2(int u) {
  for (auto v : e[0][u])
    if (v != par[0][u]) {
      dfs2(v);
      if (par[1][u] == v || par[1][v] == u) continue;
      int p = find(v);
      ans.push_back({u, v, p, par[1][p]});
    }
}
void build() {
  dfs1(1, 1, 0);
  dfs1(0, 1, 0);
  for (int i = (1); i <= int(n); i++) s[i] = chk(i, par[1][i]) ? par[1][i] : i;
  dfs2(1);
}
void sol() {
  PL(((int)(ans).size()));
  for (auto p : ans)
    for (int i = 0; i < int(4); i++) printf("%d%c", p[i], " \n"[i == 3]);
}
int main() {
  read();
  build();
  sol();
  return 0;
}
