#include <bits/stdc++.h>
namespace FastIO {
template <typename T>
inline void readInteger(T& ret) {
  char ch = getchar();
  bool flag = false;
  while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
  if (ch == '-') {
    flag = true;
    ch = getchar();
  }
  ret = 0;
  while (ch >= '0' && ch <= '9') {
    ret = ret * 10 + (ch - '0');
    ch = getchar();
  }
  if (flag) ret = -ret;
}
inline int nextInt() {
  int x;
  readInteger(x);
  return x;
}
inline long long nextLong() {
  long long x;
  readInteger(x);
  return x;
}
template <typename T>
inline void outInteger(T x) {
  if (x < 0) {
    putchar('-');
    x = -x;
  }
  if (x >= 10) {
    outInteger(x / 10);
  }
  putchar(x % 10 + '0');
}
inline void newline() { putchar('\n'); }
}  // namespace FastIO
using namespace std;
using namespace FastIO;
struct Point {
  int x, y;
  Point(int _x = 0, int _y = 0) {
    x = _x;
    y = _y;
  }
  Point operator+(Point p) { return Point(x + p.x, y + p.y); }
  Point operator-(Point p) { return Point(x - p.x, y - p.y); }
  Point operator*(int k) { return Point(k * x, k * y); }
};
int dot(Point a, Point b) { return a.x * b.x + a.y * b.y; }
int cross(Point a, Point b) { return a.x * b.y - a.y * b.x; }
double dist(Point u, Point v) { return hypot(u.x - v.x, u.y - v.y); }
int N, M;
Point p[555 * 555];
bool cmp(Point u, Point v) {
  int t = cross(u - p[0], v - p[0]);
  if (t > 0) return true;
  if (t < 0) return false;
  return dist(u, p[0]) < dist(v, p[0]);
}
void graham() {
  if (N == 0) {
    M = 0;
    return;
  }
  for (int i = 1; i < N; i++)
    if (p[i].x < p[0].x || (p[i].x == p[0].x && p[i].y < p[0].y))
      swap(p[0], p[i]);
  sort(p + 1, p + N, cmp);
  if (N < 3) {
    M = N;
    return;
  }
  M = 2;
  for (int i = 2; i < N; i++) {
    while (M > 1 && cross(p[i] - p[M - 2], p[M - 1] - p[M - 2]) >= 0) M--;
    p[M++] = p[i];
  }
}
int H;
char board[555][555];
int vst[555][555], rid;
int dx[] = {1, 0, 1, 0};
int dy[] = {0, 1, 1, 0};
int main() {
  while (scanf("%d", &H) && H) {
    for (int i = 0; i < H; i++) scanf("%s", board[H - i - 1]);
    rid++;
    for (int y = 0; y < H; y++) {
      for (int x = 0; x < H; x++) {
        if (board[y][x] != '0') continue;
        for (int i = 0; i < 4; i++) {
          int x1 = x + dx[i], y1 = y + dy[i];
          vst[x1][y1] = rid;
        }
      }
    }
    N = 0;
    for (int y = 0; y <= H; y++) {
      for (int x = 0; x <= H; x++) {
        if (vst[x][y] != rid) p[N++] = Point(x, y);
      }
    }
    graham();
    p[M] = p[0];
    reverse(p, p + M + 1);
    printf("%d\n", M);
    for (int i = 0; i < M; i++) printf("%d %d\n", p[i].x, p[i].y);
  }
  return 0;
}
