#include <bits/stdc++.h>
using namespace std;
const double EPS = 1e-4;
namespace std {
bool operator<(const complex<double> a, const complex<double> b) {
  return a.real() != b.real() ? a.real() < b.real() : a.imag() < b.imag();
}
}  // namespace std
double dot(complex<double> a, complex<double> b) {
  return a.real() * b.real() + a.imag() * b.imag();
}
double cross(complex<double> a, complex<double> b) {
  return a.real() * b.imag() - a.imag() * b.real();
}
int ccw(complex<double> a, complex<double> b, complex<double> c) {
  b -= a;
  c -= a;
  if (cross(b, c) > EPS) return +1;
  if (cross(b, c) < -EPS) return -1;
  if (dot(b, c) < -EPS) return +2;
  if (norm(b) < norm(c)) return -2;
  return 0;
}
vector<complex<double>> convexHull(vector<complex<double>> ps) {
  int n = ps.size(), k = 0;
  sort(ps.begin(), ps.end());
  vector<complex<double>> ch(2 * n);
  for (int i = 0; i < n; ch[k++] = ps[i++])
    while (k >= 2 && ccw(ch[k - 2], ch[k - 1], ps[i]) <= 0) --k;
  for (int i = n - 2, t = k + 1; i >= 0; ch[k++] = ps[i--])
    while (k >= t && ccw(ch[k - 2], ch[k - 1], ps[i]) <= 0) --k;
  ch.resize(k - 1);
  return ch;
}
int main(void) {
  int N;
  while (cin >> N, N) {
    vector<string> s(N);
    for (int i = 0; i < int(N); ++i) cin >> s[i];
    reverse(s.begin(), s.end());
    vector<vector<bool>> inside(N + 1, vector<bool>(N + 1, true));
    for (int y = 0; y < int(N); ++y)
      for (int x = 0; x < int(N); ++x)
        if (s[y][x] == '0') {
          for (int dy = 0; dy < int(2); ++dy)
            for (int dx = 0; dx < int(2); ++dx) {
              inside[y + dy][x + dx] = false;
            }
        }
    vector<complex<double>> ps;
    for (int y = 0; y < int(N + 1); ++y)
      for (int x = 0; x < int(N + 1); ++x)
        if (inside[y][x]) {
          ps.push_back(complex<double>(x, y));
        }
    ps = convexHull(ps);
    reverse(ps.begin() + 1, ps.end());
    cout << ps.size() << endl;
    for (complex<double> p : ps) {
      cout << p.real() << " " << p.imag() << endl;
    }
  }
  return 0;
}
