#include <bits/stdc++.h>
using namespace std;
struct pt {
  long long x, y;
  pt() {}
  pt(long long _x, long long _y) : x(_x), y(_y) {}
  pt operator+(const pt& p) const { return pt(x + p.x, y + p.y); }
  pt operator-(const pt& p) const { return pt(x - p.x, y - p.y); }
  long long cross(const pt& p) const { return x * p.y - y * p.x; }
  long long cross(const pt& p, const pt& q) const {
    return (p - *this).cross(q - *this);
  }
  long long dot(const pt& p) const { return x * p.x + y * p.y; }
  long long dot(const pt& p, const pt& q) const {
    return (p - *this).dot(q - *this);
  }
};
vector<pt> graham(vector<pt> p) {
  int n = p.size();
  int pos = 0;
  for (int i = 1; i < n; i++) {
    if (p[i].x < p[pos].x || (p[i].x == p[pos].x && p[i].y < p[pos].y)) pos = i;
  }
  swap(p[0], p[pos]);
  pt base = p[0];
  sort(1 + (p).begin(), (p).end(), [&base](const pt& l, const pt& r) {
    return base.cross(l, r) == 0 ? base.dot(l, l) < base.dot(r, r)
                                 : base.cross(l, r) > 0;
  });
  int ptr = n - 1;
  while (ptr > 0 && base.cross(p[ptr], p[n - 1]) == 0) --ptr;
  vector<pt> stk;
  for (int i = 0; i < n; i++) {
    while (stk.size() >= 2u && stk[stk.size() - 2].cross(stk.back(), p[i]) <= 0)
      stk.pop_back();
    stk.push_back(p[i]);
  }
  return stk;
}
void solve() {
  int n, m;
  cin >> n >> m;
  if (!n) exit(0);
  vector<pair<int, int> > s(m);
  vector<pt> cand;
  set<pair<int, int> > nonz, rnonz;
  for (int i = 0; i < m; i++) {
    cin >> s[i].first >> s[i].second;
    --s[i].first;
    --s[i].second;
    int x = n - 1 - s[i].second;
    int y = s[i].first;
    s[i] = {x, y};
    nonz.insert(s[i]);
    rnonz.emplace(s[i].second, s[i].first);
  }
  auto isZero = [&n, &nonz, &rnonz](int i, int j) {
    if (i < 0 || j < 0 || i >= n || j >= n)
      return true;
    else {
      if (nonz.count(make_pair(i, j))) return false;
      auto it = nonz.lower_bound(make_pair(i, j));
      if (it == nonz.end() || it->first != i) return true;
      if (it == nonz.begin() || (--it)->first != i) return true;
      swap(i, j);
      it = rnonz.lower_bound(make_pair(i, j));
      if (it == rnonz.end() || it->first != i) return true;
      if (it == rnonz.begin() || (--it)->first != i) return true;
      return false;
    }
  };
  vector<int> ds = {-1, 1};
  for (auto& cell : s) {
    int i, j;
    tie(i, j) = cell;
    for (int dx : ds) {
      for (int dy : ds) {
        if (isZero(i - dx, j - dy) && isZero(i - dx, j) && isZero(i, j - dy) &&
            !isZero(i + dx, j + dy)) {
          cand.emplace_back(i + max(0, dx), j + max(0, dy));
        }
      }
    }
  }
  auto hull = graham(cand);
  for (pt& p : hull) {
    int x = p.y;
    int y = n - p.x;
    p = pt(x, y);
  }
  reverse((hull).begin(), (hull).end());
  size_t pos = 0;
  for (size_t i = 1; i < hull.size(); i++)
    if (hull[i].x < hull[pos].x ||
        (hull[i].x == hull[pos].x && hull[i].y < hull[pos].y))
      pos = i;
  rotate(hull.begin(), hull.begin() + pos, hull.end());
  cout << hull.size() << '\n';
  for (auto p : hull) {
    cout << p.x << ' ' << p.y << '\n';
  }
}
signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  int T = 1;
  while (1) solve();
  return 0;
}
