#include <bits/stdc++.h>
#pragma GCC optimize("O3")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx")
using namespace std;
const int dx[4] = {0, 0, 1, 1};
const int dy[4] = {0, 1, 1, 0};
struct Vector {
  int x, y;
  Vector() {}
  Vector(int _x, int _y) : x(_x), y(_y) {}
  Vector(Vector a, Vector b) : x(b.x - a.x), y(b.y - a.y) {}
  long long len2() { return x * 1LL * x + y * 1LL * y; }
};
bool operator==(Vector a, Vector b) { return a.x == b.x && a.y == b.y; }
bool operator<(Vector a, Vector b) {
  return a.x < b.x || (a.x == b.x && a.y < b.y);
}
long long cP(Vector a, Vector b) { return a.x * 1LL * b.y - a.y * 1LL * b.x; }
int N;
vector<string> mm;
vector<Vector> gg;
vector<Vector> pp;
void INIT() {
  mm.clear();
  pp.clear();
  gg.clear();
}
bool input() {
  INIT();
  cin >> N;
  if (!N) return false;
  mm.resize(N);
  for (int i = N - 1; i >= 0; i--) cin >> mm[i];
  return true;
}
bool check1(int x, int y) {
  for (int k = 0; k < 4; k++) {
    int nx = x + dx[k];
    int ny = y + dy[k];
    if (nx >= N || ny >= N) continue;
    if (mm[nx][ny] == '0') return false;
  }
  return true;
}
bool cmp_angle(Vector v1, Vector v2) {
  Vector a(gg[0], v1);
  Vector b(gg[0], v2);
  long long cp = cP(a, b);
  return ((cp < 0) || (cp == 0 && a.len2() < b.len2()));
}
void convex_hull() {
  for (int i = 0; i < (int)gg.size(); i++) {
    if (gg[i].x < gg[0].x || (gg[i].x == gg[0].x && gg[i].y < gg[0].y))
      swap(gg[0], gg[i]);
  }
  sort(gg.begin() + 1, gg.end(), cmp_angle);
  pp.push_back(gg[0]);
  pp.push_back(gg[1]);
  for (int i = 2; i < (int)gg.size(); i++) {
    long long cp =
        cP(Vector(pp.back(), pp[pp.size() - 2]), Vector(pp.back(), gg[i]));
    while (cp <= 0) {
      pp.pop_back();
      if (pp.size() < 2) break;
      cp = cP(Vector(pp.back(), pp[pp.size() - 2]), Vector(pp.back(), gg[i]));
    }
    if (i < (int)gg.size()) pp.push_back(gg[i]);
  }
}
void solve() {
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
      if (mm[i][j] == '4') {
        for (int k = 0; k < 4; k++) gg.push_back(Vector(i + dx[k], j + dy[k]));
      }
      int gx, gy;
      gx = gy = -1;
      if (mm[i][j] == '1') {
        for (int x = max(0, i - 1); x <= i; x++) {
          for (int y = max(0, j - 1); y <= j; y++) {
            if (check1(x, y)) {
              gx = x;
              gy = y;
            }
          }
        }
      }
      if (gx != -1 && gy != -1) gg.push_back(Vector(gx + 1, gy + 1));
    }
  }
  sort(gg.begin(), gg.end());
  gg.resize(unique(gg.begin(), gg.end()) - gg.begin());
  convex_hull();
  cout << pp.size() << "\n";
  int start = 0;
  for (int i = 0; i < (int)pp.size(); i++) {
    swap(pp[i].x, pp[i].y);
    if (pp[i] < pp[start]) start = i;
  }
  int cur = start;
  for (int i = 0; i < (int)pp.size(); i++) {
    cout << pp[cur].x << " " << pp[cur].y << "\n";
    --cur;
    if (cur < 0) cur += (int)pp.size();
  }
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  while (input()) {
    solve();
  }
  return 0;
}
