4
1 4
3 1
3 4
 5
4 1
4 3
5 3
2 4
 21
7 15
13 1
14 3
4 10
2 3
16 18
17 20
16 20
8 4
3 12
2 17
13 11
16 1
13 2
13 5
8 9
6 14
3 17
16 9
13 8
 3
3 1
3 2
 6
5 2
5 3
1 4
3 1
5 6
 60
17 34
46 22
50 44
46 33
41 21
31 33
48 6
38 19
35 60
2 24
49 29
7 53
34 1
19 55
32 1
31 42
27 28
4 53
6 50
21 34
1 10
12 36
54 8
16 13
51 43
45 51
54 20
13 53
34 33
49 33
51 11
59 34
15 5
59 28
30 39
13 30
58 4
34 14
3 9
19 34
4 18
26 48
56 54
3 43
57 25
3 41
35 3
48 44
19 13
54 1
23 31
59 47
5 1
46 40
6 26
20 25
37 5
17 24
20 52
 3
3 2
1 2
 39
6 13
15 39
10 35
31 28
4 21
12 39
3 7
3 13
6 1
5 14
36 28
12 15
18 38
30 29
19 34
36 16
20 22
8 13
38 32
26 39
21 37
1 7
15 27
12 26
8 3
6 14
29 2
25 23
32 21
5 16
32 25
6 8
13 10
23 30
34 37
29 33
28 14
36 5
 10
5 9
8 5
7 6
7 9
3 9
2 1
7 2
3 6
7 1

1
3 4 1 2  0
 3
13 2 1 7 3 17 1 19 13 8 1 21  0
 0
 2
48 44 1 6 6 26 1 12  0
 7
12 15 1 2 1 7 1 9 12 26 1 11 8 3 1 12 6 8 1 17 28 14 1 20 36 5 1 24  2
3 6 1 4 7 1 1 10 
#include <bits/stdc++.h>
int main() {
  std::size_t N;
  if (!(std::cin >> N)) return 1;
  std::vector<std::size_t> edges(2 * (N - 1), 0);
  for (std::size_t& edge : edges) {
    if (!(std::cin >> edge)) return 1;
  }
  std::vector<std::size_t> edge_order(edges.size(), 0);
  for (std::size_t i = 0; i < edge_order.size(); i++) {
    edge_order[i] = i;
  }
  std::sort(edge_order.begin(), edge_order.end(),
            [&edges](const std::size_t i, const std::size_t j) {
              return edges[i] < edges[j];
            });
  std::vector<std::size_t> parent(N, 0);
  std::vector<std::size_t> redundant_edges;
  auto find_parent = [&N, &edges, &edge_order, &parent,
                      &redundant_edges](const std::size_t node) {
    if (parent[node - 1] != 0) return parent[node - 1];
    auto comp = [&edges, &edge_order](const std::size_t i,
                                      const std::size_t node) {
      return edges[i] < node;
    };
    auto start = std::lower_bound(
        edge_order.begin(), edge_order.end(), node,
        [&edges, &edge_order](const std::size_t i, const std::size_t node) {
          return edges[i] < node;
        });
    auto end = std::upper_bound(
        edge_order.begin(), edge_order.end(), node,
        [&edges, &edge_order](const std::size_t node, const std::size_t i) {
          return node < edges[i];
        });
    auto it = start;
    std::vector<std::size_t> neighbors({node});
    while (it != end) {
      if (*it % 2) {
        neighbors.push_back(edges[*it - 1]);
      } else {
        neighbors.push_back(edges[*it + 1]);
      }
      it++;
    }
    if (neighbors.size() > 1) {
      std::sort(neighbors.begin(), neighbors.end());
      for (auto it = neighbors.begin() + 1; it != neighbors.end(); it++) {
        if (*it != node) {
          redundant_edges.push_back(node);
          redundant_edges.push_back(*it);
        }
      }
      parent[node - 1] = neighbors[0];
    } else {
      parent[node - 1] = node;
    }
    return parent[node - 1];
  };
  auto find_root = [&find_parent, &parent](std::size_t node) {
    std::vector<std::size_t> path({node});
    std::size_t parent_node = find_parent(node);
    while (parent_node != node) {
      node = parent_node;
      path.push_back(node);
      parent_node = find_parent(node);
    }
    for (std::size_t path_node : path) {
      parent[path_node - 1] = parent_node;
    }
    return parent_node;
  };
  std::size_t count = 0;
  std::vector<std::size_t> added_edges;
  for (std::size_t i = 1; i <= N; i++) {
    std::size_t parent_node = find_root(i);
    if (parent_node != 1) {
      added_edges.push_back(i);
      added_edges.push_back(1);
      count += 1;
    }
  }
  std::cout << count << std::endl;
  for (std::size_t i = 0; i < count; i++) {
    std::cout << redundant_edges[2 * i] << " " << redundant_edges[2 * i + 1]
              << " " << added_edges[2 * i] << " " << added_edges[2 * i + 1]
              << std::endl;
    ;
  }
  return 0;
}
