#include <bits/stdc++.h>
using namespace std;
using ll = long long;
constexpr int INF = 10000000;
vector<vector<int>> adjlist;
vector<int> match, dist;
bool bfs(int n) {
  queue<int> q;
  dist[0] = -1;
  for (int i = 1; i <= n; i++) {
    if (match[i] == 0) {
      dist[i] = 0;
      q.push(i);
    } else
      dist[i] = -1;
  }
  bool res = false;
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    if (dist[u] >= 0)
      for (int v : adjlist[u]) {
        if (match[v] == 0) res = true;
        if (dist[match[v]] == -1) {
          dist[match[v]] = dist[u] + 1;
          q.push(match[v]);
        }
      }
  }
  return res;
}
bool dfs(int u) {
  for (int v : adjlist[u])
    if (match[v] == 0 || (dist[match[v]] > dist[u] && dfs(match[v]))) {
      match[v] = u;
      match[u] = v;
      return true;
    }
  dist[u] = -1;
  return false;
}
int hopcroft_karp(int n) {
  int ans = 0;
  match.assign(adjlist.size(), 0);
  dist.resize(adjlist.size(), -1);
  for (int i = 1; i <= n; i++)
    for (int w : adjlist[i])
      if (match[w] == 0) {
        match[i] = w;
        match[w] = i;
        ans++;
        break;
      }
  while (bfs(n))
    for (int i = 1; i <= n; i++)
      if (match[i] == 0 && dfs(i)) ans++;
  return ans;
}
vector<bool> visit;
void alternate(int u) {
  visit[u] = true;
  for (const auto &n : adjlist[u]) {
    if (visit[n]) continue;
    visit[n] = true;
    alternate(match[n]);
  }
}
void koenig(int n) {
  hopcroft_karp(n);
  visit = vector<bool>((int)(adjlist).size());
  for (int i = 1; i <= n; i++) {
    if (match[i] == 0) alternate(i);
  }
  for (int i = n + 1; i < (int)(adjlist).size(); ++i) {
    visit[i] = !visit[i];
  }
}
struct lineX {
  ll x1, x2, y;
  vector<pair<int, int>> pts() const {
    return {make_pair(x1, y), make_pair(x2, y)};
  }
};
struct lineY {
  ll x, y1, y2;
  vector<pair<int, int>> pts() const {
    return {make_pair(x, y1), make_pair(x, y2)};
  }
};
bool intersect(const lineX &a, const lineY &b) {
  for (const auto &p1 : a.pts())
    for (const auto &p2 : b.pts())
      if (p1 == p2) return false;
  return a.x1 <= b.x && a.x2 >= b.x && b.y1 <= a.y && b.y2 >= a.y;
}
int main() {
  int n;
  scanf("%d", &n);
  vector<pair<int, int>> pts(n);
  for (int i = 0; i < n; i++) {
    scanf("%d%d", &pts[i].first, &pts[i].second);
  }
  map<ll, vector<ll>> x;
  map<ll, vector<ll>> y;
  for (const auto &p : pts) {
    x[p.first].push_back(p.second);
    y[p.second].push_back(p.first);
  }
  vector<lineX> lX;
  vector<lineY> lY;
  for (auto &p : x) {
    sort(begin(p.second), end(p.second));
    int s = (int)(p.second).size();
    for (int i = 0; i < s - 1; i++) {
      lY.push_back(lineY{p.first, p.second[i], p.second[i + 1]});
    }
  }
  for (auto &p : y) {
    sort(begin(p.second), end(p.second));
    int s = (int)(p.second).size();
    for (int i = 0; i < s - 1; i++) {
      lX.push_back(lineX{p.second[i], p.second[i + 1], p.first});
    }
  }
  adjlist = vector<vector<int>>((int)(lX).size() + (int)(lY).size() + 1);
  for (int i = 0; i < (int)(lX).size(); i++)
    for (int j = 0; j < (int)(lY).size(); j++) {
      if (intersect(lX[i], lY[j]))
        adjlist[i + 1].push_back((int)(lX).size() + j + 1);
    }
  koenig((int)(lX).size());
  vector<lineX> resX;
  vector<lineY> resY;
  int idx = 0;
  for (auto &p : x) {
    int s = (int)(p.second).size();
    int cur = 0;
    while (cur < s) {
      int to = cur;
      while (to + 1 < s && visit[(int)(lX).size() + idx + 1]) {
        ++to;
        ++idx;
      }
      if (to + 1 < s && !visit[(int)(lX).size() + idx + 1]) ++idx;
      resY.push_back(lineY{p.first, p.second[cur], p.second[to]});
      cur = to + 1;
    }
  }
  idx = 0;
  for (auto &p : y) {
    int s = (int)(p.second).size();
    int cur = 0;
    while (cur < s) {
      int to = cur;
      while (to + 1 < s && visit[idx + 1]) {
        ++to;
        ++idx;
      }
      if (to + 1 < s && !visit[idx + 1]) ++idx;
      resX.push_back(lineX{p.second[cur], p.second[to], p.first});
      cur = to + 1;
    }
  }
  printf("%d\n", (int)(resX).size());
  for (const auto &l : resX) {
    printf("%d %d %d %d\n", (int)l.x1, (int)l.y, (int)l.x2, (int)l.y);
  }
  printf("%d\n", (int)(resY).size());
  for (const auto &l : resY) {
    printf("%d %d %d %d\n", (int)l.x, (int)l.y1, (int)l.x, (int)l.y2);
  }
}
