#include <bits/stdc++.h>
using namespace std;
long long gcd(long long a, long long b) { return b == 0 ? a : gcd(b, a % b); }
const int MAXN = 250000;
const int MAXLG = 17;
int n;
vector<int> adj1[MAXN];
vector<int> adj2[MAXN];
vector<pair<pair<int, int>, pair<int, int>>> ans;
int deg2[MAXN];
bool done[MAXN];
queue<int> q2;
int dep1[MAXN];
int par1[MAXN];
int up1[MAXN][MAXLG + 1];
int ufpar[MAXN], ufsz[MAXN];
int uffind(int x) {
  if (ufpar[x] == x) return x;
  return ufpar[x] = uffind(ufpar[x]);
}
void ufunite(int x, int y) {
  x = uffind(x);
  y = uffind(y);
  if (x == y) return;
  if (ufsz[x] < ufsz[y]) swap(x, y);
  ufpar[y] = x, ufsz[x] += ufsz[y];
}
void dfs1(int at) {
  dep1[at] = par1[at] == -1 ? 0 : dep1[par1[at]] + 1;
  up1[at][0] = par1[at] == -1 ? at : par1[at];
  for (int k = (0); k < (MAXLG); ++k) up1[at][k + 1] = up1[up1[at][k]][k];
  for (int i = (0); i < (((int)(adj1[at]).size())); ++i) {
    int to = adj1[at][i];
    if (to == par1[at]) continue;
    par1[to] = at;
    dfs1(to);
  }
}
int lca1(int a, int b) {
  if (dep1[a] < dep1[b]) swap(a, b);
  for (int k = MAXLG; k >= 0; --k)
    if (dep1[a] - (1 << k) >= dep1[b]) a = up1[a][k];
  if (a == b) return a;
  for (int k = MAXLG; k >= 0; --k)
    if (up1[a][k] != up1[b][k]) a = up1[a][k], b = up1[b][k];
  return par1[a];
}
pair<int, int> findedgeup(int a, int b) {
  for (int k = MAXLG; k >= 0; --k)
    if (dep1[a] - (1 << k) >= dep1[b]) {
      int c = up1[a][k];
      if (uffind(a) != uffind(c))
        b = c;
      else
        a = c;
    }
  return make_pair(a, par1[a]);
}
pair<int, int> findedgedown(int a, int b) {
  for (int k = MAXLG; k >= 0; --k)
    if (dep1[b] - (1 << k) >= dep1[a]) {
      int c = up1[b][k];
      if (uffind(a) != uffind(c))
        b = c;
      else
        a = c;
    }
  return make_pair(b, par1[b]);
}
pair<int, int> findedgeonpath(int a, int b) {
  assert(uffind(a) != uffind(b));
  int c = lca1(a, b);
  if (uffind(a) != uffind(c))
    return findedgeup(a, c);
  else
    return findedgedown(c, b);
}
void solve() {
  par1[0] = -1;
  dfs1(0);
  for (int i = (0); i < (n); ++i) ufpar[i] = i, ufsz[i] = 1;
  for (int i = (0); i < (n); ++i) deg2[i] = ((int)(adj2[i]).size());
  for (int i = (0); i < (n); ++i) done[i] = false;
  q2 = queue<int>();
  for (int i = (0); i < (n); ++i)
    if (deg2[i] <= 1) q2.push(i);
  ans.clear();
  while (!q2.empty()) {
    int at = q2.front();
    q2.pop();
    done[at] = true;
    int to = -1;
    for (int i = (0); i < (((int)(adj2[at]).size())); ++i) {
      int cur = adj2[at][i];
      if (done[cur]) continue;
      assert(to == -1);
      to = cur;
    }
    if (to == -1) break;
    pair<int, int> edge = findedgeonpath(at, to);
    ans.push_back(make_pair(edge, make_pair(at, to)));
    ufunite(edge.first, edge.second);
    if (--deg2[to] == 1) q2.push(to);
  }
  assert(((int)(ans).size()) == n - 1);
}
void run() {
  scanf("%d", &n);
  for (int i = (0); i < (n - 1); ++i) {
    int a, b;
    scanf("%d%d", &a, &b);
    --a, --b;
    adj1[a].push_back(b);
    adj1[b].push_back(a);
  }
  for (int i = (0); i < (n - 1); ++i) {
    int a, b;
    scanf("%d%d", &a, &b);
    --a, --b;
    adj2[a].push_back(b);
    adj2[b].push_back(a);
  }
  solve();
  printf("%d\n", ((int)(ans).size()));
  for (int i = (0); i < (((int)(ans).size())); ++i)
    printf("%d %d %d %d\n", ans[i].first.first + 1, ans[i].first.second + 1,
           ans[i].second.first + 1, ans[i].second.second + 1);
}
int main() {
  run();
  return 0;
}
