#include <bits/stdc++.h>
template <class T>
inline void chkmax(T &x, const T &y) {
  if (x < y) x = y;
}
template <class T>
inline void chkmin(T &x, const T &y) {
  if (x > y) x = y;
}
template <class T>
inline void read(T &x) {
  char c;
  int f = 1;
  x = 0;
  while (((c = getchar()) < '0' || c > '9') && c != '-')
    ;
  if (c == '-')
    f = -1;
  else
    x = c - '0';
  while ((c = getchar()) >= '0' && c <= '9') x = x * 10 + c - '0';
  x *= f;
}
int outn;
char out[(int)2e7];
template <class T>
inline void write(T x) {
  if (x < 0) out[outn++] = '-', x = -x;
  if (x) {
    static int tmpn;
    static char tmp[20];
    tmpn = 0;
    while (x) tmp[tmpn++] = x % 10 + '0', x /= 10;
    while (tmpn) out[outn++] = tmp[--tmpn];
  } else
    out[outn++] = '0';
}
const int N = 5e5;
int n;
std::pair<int, int> alle[N * 2 + 9];
struct edge {
  int v, id;
  edge() { v = id = 0; }
  edge(int _v, int _id) : v(_v), id(_id) {}
};
std::vector<edge> g[N + 9], h[N + 9];
struct data {
  int u, v, id;
  data() { u = v = id = 0; }
  data(int _u, int _v, int _id) : u(_u), v(_v), id(_id) {}
  inline friend bool operator<(const data &p, const data &q) {
    return p.u < q.u || (p.u == q.u && p.v < q.v);
  }
} e[N * 2 + 9];
bool add[N * 2 + 9], rem[N * 2 + 9], done[N * 2 + 9];
int fa[N + 9];
inline int find(int x) {
  int anc = x, y;
  while (anc != fa[anc]) anc = fa[anc];
  while (x != anc) y = fa[x], fa[x] = anc, x = y;
  return anc;
}
inline void merge(int u, int v) {
  u = find(u), v = find(v);
  if (u == v) return;
  fa[u] = v;
  if ((int)(h[u]).size() > (int)(h[v]).size()) std::swap(h[u], h[v]);
  while (!h[u].empty()) {
    h[v].push_back(h[u].back());
    h[u].pop_back();
  }
}
void dfs(int now, int fa) {
  for (int i = 0, to; i < (int)(g[now]).size(); ++i)
    if ((to = g[now][i].v) != fa) {
      dfs(to, now);
      if (!rem[g[now][i].id]) {
        merge(to, now);
        continue;
      }
      edge t = h[to].back();
      while (done[t.id]) {
        h[to].pop_back();
        t = h[to].back();
      }
      done[t.id] = true;
      write(now), out[outn++] = ' ';
      write(to), out[outn++] = ' ';
      write(alle[t.id].first), out[outn++] = ' ';
      write(alle[t.id].second), out[outn++] = '\n';
      h[to].pop_back();
      merge(to, t.v);
    }
}
int main() {
  read(n);
  for (int i = 1; i < n; ++i) {
    int u, v;
    read(u), read(v);
    if (u > v) std::swap(u, v);
    e[i] = data(u, v, i);
    alle[i] = std::make_pair(u, v);
    g[u].push_back(edge(v, i));
    g[v].push_back(edge(u, i));
  }
  for (int i = 1; i < n; ++i) {
    int u, v;
    read(u), read(v);
    if (u > v) std::swap(u, v);
    e[n - 1 + i] = data(u, v, n - 1 + i);
    alle[n - 1 + i] = std::make_pair(u, v);
  }
  std::sort(e + 1, e + 2 * (n - 1) + 1);
  for (int i = 1; i <= 2 * (n - 1); ++i) {
    if (i < 2 * (n - 1) && e[i].u == e[i + 1].u && e[i].v == e[i + 1].v) {
      ++i;
      continue;
    }
    int x = e[i].id;
    if (x <= n - 1)
      rem[e[i].id] = true;
    else
      add[e[i].id] = true;
  }
  int ans = 0;
  for (int i = n; i <= 2 * (n - 1); ++i)
    if (add[i]) {
      h[alle[i].first].push_back(edge(alle[i].second, i));
      h[alle[i].second].push_back(edge(alle[i].first, i));
      ans++;
    }
  for (int i = 1; i <= n; ++i) fa[i] = i;
  write(ans), out[outn++] = '\n';
  dfs(1, 0);
  printf("%s", out);
  return 0;
}
