#include <bits/stdc++.h>
using namespace std;
using namespace std;
bool solve(int);
int main() {
  int test = 0;
  while (solve(test++))
    ;
  return 0;
}
const int N = 500 * 1000 + 5;
int n;
pair<int, int> s[N + N];
int nxt[N + N];
vector<int> g[N];
int e[N], el[N];
set<pair<int, int> > good, bad;
int dsu[N], rk[N], lead[N];
void init(int n) {
  for (int i = 0; i < int(n); ++i) dsu[i] = i, rk[i] = 0, lead[i] = i;
}
int getp(int v) { return dsu[v] == v ? v : (dsu[v] = getp(dsu[v])); }
void unite(int a, int b, int l) {
  a = getp(a), b = getp(b);
  if (a == b) {
    lead[a] = l;
    return;
  }
  if (rk[a] < rk[b]) swap(a, b);
  dsu[b] = a;
  rk[a] += rk[a] == rk[b];
  lead[a] = l;
}
int c[N], p[N];
bool ind[N];
bool fast[N];
void dfs0(int v, int p = -1) {
  ::p[v] = p;
  for (auto to : g[v])
    if (to != p) dfs0(to, v);
}
void dfs(int v, int p = -1) {
  ::p[v] = p;
  c[v] = 0;
  ind[v] = true;
  for (auto to : g[v]) {
    if (to == p) continue;
    dfs(to, v);
    c[v]++;
  }
}
void unite(int a, int b) {
  if (e[b] == -1) return;
  nxt[el[b]] = e[a];
  e[a] = e[b];
  if (el[a] == -1) el[a] = el[b];
}
bool solve(int) {
  if (scanf("%d", &n) != 1) return false;
  for (int i = 0; i < int(n); ++i) {
    e[i] = -1;
    el[i] = -1;
    g[i].clear();
    fast[i] = false;
  }
  good.clear();
  int res = 0;
  for (int t = 0; t < int(2); ++t) {
    for (int i = 0; i < int(n - 1); ++i) {
      int u, v;
      assert(scanf("%d%d", &u, &v) == 2);
      --u, --v;
      if (t) {
        if (p[v] != u && p[u] != v) {
          s[i * 2 + 1] = make_pair(v, u);
          s[i * 2 + 2] = make_pair(u, v);
          nxt[i * 2 + 1] = e[u];
          e[u] = i * 2 + 1;
          nxt[i * 2 + 2] = e[v];
          e[v] = i * 2 + 2;
          if (el[u] == -1) el[u] = i * 2 + 1;
          if (el[v] == -1) el[v] = i * 2 + 2;
          res++;
        } else {
          if (p[v] == u)
            fast[v] = true;
          else
            fast[u] = true;
        }
      } else
        g[u].push_back(v), g[v].push_back(u);
    }
    if (!t) dfs0(0);
  }
  bad.clear();
  cout << res << endl;
  init(n);
  dfs(0);
  good.clear();
  for (int i = 0; i < int(n); ++i) {
    g[i].clear();
    g[i].shrink_to_fit();
  }
  queue<int> q;
  for (int i = 0; i < int(n); ++i)
    if (c[i] == 0) q.push(i);
  while (!q.empty()) {
    int v = q.front();
    q.pop();
    if (fast[v]) {
      assert(ind[p[v]]);
      unite(v, p[v], p[v]);
      unite(p[v], v);
      c[p[v]]--;
      if (c[p[v]] == 0) q.push(p[v]);
      ind[v] = false;
      continue;
    }
    while (e[v] != -1) {
      pair<int, int> p = s[e[v]];
      e[v] = nxt[e[v]];
      assert(lead[getp(p.second)] == v);
      if (lead[getp(p.first)] == v) continue;
      int pp = ::p[v];
      printf("%d %d %d %d\n", pp + 1, v + 1, p.first + 1, p.second + 1);
      c[pp]--;
      assert(ind[pp]);
      if (c[pp] == 0) q.push(pp);
      ind[v] = false;
      int np = lead[getp(p.first)];
      unite(v, np, np);
      unite(np, v);
      break;
    }
  }
  for (int i = 0; i < int(n); ++i) assert(c[i] == 0);
  return true;
}
