#include <bits/stdc++.h>
using namespace std;
template <typename T, class F = function<T(const T&, const T&)>>
class SparseTable {
 public:
  int n;
  vector<vector<T>> mat;
  F func;
  SparseTable(const vector<T>& a, const F& f) : func(f) {
    n = static_cast<int>(a.size());
    int max_log = 32 - __builtin_clz(n);
    mat.resize(max_log);
    mat[0] = a;
    for (int j = 1; j < max_log; j++) {
      mat[j].resize(n - (1 << j) + 1);
      for (int i = 0; i <= n - (1 << j); i++) {
        mat[j][i] = func(mat[j - 1][i], mat[j - 1][i + (1 << (j - 1))]);
      }
    }
  }
  T get(int from, int to) const {
    assert(0 <= from && from <= to && to <= n - 1);
    int lg = 32 - __builtin_clz(to - from + 1) - 1;
    return func(mat[lg][from], mat[lg][to - (1 << lg) + 1]);
  }
};
class dsu {
 public:
  vector<int> p;
  int n;
  dsu(int _n) : n(_n) {
    p.resize(n);
    iota(p.begin(), p.end(), 0);
  }
  inline int get(int x) { return (x == p[x] ? x : (p[x] = get(p[x]))); }
  inline bool unite(int x, int y) {
    x = get(x);
    y = get(y);
    if (x != y) {
      p[x] = y;
      return true;
    }
    return false;
  }
};
int n;
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  cin >> n;
  vector<vector<int>> a(n);
  vector<vector<int>> b(n);
  for (int i = 0; i < n - 1; i++) {
    int u, v;
    cin >> u >> v;
    u--;
    v--;
    a[u].push_back(v);
    a[v].push_back(u);
  }
  for (int i = 0; i < n - 1; i++) {
    int u, v;
    cin >> u >> v;
    u--;
    v--;
    b[u].push_back(v);
    b[v].push_back(u);
  }
  const int MAX = 20;
  vector<int> in(n);
  vector<int> out(n);
  vector<int> dep(n);
  vector<int> tour;
  vector<vector<int>> par(n, vector<int>(MAX));
  function<void(int, int)> dfs = [&](int v, int p) {
    par[v][0] = p;
    if (~p) dep[v] = dep[p] + 1;
    in[v] = tour.size();
    tour.push_back(v);
    for (int i : a[v]) {
      if (i == p) continue;
      dfs(i, v);
      tour.push_back(v);
    }
    out[v] = tour.size() - 1;
  };
  dfs(0, -1);
  for (int i = 1; i < MAX; i++) {
    for (int j = 0; j < n; j++) {
      if (par[j][i - 1] == -1)
        par[j][i] = -1;
      else
        par[j][i] = par[par[j][i - 1]][i - 1];
    }
  }
  SparseTable<int> sp(tour, [&](int i, int j) {
    return (dep[i] == dep[j] ? min(i, j) : (dep[i] < dep[j] ? i : j));
  });
  auto p = [&](int i, int j) {
    return sp.get(min(in[i], in[j]), max(out[i], out[j]));
  };
  dsu st(n);
  vector<int> que;
  vector<int> pb(n);
  que.push_back(0);
  pb[0] = -1;
  for (int z = 0; z < (int)que.size(); z++) {
    int c = que[z];
    for (int i : b[c]) {
      if (i == pb[c]) continue;
      que.push_back(i);
      pb[i] = c;
    }
  }
  reverse(que.begin(), que.end());
  que.pop_back();
  vector<vector<int>> res;
  for (int u : que) {
    int v = pb[u];
    int z = p(u, v);
    int t = st.get(u);
    for (int rot = 0; rot < 2; rot++) {
      int dis = u;
      for (int i = MAX - 1; i > -1; i--) {
        if (par[u][i] == -1 || dep[par[u][i]] < dep[z]) continue;
        if ((st.get(par[u][i]) == t) ^ rot) u = par[u][i];
      }
      if (u != z) {
        res.push_back({u, par[u][0], dis, v});
        st.unite(u, par[u][0]);
        break;
      } else
        u = dis;
      swap(u, v);
    }
  }
  cout << n - 1 << endl;
  for (auto u : res) {
    for (int i : u) cout << i + 1 << " ";
    cout << endl;
  }
  return 0;
}
