#include <bits/stdc++.h>
using namespace std;
const int oo = 2139063143;
const int N = 2010000;
const int P = 1000000007;
const double eps = 1e-7;
template <typename T>
inline void sc(T &x) {
  x = 0;
  static int p;
  p = 1;
  static char c;
  c = getchar();
  while (!isdigit(c)) {
    if (c == '-') p = -1;
    c = getchar();
  }
  while (isdigit(c)) {
    x = (x << 1) + (x << 3) + (c - 48);
    c = getchar();
  }
  x *= p;
}
template <typename T>
inline void print(T x) {
  if (x < 0) putchar('-'), x = -x;
  if (x >= 10) print(x / 10);
  putchar(x % 10 + '0');
}
template <typename T>
inline void pr(T x) {
  print(x), putchar('\n');
}
template <typename T1, typename T2>
void chkmax(T1 &A, T2 B) {
  A = A >= B ? A : B;
}
template <typename T1, typename T2>
void chkmin(T1 &A, T2 B) {
  A = A <= B ? A : B;
}
int n;
struct LY {
  int x, y, w;
} a[N];
struct LCT {
  struct lct {
    int fa, son[2], pos;
    bool rev;
  } t[N];
  bool notroot(int p) {
    return t[t[p].fa].son[0] == p || t[t[p].fa].son[1] == p;
  }
  void pushrev(int p) { t[p].rev ^= 1, swap(t[p].son[0], t[p].son[1]); }
  void push(int p) {
    if (t[p].rev) {
      int ls = t[p].son[0], rs = t[p].son[1];
      if (ls) pushrev(ls);
      if (rs) pushrev(rs);
      t[p].rev = 0;
    }
  }
  void update(int p) {
    t[p].pos = p;
    int ls = t[p].son[0], rs = t[p].son[1];
    if (ls && a[t[ls].pos].w < a[t[p].pos].w) t[p].pos = t[ls].pos;
    if (rs && a[t[rs].pos].w < a[t[p].pos].w) t[p].pos = t[rs].pos;
  }
  int get(int p) { return t[t[p].fa].son[1] == p; }
  void rotate(int p) {
    int s = get(p), f = t[p].fa, ff = t[f].fa;
    t[f].son[s] = t[p].son[s ^ 1];
    if (t[f].son[s]) t[t[f].son[s]].fa = f;
    if (notroot(f)) t[ff].son[get(f)] = p;
    t[p].fa = ff;
    t[p].son[s ^ 1] = f, t[f].fa = p;
    update(f), update(p);
  }
  int st[N], z = 0;
  void splay(int p) {
    int y = p;
    st[z = 1] = y;
    while (notroot(y)) st[++z] = y = t[y].fa;
    while (z) push(st[z]), --z;
    while (notroot(p)) {
      int f = t[p].fa;
      if (notroot(f)) rotate(get(f) == get(p) ? f : p);
      rotate(p);
    }
  }
  void access(int p) {
    for (int y = 0; p; y = p, p = t[p].fa) splay(p), t[p].son[1] = y, update(p);
  }
  void makeroot(int p) {
    access(p);
    splay(p);
    pushrev(p);
  }
  int findroot(int p) {
    access(p), splay(p);
    while (t[p].son[0]) push(p), p = t[p].son[0];
    splay(p);
    return p;
  }
  void split(int x, int y) {
    makeroot(y);
    access(x), splay(x);
  }
  void link(int x, int y) {
    makeroot(y);
    t[y].fa = x;
  }
  void cut(int x, int y) {
    split(x, y);
    t[y].fa = t[x].son[0] = 0;
    update(x);
  }
  void init() {
    for (int i = 1; i <= n * 3; i++) t[i].pos = i;
  }
} T;
map<int, bool> us[N];
int main() {
  sc(n);
  for (int i = n + 1; i < n * 2; i++) {
    sc(a[i].x), sc(a[i].y), a[i].w = 0;
    if (a[i].x > a[i].y) swap(a[i].x, a[i].y);
  }
  for (int i = n * 2 + 1; i < n * 3; i++) {
    sc(a[i].x), sc(a[i].y), a[i].w = 1;
    if (a[i].x > a[i].y) swap(a[i].x, a[i].y);
    us[a[i].x][a[i].y] = 1;
  }
  for (int i = 1; i <= n; i++) a[i].w = 1;
  T.init();
  int ans = n - 1;
  for (int i = n + 1; i < n * 2; i++) {
    if (us[a[i].x].count(a[i].y)) a[i].w = 1, --ans;
    T.link(a[i].x, i), T.link(a[i].y, i);
  }
  pr(ans);
  for (int i = n * 2 + 1; i < n * 3; i++) {
    int x = a[i].x, y = a[i].y;
    T.split(x, y);
    int id = T.t[x].pos;
    if (a[id].w) continue;
    T.cut(a[id].x, id);
    T.cut(a[id].y, id);
    printf("%d %d %d %d\n", a[id].x, a[id].y, x, y);
    T.link(x, i), T.link(y, i);
  }
  return 0;
}
