#include <bits/stdc++.h>
using namespace std;
struct vec {
  long long x, y;
  vec(long long a = 0, long long b = 0) {
    x = a;
    y = b;
  }
  long long operator*(vec A) { return x * A.x + y * A.y; }
  long long operator%(vec A) { return x * A.y - y * A.x; }
  vec(vec A, vec B) {
    x = B.x - A.x;
    y = B.y - A.y;
  }
  long long leng() { return x * x + y * y; }
};
vec cmp_vec;
bool cmp(vec A, vec B) {
  if ((vec(cmp_vec, A) % vec(cmp_vec, B)) == 0) {
    return vec(cmp_vec, A).leng() < vec(cmp_vec, B).leng();
  }
  return ((vec(cmp_vec, A) % vec(cmp_vec, B)) > 0);
}
bool cmp1(vec A, vec B) { return A.x < B.x || (A.x == B.x && A.y < B.y); }
void hull(vector<vec> arr) {
  long long n = arr.size();
  sort(arr.begin(), arr.end(), cmp1);
  cmp_vec = arr[0];
  sort(arr.begin() + 1, arr.end(), cmp);
  vector<vec> hul({cmp_vec});
  for (auto x : arr) {
    if (x.x == cmp_vec.x && x.y == cmp_vec.y) continue;
    while (hul.size() > 1 and
           vec(hul[hul.size() - 2], hul.back()) % vec(hul.back(), x) <= 0) {
      hul.pop_back();
    }
    hul.push_back(x);
  }
  reverse(hul.begin() + 1, hul.end());
  cout << hul.size() << endl;
  for (auto x : hul) {
    cout << x.x << " " << x.y << endl;
  }
}
vector<long long> max_hor, min_hor;
bool inside(long long x, long long y) {
  return x <= max_hor[y] && x >= min_hor[y];
}
void sol(long long n, long long m) {
  set<pair<long long, long long> > arr;
  max_hor.clear();
  min_hor.clear();
  max_hor.resize(n, -1e9);
  min_hor.resize(n, 1e9);
  for (long long i = 0; i < m; i++) {
    long long x, y;
    cin >> x >> y;
    x--;
    y--;
    max_hor[y] = max(max_hor[y], x);
    min_hor[y] = min(min_hor[y], x);
    arr.insert(make_pair(x, y));
  }
  set<pair<long long, long long> > imp;
  for (auto A : arr) {
    long long i = A.first;
    long long j = A.second;
    if (not inside(i + 1, j + 1) && not inside(i + 1, j) &&
        not inside(i, j + 1) &&
        arr.count({i + 1, j + 1}) + arr.count({i + 1, j}) +
                arr.count({i, j + 1}) ==
            0) {
      imp.insert({i, j});
    }
    if (not inside(i - 1, j - 1) && not inside(i - 1, j) &&
        not inside(i, j - 1) &&
        arr.count({i - 1, j - 1}) + arr.count({i - 1, j}) +
                arr.count({i, j - 1}) ==
            0) {
      imp.insert({i + 1, j + 1});
    }
    if (not inside(i, j - 1) && not inside(i + 1, j - 1) &&
        not inside(i + 1, j) &&
        arr.count({i, j - 1}) + arr.count({i + 1, j - 1}) +
                arr.count({i + 1, j}) ==
            0) {
      imp.insert({i, j + 1});
    }
    if (not inside(i, j + 1) && not inside(i - 1, j) &&
        not inside(i - 1, j + 1) &&
        arr.count({i, j + 1}) + arr.count({i - 1, j}) +
                arr.count({i - 1, j + 1}) ==
            0) {
      imp.insert({i + 1, j});
    }
  }
  vector<vec> tohull;
  for (auto x : imp) {
    tohull.push_back(vec(x.first, x.second));
  }
  hull(tohull);
}
signed main() {
  long long n, m;
  while (cin >> n) {
    cin >> m;
    if (n == 0) break;
    sol(n, m);
  }
}
