#include <bits/stdc++.h>
using namespace std;
const int maxn = 200005;
inline pair<int, int> operator-(const pair<int, int> &p,
                                const pair<int, int> &q) {
  return pair<int, int>(p.first - q.first, p.second - q.second);
}
int pmy[4 * maxn], pMy[4 * maxn], smy[4 * maxn], sMy[4 * maxn];
pair<int, int> p[maxn];
int sz;
vector<pair<int, int> > lo, up;
vector<pair<int, int> > qx;
inline long long cross(const pair<int, int> &p, const pair<int, int> &q) {
  return 1LL * p.first * q.second - 1LL * p.second * q.first;
}
inline int hull(vector<pair<int, int> > &h) {
  if (sz <= 1) return sz;
  h.clear();
  h.push_back(p[0]);
  for (int i = 1; i < sz; i++) {
    while (h.size() > 1 &&
           cross(h.back() - h[(int)h.size() - 2], p[i] - h.back()) <= 0)
      h.pop_back();
    h.push_back(p[i]);
  }
  return h.size();
}
inline bool fnd(const pair<int, int> &p, const vector<pair<int, int> > &v) {
  int i = lower_bound((v).begin(), (v).end(), p) - v.begin();
  return i < int(v.size()) && v[i] == p;
}
inline int convex_hull() {
  lo.clear();
  up.clear();
  if (sz <= 1) return sz;
  sort(p, p + sz);
  sz = unique(p, p + sz) - p;
  int L = hull(lo);
  reverse(p, p + sz);
  int H = hull(up);
  sz = 0;
  for (int i = 0; i < int(lo.size()); i++) p[sz++] = lo[i];
  for (int i = 1; i < int(up.size()) - 1; i++) p[sz++] = up[i];
  return L + H - 2;
}
bool in(pair<int, int> q) {
  int it =
      lower_bound(qx.begin(), qx.end(), make_pair(q.first, 0)) - qx.begin();
  if (it == qx.size() || (pMy[it] <= q.second || pmy[it] >= q.second))
    return false;
  it = lower_bound(qx.begin(), qx.end(), make_pair(q.first + 1, 0)) -
       qx.begin() - 1;
  if (it < 0 || (sMy[it] <= q.second || smy[it] >= q.second)) return false;
  return true;
}
int main() {
  ios::sync_with_stdio(false);
  int n, m;
  while (cin >> n >> m && n) {
    map<pair<int, int>, int> cnt;
    int y, x;
    qx.clear();
    for (int i = 0; i < m; i++) {
      cin >> x >> y;
      x--, y--;
      cnt[make_pair(x, y)]++;
      cnt[make_pair(x + 1, y)]++;
      cnt[make_pair(x, y + 1)]++;
      cnt[make_pair(x + 1, y + 1)]++;
      qx.push_back(make_pair(x, y));
      qx.push_back(make_pair(x + 1, y));
      qx.push_back(make_pair(x, y + 1));
      qx.push_back(make_pair(x + 1, y + 1));
    }
    sort(qx.begin(), qx.end());
    qx.resize(unique(qx.begin(), qx.end()) - qx.begin());
    pmy[0] = n, pMy[0] = 0;
    for (int i = 1; i <= qx.size(); i++) {
      pmy[i] = min(pmy[i - 1], qx[i - 1].second);
      pMy[i] = max(pMy[i - 1], qx[i - 1].second);
    }
    smy[qx.size() - 1] = n, sMy[qx.size() - 1] = 0;
    for (int i = int(qx.size()) - 2; i >= 0; i--) {
      smy[i] = min(smy[i + 1], qx[i + 1].second);
      sMy[i] = max(sMy[i + 1], qx[i + 1].second);
    }
    sz = 0;
    for (auto q : cnt) {
      if (q.second == 4 || (q.second == 3 && in(q.first))) {
        p[sz++] = q.first;
      }
    }
    convex_hull();
    cout << sz << endl;
    int st = 0;
    for (int i = 0; i < sz; i++)
      if (p[i] < p[st]) st = i;
    int j = st;
    do {
      cout << p[j].first << ' ' << p[j].second << '\n';
      j--;
      if (j < 0) j = sz - 1;
    } while (j != st);
  }
  return 0;
}
