#include <bits/stdc++.h>
using namespace std;
struct Point {
  double x, y;
  bool operator<(const Point& p) const {
    return x < p.x || (x == p.x && y < p.y);
  }
  bool operator==(const Point& p) const { return x == p.x && y == p.y; }
};
Point operator-(Point p, const Point& q) {
  p.x -= q.x;
  p.y -= q.y;
  return p;
}
double cross(Point p, Point q) { return p.x * q.y - q.x * p.y; }
const double EPS = 1e-7;
int convex_hull(Point P[], int n, Point hull[]) {
  sort(P, P + n);
  n = unique(P, P + n) - P;
  vector<Point> L, U;
  if (n <= 2) {
    copy(P, P + n, hull);
    return n;
  }
  for (int i = 0; i < n; i++) {
    while (L.size() > 1 && cross(P[i] - L.back(), L[L.size() - 2] - P[i]) < EPS)
      L.pop_back();
    while (U.size() > 1 &&
           cross(P[i] - U.back(), U[U.size() - 2] - P[i]) > -EPS)
      U.pop_back();
    L.push_back(P[i]);
    U.push_back(P[i]);
  }
  copy(L.begin(), L.end(), hull);
  copy(U.rbegin() + 1, U.rend() - 1, hull + L.size());
  return L.size() + U.size() - 2;
}
const int MAX_N = 530;
string A[MAX_N];
Point P[MAX_N * MAX_N], hull[MAX_N * MAX_N];
int di[4] = {0, -1, 0, -1};
int dj[4] = {0, 0, -1, -1};
void do_case(int n) {
  for (int i = 0; i < n; i++) cin >> A[n - 1 - i];
  int m = 0;
  for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++) {
      int ctr[5] = {0};
      for (int k = 0; k < 4; k++) {
        int nI = i + di[k], nJ = j + dj[k];
        if (0 <= nI && nI < n && 0 <= nJ && nJ < n) ctr[A[nI][nJ] - '0']++;
      }
      if (ctr[1] && ctr[0] == 0) P[m++] = {double(j), double(i)};
    }
  int h = convex_hull(P, m, hull);
  cout << h << "\n";
  int i = min_element(hull, hull + h) - hull;
  cout << hull[i].x << " " << hull[i].y << "\n";
  int j = (i + h - 1) % h;
  while (i != j) {
    cout << hull[j].x << " " << hull[j].y << "\n";
    j--;
    if (j < 0) j = h - 1;
  }
}
int main() {
  int n;
  while (cin >> n && n) do_case(n);
}
