#include <bits/stdc++.h>
using namespace std;
bool debug = 0;
int n, m, k;
int dx[4] = {0, 1, 0, -1}, dy[4] = {1, 0, -1, 0};
string direc = "RDLU";
long long ln, lk, lm;
void etp(bool f = 0) {
  puts(f ? "Yes" : "No");
  exit(0);
}
void addmod(int &x, int y, int mod = 1000000007) {
  x += y;
  if (x >= mod) x -= mod;
}
void et() {
  puts("-1");
  exit(0);
}
long long fastPow(long long x, long long y, int mod = 1000000007) {
  long long ans = 1;
  while (y > 0) {
    if (y & 1) ans = (x * ans) % mod;
    x = x * x % mod;
    y >>= 1;
  }
  return ans;
}
struct Point {
  long long x, y;
  Point() {}
  Point(long long x, long long y) : x(x), y(y) {}
  Point operator+(const Point &o) const { return Point(x + o.x, y + o.y); }
  Point operator-(const Point &o) const { return Point(x - o.x, y - o.y); }
  bool operator<(const Point &o) const {
    return x < o.x || (x == o.x && y < o.y);
  }
  friend bool operator==(const Point &r1, const Point &r2) {
    return r1.x == r2.x && r1.y == r2.y;
  }
  long long cross(Point b) const { return x * b.y - b.x * y; }
  void readin() { scanf("%lld%lld", &x, &y); }
  void pp() { printf("%lld %lld\n", x, y); }
} p[300105];
vector<Point> convex(vector<Point> &vp) {
  sort(vp.begin(), vp.end());
  int N = unique(vp.begin(), vp.end()) - vp.begin();
  vector<Point> ans1, ans2;
  for (int(i) = 0; (i) < (int)(N); (i)++) {
    while (ans1.size() > 1) {
      Point o = ans1[ans1.size() - 2], a = ans1.back();
      if ((a - o).cross(vp[i] - o) <= 0) {
        ans1.pop_back();
      } else
        break;
    }
    ans1.push_back(vp[i]);
  }
  for (int i = N - 1; i >= 0; i--) {
    while (ans2.size() > 1) {
      Point o = ans2[ans2.size() - 2], a = ans2.back();
      if ((a - o).cross(vp[i] - o) <= 0) {
        ans2.pop_back();
      } else
        break;
    }
    ans2.push_back(vp[i]);
  }
  for (int i = 1; i < ans2.size() - 1; i++) ans1.push_back(ans2[i]);
  return ans1;
}
long long xl[300105], xr[300105], yl[300105], yr[300105];
bool isIn(long long x, long long y) {
  for (int i = 0; i <= 1; i++)
    for (int j = 0; j <= 1; j++)
      if (xl[y + j] > x + i || xr[y + j] < x + i || yl[x + i] > y + j ||
          yr[x + i] < y + j)
        return 0;
  return 1;
}
void fmain() {
  for (int(i) = 0; (i) < (int)(300105); (i)++) {
    xl[i] = (1LL << 60);
    yl[i] = (1LL << 60);
  }
  while (~scanf("%d%d", &n, &m)) {
    if (n == 0) break;
    for (int(i) = 1; (i) <= (int)(m); (i)++) p[i].readin();
    for (int(i) = 1; (i) <= (int)(m); (i)++) {
      xl[p[i].y] = min(xl[p[i].y], p[i].x);
      xr[p[i].y] = max(xr[p[i].y], p[i].x);
      yl[p[i].x] = min(yl[p[i].x], p[i].y);
      yr[p[i].x] = max(yr[p[i].x], p[i].y);
    }
    vector<Point> vp;
    for (int(i) = 1; (i) <= (int)(m); (i)++) {
      long long x = p[i].x, y = p[i].y;
      if (isIn(x, y)) vp.push_back(Point(x, y));
      if (isIn(x - 1, y)) vp.push_back(Point(x - 1, y));
      if (isIn(x, y - 1)) vp.push_back(Point(x, y - 1));
      if (isIn(x - 1, y - 1)) vp.push_back(Point(x - 1, y - 1));
    }
    vector<Point> ans = convex(vp);
    printf("%d\n", ans.size());
    ans[0].pp();
    for (int i = ans.size() - 1; i >= 1; i--) ans[i].pp();
    for (int(i) = 1; (i) <= (int)(m); (i)++) {
      xl[p[i].y] = (1LL << 60);
      xr[p[i].y] = 0;
      yl[p[i].x] = (1LL << 60);
      yr[p[i].x] = 0;
    }
  }
}
int main() {
  fmain();
  return 0;
}
