#include <bits/stdc++.h>
using namespace std;
template <typename TYPE>
inline void chkmax(TYPE &first, TYPE second) {
  first < second ? first = second : 0;
}
template <typename TYPE>
inline void chkmin(TYPE &first, TYPE second) {
  second < first ? first = second : 0;
}
template <typename TYPE>
void readint(TYPE &first) {
  first = 0;
  int f = 1;
  char c;
  for (c = getchar(); !isdigit(c); c = getchar())
    if (c == '-') f = -1;
  for (; isdigit(c); c = getchar()) first = first * 10 + c - '0';
  first *= f;
}
const int MAXN = 250005;
int n;
vector<int> G[MAXN];
int size[MAXN], dfn[MAXN], dfn_cnt, q[MAXN], pa[MAXN];
void dfs(int u) {
  q[dfn[u] = ++dfn_cnt] = u;
  size[u] = 1;
  for (auto v : G[u]) {
    if (v == pa[u]) continue;
    pa[v] = u;
    dfs(v);
    size[u] += size[v];
  }
}
namespace LCT {
int ch[MAXN][2], fa[MAXN], rev[MAXN], Min[MAXN], Max[MAXN];
bool nroot(int first) {
  return ch[fa[first]][0] == first || ch[fa[first]][1] == first;
}
bool sonr(int first) { return ch[fa[first]][1] == first; }
void reverse(int first) {
  rev[first] ^= 1;
  swap(ch[first][0], ch[first][1]);
}
void pushdown(int first) {
  if (rev[first]) reverse(ch[first][0]), reverse(ch[first][1]), rev[first] = 0;
}
void update(int first) {
  Min[first] = min(min(Min[ch[first][0]], Min[ch[first][1]]), dfn[first]);
  Max[first] = max(max(Max[ch[first][0]], Max[ch[first][1]]), dfn[first]);
}
void pushall(int first) {
  if (nroot(first)) pushall(fa[first]);
  pushdown(first);
}
void rotate(int first) {
  int second = fa[first], z = fa[second], ty = sonr(first),
      s = ch[first][ty ^ 1];
  if (nroot(second)) ch[z][sonr(second)] = first;
  ch[first][ty ^ 1] = second, ch[second][ty] = s;
  fa[first] = z, fa[second] = first;
  if (s) fa[s] = second;
  update(second), update(first);
}
void splay(int first) {
  pushall(first);
  while (nroot(first))
    if (!nroot(fa[first]))
      rotate(first);
    else if (sonr(first) == sonr(fa[first]))
      rotate(fa[first]), rotate(first);
    else
      rotate(first), rotate(first);
}
void access(int first) {
  for (int second = 0; first; first = fa[second = first])
    splay(first), ch[first][1] = second, update(first);
}
void makeroot(int first) { access(first), splay(first), reverse(first); }
void link(int first, int second) {
  makeroot(first);
  makeroot(second);
  if (fa[first]) return;
  fa[first] = second;
}
void cut(int first, int second) {
  makeroot(first), access(second), splay(first);
  if (fa[second] != first) return;
  fa[second] = ch[first][sonr(second)] = 0;
  update(first);
}
int findfir(int u, int l, int r) {
  pushdown(u);
  if (Min[ch[u][0]] < l || Max[ch[u][0]] > r) return findfir(ch[u][0], l, r);
  if (dfn[u] < l || dfn[u] > r) return u;
  return findfir(ch[u][1], l, r);
}
};  // namespace LCT
int main() {
  LCT::Min[0] = 1 << 30;
  int u, v;
  readint(n);
  for (int i = 1; i < n; ++i) {
    readint(u), readint(v);
    G[u].push_back(v), G[v].push_back(u);
  }
  dfs(1);
  for (int i = 1; i <= n; ++i) LCT::Min[i] = LCT::Max[i] = dfn[i];
  for (int i = 1; i < n; ++i) {
    readint(u), readint(v);
    LCT::link(u, v);
  }
  printf("%d\n", n - 1);
  for (int i = n; i > 1; --i) {
    u = q[i];
    LCT::makeroot(u);
    LCT::access(pa[u]);
    LCT::splay(u);
    int first = LCT::findfir(u, dfn[u], dfn[u] + size[u] - 1), second;
    LCT::access(first);
    LCT::splay(first);
    LCT::pushdown(first);
    for (second = LCT::ch[first][0]; LCT::ch[second][1];
         second = LCT::ch[second][1])
      LCT::pushdown(second);
    LCT::cut(first, second);
    LCT::link(u, pa[u]);
    printf("%d %d %d %d\n", u, pa[u], first, second);
  }
  return 0;
}
