#include <bits/stdc++.h>
using namespace std;
const int MaxN = 500005;
struct ufset {
  int pa[MaxN];
  void Init() {
    for (int i = 0; i < MaxN; ++i) pa[i] = i;
  }
  int Find(int x) { return x == pa[x] ? x : pa[x] = Find(pa[x]); }
} uf;
struct State {
  int a, b, c, d;
};
int n, fa[2][MaxN];
vector<State> ans;
vector<int> G[2][MaxN];
template <typename T>
void Exit(const T &code) {
  cout << code << endl;
  exit(0);
}
void dfs(int l, int x, int f = -1) {
  for (std::vector<int>::iterator it = G[l][x].begin(); it != G[l][x].end();
       ++it) {
    int nxt = *it;
    if (nxt == f) continue;
    fa[l][nxt] = x;
    dfs(l, nxt, x);
  }
}
void Init() {
  uf.Init();
  ios::sync_with_stdio(false);
  cin >> n;
  for (int i = 0; i < n - 1; ++i) {
    int u, v;
    cin >> u >> v;
    G[0][u].push_back(v);
    G[0][v].push_back(u);
  }
  dfs(0, 1);
  for (int i = 0; i < n - 1; ++i) {
    int u, v;
    cin >> u >> v;
    G[1][u].push_back(v);
    G[1][v].push_back(u);
  }
  dfs(1, 1);
}
void dfs1(int x, int f = -1) {
  for (std::vector<int>::iterator it = G[0][x].begin(); it != G[0][x].end();
       ++it) {
    int nxt = *it;
    if (nxt == f) continue;
    dfs1(nxt, x);
    if (fa[1][x] != nxt && fa[1][nxt] != x)
      ans.push_back((State){x, nxt, uf.Find(nxt), fa[1][uf.Find(nxt)]});
  }
}
void Main() {
  for (int i = 1; i <= n; ++i) {
    int u = fa[1][i];
    if (fa[0][u] == i || fa[0][i] == u) uf.pa[i] = u;
  }
  dfs1(1);
  cout << ans.size() << endl;
  for (std::vector<State>::iterator it = ans.begin(); it != ans.end(); ++it)
    cout << it->a << ' ' << it->b << ' ' << it->c << ' ' << it->d << endl;
}
int main() {
  Init();
  Main();
  return 0;
}
