#include <bits/stdc++.h>
using namespace std;
constexpr int INF = 1e9 + 7;
constexpr long long INFL = 1e18;
template <class L, class R>
ostream &operator<<(ostream &os, pair<L, R> P) {
  return os << "(" << P.first << "," << P.second << ")";
}
constexpr int maxn = 1005;
vector<pair<int, int>> P, Q;
vector<pair<int, int>> pkt, pom;
map<pair<int, int>, int> M;
vector<int> G[maxn];
int vis[maxn], skoj[maxn * 2], lp = 1;
bool mark[maxn * 2];
int fu[maxn], best[maxn];
int fin(int a) { return fu[a] == a ? a : fu[a] = fin(fu[a]); }
bool intersect(pair<int, int> a, pair<int, int> b) {
  auto a1 = pom[a.first], a2 = pom[a.second];
  auto b1 = pom[b.first], b2 = pom[b.second];
  assert(a1.second < a2.second and b1.first < b2.first);
  if (a1.second < b1.second and b1.second < a2.second and
      b1.first < a1.first and a1.first < b2.first)
    return true;
  return false;
}
bool dfs(int a) {
  vis[a] = lp;
  for (auto v : G[a]) {
    if (skoj[v] == -1 or (vis[skoj[v]] != lp and dfs(skoj[v]))) {
      skoj[a] = v;
      skoj[v] = a;
      return true;
    }
  }
  return false;
}
void dfs_mark(int a) {
  if (a == -1) return;
  if (mark[a]) return;
  mark[a] = true;
  for (auto v : G[a]) {
    if (not mark[v] and skoj[v] != a) {
      mark[v] = true;
      dfs_mark(skoj[v]);
    }
  }
}
void solve() {
  int n = P.size(), m = Q.size();
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (intersect(P[i], Q[j])) {
        G[i].push_back(j + n);
      }
    }
  }
  fill(skoj, skoj + n + m + 1, -1);
  for (int i = 0; i < n; i++) {
    if (not dfs(i)) {
      lp++;
      dfs(i);
    }
  }
  for (int i = 0; i < n; i++) {
    if (skoj[i] != -1 or mark[i]) continue;
    dfs_mark(i);
  }
  vector<pair<int, int>> pr, qr;
  for (int i = 0; i < n; i++)
    if (mark[i]) pr.emplace_back(P[i]);
  for (int j = 0; j < m; j++)
    if (not mark[j + n]) qr.emplace_back(Q[j]);
  P = pr, Q = qr;
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  int n;
  cin >> n;
  for (int i = 0; i < n; i++) {
    int x, y;
    cin >> x >> y;
    pkt.emplace_back(x, y);
    M[{x, y}] = i;
  }
  pom = pkt;
  sort((pkt).begin(), (pkt).end());
  for (int i = 0; i < n;) {
    int j = i;
    while (j < n and pkt[j].first == pkt[i].first) j++;
    for (int k = i; k + 1 < j; k++) P.emplace_back(M[pkt[k]], M[pkt[k + 1]]);
    i = j;
  }
  sort((pkt).begin(), (pkt).end(), [](pair<int, int> a, pair<int, int> b) {
    return make_pair(a.second, a.first) < make_pair(b.second, b.first);
  });
  for (int i = 0; i < n;) {
    int j = i;
    while (j < n and pkt[j].second == pkt[i].second) j++;
    for (int k = i; k + 1 < j; k++) Q.emplace_back(M[pkt[k]], M[pkt[k + 1]]);
    i = j;
  }
  solve();
  cout << n - (int)(Q).size() << endl;
  iota(fu, fu + n + 1, 0);
  for (auto p : Q) {
    auto a = fin(p.first), b = fin(p.second);
    fu[b] = a;
  }
  for (int i = 0; i < n; i++) best[fin(i)] = max(best[fin(i)], pom[i].first);
  for (int i = 0; i < n; i++)
    if (fu[i] == i)
      cout << pom[i].first << " " << pom[i].second << " " << best[i] << " "
           << pom[i].second << "\n";
  cout << n - (int)(P).size() << endl;
  iota(fu, fu + n + 1, 0);
  for (auto p : P) {
    auto a = fin(p.first), b = fin(p.second);
    fu[b] = a;
  }
  fill(best, best + n + 1, 0);
  for (int i = 0; i < n; i++) best[fin(i)] = max(best[fin(i)], pom[i].second);
  for (int i = 0; i < n; i++)
    if (fu[i] == i)
      cout << pom[i].first << " " << pom[i].second << " " << pom[i].first << " "
           << best[i] << "\n";
}
