#include <bits/stdc++.h>
using namespace std;
const int N = 10010;
const int M = 2e6 + 10;
const int inf = 0x3f3f3f3;
int head[N], d[N], cur[N];
int n, m, s, t, tot;
queue<int> q;
struct EDGE {
  int to, nx, c;
} e[M * 2];
void add(int u, int v, int z) {
  e[tot].to = v;
  e[tot].nx = head[u];
  e[tot].c = z;
  head[u] = tot++;
  e[tot].to = u;
  e[tot].nx = head[v];
  e[tot].c = 0;
  head[v] = tot++;
}
bool bfs(int s, int t) {
  memset(d, 0, sizeof(d));
  while (q.size()) q.pop();
  for (int i = 1; i <= t; i++) cur[i] = head[i];
  q.push(s);
  d[s] = 1;
  while (q.size()) {
    int x = q.front();
    q.pop();
    for (int i = head[x]; i != -1; i = e[i].nx) {
      int y = e[i].to;
      if (e[i].c && !d[y]) {
        q.push(y);
        d[y] = d[x] + 1;
        if (y == t) return 1;
      }
    }
  }
  return 0;
}
int dfs(int x, int flow) {
  if (x == t) return flow;
  int rest = flow, k;
  for (int i = cur[x]; i != -1 && rest; i = e[i].nx) {
    cur[x] = i;
    int y = e[i].to, z = e[i].c;
    if (z && d[y] == d[x] + 1) {
      k = dfs(y, min(rest, z));
      if (!k) d[y] = 0;
      e[i].c -= k;
      e[i ^ 1].c += k;
      rest -= k;
    }
  }
  return flow - rest;
}
int dinic(int s, int t) {
  int flow = 0, maxflow = 0;
  while (bfs(s, t))
    while (flow = dfs(s, inf)) maxflow += flow;
  return maxflow;
}
void init() {
  for (int i = 1; i <= t; i++) head[i] = -1;
  tot = 0;
}
bool cmp1(pair<int, int> x, pair<int, int> y) {
  if (x.first == y.first) return x.second < y.second;
  return x.first < y.first;
}
bool cmp2(pair<int, int> x, pair<int, int> y) {
  if (x.second == y.second) return x.first < y.first;
  return x.second < y.second;
}
bool cmp3(pair<pair<int, int>, pair<int, int> > x,
          pair<pair<int, int>, pair<int, int> > y) {
  if (x.first.first == y.first.first) return x.first.second < y.first.second;
  return x.first.first < y.first.first;
}
bool cmp4(pair<pair<int, int>, pair<int, int> > x,
          pair<pair<int, int>, pair<int, int> > y) {
  if (x.first.second == y.first.second) return x.first.first < y.first.first;
  return x.first.second < y.first.second;
}
pair<int, int> x[1010];
map<pair<pair<int, int>, pair<int, int> >, int> mp;
pair<pair<int, int>, pair<int, int> > sj[10100];
vector<pair<pair<int, int>, pair<int, int> > > op, ans;
int tid = 1, pp;
bool ison(pair<pair<int, int>, pair<int, int> > a,
          pair<pair<int, int>, pair<int, int> > b) {
  if (b.first.first > a.first.first && b.first.first < a.second.first &&
      a.first.second > b.first.second && a.first.second < b.second.second)
    return true;
  return false;
}
int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) {
    scanf("%d%d", &x[i].first, &x[i].second);
  }
  sort(x + 1, x + 1 + n, cmp2);
  for (int i = 2; i <= n; i++) {
    if (x[i].second == x[i - 1].second) {
      mp[{x[i - 1], x[i]}] = tid;
      sj[tid++] = {x[i - 1], x[i]};
    }
  }
  pp = tid;
  sort(x + 1, x + 1 + n, cmp1);
  for (int i = 2; i <= n; i++) {
    if (x[i].first == x[i - 1].first) {
      mp[{x[i - 1], x[i]}] = tid;
      sj[tid++] = {x[i - 1], x[i]};
    }
  }
  s = tid;
  t = s + 1;
  init();
  for (int i = 1; i < pp; i++) add(s, i, 1);
  for (int i = pp; i < s; i++) add(i, t, 1);
  for (int i = 1; i < pp; i++) {
    for (int j = pp; j < s; j++) {
      if (ison(sj[i], sj[j])) add(i, j, inf);
    }
  }
  dinic(s, t);
  for (int i = 1; i <= n; i++) ans.push_back({x[i], x[i]});
  for (int i = head[s]; i != -1; i = e[i].nx) {
    if (d[e[i].to]) ans.push_back(sj[e[i].to]);
  }
  sort(ans.begin(), ans.end(), cmp4);
  pair<int, int> st = ans[0].first, ed = ans[0].second;
  for (int i = 1; i < ans.size(); i++) {
    if (ans[i].first.second == ed.second && ans[i].first.first <= ed.first) {
      ed.first = max(ed.first, ans[i].second.first);
    } else {
      op.push_back({st, ed});
      st = ans[i].first;
      ed = ans[i].second;
    }
  }
  op.push_back({st, ed});
  printf("%d\n", op.size());
  for (int i = 0; i < op.size(); i++)
    printf("%d %d %d %d\n", op[i].first.first, op[i].first.second,
           op[i].second.first, op[i].second.second);
  ans.clear();
  op.clear();
  for (int i = 1; i <= n; i++) ans.push_back({x[i], x[i]});
  for (int i = head[t]; i != -1; i = e[i].nx) {
    if (d[e[i].to] == 0) ans.push_back(sj[e[i].to]);
  }
  sort(ans.begin(), ans.end(), cmp3);
  st = ans[0].first, ed = ans[0].second;
  for (int i = 1; i < ans.size(); i++) {
    if (ans[i].first.first == ed.first && ans[i].first.second <= ed.second) {
      ed.second = max(ed.second, ans[i].second.second);
    } else {
      op.push_back({st, ed});
      st = ans[i].first;
      ed = ans[i].second;
    }
  }
  op.push_back({st, ed});
  printf("%d\n", op.size());
  for (int i = 0; i < op.size(); i++)
    printf("%d %d %d %d\n", op[i].first.first, op[i].first.second,
           op[i].second.first, op[i].second.second);
}
