#include <bits/stdc++.h>
using namespace std;
const int maxn = 100050;
struct Point {
  int x, y;
  Point(int x = 0, int y = 0) : x(x), y(y) {}
};
Point operator+(Point A, Point B) { return Point(A.x + B.x, A.y + B.y); }
Point operator-(Point A, Point B) { return Point(A.x - B.x, A.y - B.y); }
Point operator*(Point A, int p) { return Point(A.x * p, A.y * p); }
Point operator/(Point A, int p) { return Point(A.x / p, A.y / p); }
int dcmp(int x) {
  if (x == 0)
    return 0;
  else
    return x < 0 ? -1 : 1;
}
bool operator<(const Point& a, const Point& b) {
  return a.x < b.x || (a.x == b.x && a.y < b.y);
}
bool operator==(const Point& a, const Point& b) {
  return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0;
}
int Cross(Point A, Point B) { return A.x * B.y - A.y * B.x; }
vector<Point> ConvexHull(vector<Point> p) {
  sort(p.begin(), p.end());
  p.erase(unique(p.begin(), p.end()), p.end());
  int n = p.size();
  vector<Point> ch(n + 1);
  int m = 0;
  for (int i = 0; i < n; i++) {
    while (m > 1 && dcmp(Cross(ch[m - 1] - ch[m - 2], p[i] - ch[m - 2])) <= 0)
      m--;
    ch[m++] = p[i];
  }
  int k = m;
  for (int i = n - 2; i >= 0; i--) {
    while (m > k && dcmp(Cross(ch[m - 1] - ch[m - 2], p[i] - ch[m - 2])) <= 0)
      m--;
    ch[m++] = p[i];
  }
  if (n > 1) m--;
  ch.resize(m);
  return ch;
}
int rows[maxn], rowb[maxn], cols[maxn], colb[maxn];
int N, M;
int t1, t2, t3, t4;
vector<Point> p;
vector<Point> v;
Point now[15];
int gox[] = {0, -1, 0, 1, -1, 1, -1, 0, 1};
int goy[] = {0, 1, 1, 1, 0, 0, -1, -1, -1};
void init() {
  memset(rowb, 0, sizeof(rowb));
  memset(colb, 0, sizeof(colb));
  memset(rows, 0x3f, sizeof(rows));
  memset(cols, 0x3f, sizeof(cols));
  p.clear();
  v.clear();
}
int jud(Point n1, Point n2, Point n3, Point n4) {
  Point a[6];
  a[1] = n1;
  a[2] = n2;
  a[3] = n3;
  a[4] = n4;
  for (int i = 1; i <= 4; i++) {
    if (a[i].y < rows[a[i].x] || a[i].y > rowb[a[i].x]) return 0;
    if (a[i].x < cols[a[i].y] || a[i].x > colb[a[i].y]) return 0;
  }
  return 1;
}
int main() {
  while (~scanf("%d %d", &N, &M) && N) {
    init();
    for (int i = 1; i <= M; i++) {
      scanf("%d %d", &t1, &t2);
      t3 = t1;
      t4 = t2;
      v.push_back(Point(t3, t4));
      rows[t3] = min(t4, rows[t3]);
      rowb[t3] = max(t4, rowb[t3]);
      cols[t4] = min(t3, cols[t4]);
      colb[t4] = max(t3, colb[t4]);
    }
    for (int i = 0; i < v.size(); i++) {
      now[0] = v[i];
      for (int j = 1; j <= 8; j++) {
        now[j].x = v[i].x + gox[j];
        now[j].y = v[i].y + goy[j];
      }
      if (jud(now[1], now[2], now[4], now[0])) {
        p.push_back(now[2]);
      }
      if (jud(now[2], now[3], now[0], now[5])) {
        p.push_back(now[3]);
      }
      if (jud(now[4], now[0], now[6], now[7])) {
        p.push_back(now[0]);
      }
      if (jud(now[0], now[5], now[7], now[8])) {
        p.push_back(now[5]);
      }
    }
    p = ConvexHull(p);
    printf("%d\n", p.size());
    if (p.size()) {
      printf("%d %d\n", p[0].x - 1, p[0].y - 1);
    }
    for (int i = p.size() - 1; i >= 1; i--) {
      printf("%d %d\n", p[i].x - 1, p[i].y - 1);
    }
  }
  return 0;
}
