#include <bits/stdc++.h>
using namespace std;
struct point {
  long long x, y;
  int id;
  point(){};
  point(long long _x, long long _y, int _id) : x(_x), y(_y), id(_id){};
};
struct vect {
  long long x, y;
  vect(){};
  vect(long long _x, long long _y) : x(_x), y(_y){};
  vect(point a, point b) : x(b.x - a.x), y(b.y - a.y){};
};
long long crossProductNorm(vect a, vect b) { return a.x * b.y - b.x * a.y; }
bool isCCW(vect a, vect b) { return crossProductNorm(a, b) < 0; }
long long dst(point a, point b) {
  return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
}
point refPoint;
bool compCW(point a, point b) {
  vect aVect(refPoint, a);
  vect bVect(refPoint, b);
  return isCCW(aVect, bVect) || (crossProductNorm(aVect, bVect) == 0 &&
                                 dst(refPoint, a) < dst(refPoint, b));
}
vector<point> constructConvexHull(vector<point> &pts) {
  if (pts.empty()) {
    vector<point> v;
    return v;
  }
  int minY = pts[0].y, minX = pts[0].x;
  int minYP = 0;
  for (int i = (1); i < (pts.size()); i++)
    if (pts[i].y < minY || (pts[i].y == minY && pts[i].x < minX))
      minY = pts[i].y, minX = pts[i].x, minYP = i;
  refPoint = pts[minYP];
  pts.erase(pts.begin() + minYP);
  sort(pts.begin(), pts.end(), compCW);
  pts.insert(pts.begin(), refPoint);
  vector<point> myCH;
  myCH.push_back(pts[0]);
  for (int i = (1); i < (pts.size()); i++) {
    while (myCH.size() >= 2) {
      vect v1(myCH[myCH.size() - 1], pts[i]);
      vect v2(myCH[myCH.size() - 2], myCH[myCH.size() - 1]);
      if (!isCCW(v2, v1))
        myCH.pop_back();
      else
        break;
    }
    myCH.push_back(pts[i]);
  }
  while (myCH.size() > 2) {
    vect v1(myCH[myCH.size() - 1], pts[0]);
    vect v2(myCH[myCH.size() - 2], myCH[myCH.size() - 1]);
    if (!isCCW(v2, v1))
      myCH.pop_back();
    else
      break;
  }
  return myCH;
}
char g[505][505];
int main() {
  while (1) {
    int n;
    scanf("%d", &n);
    if (n == 0) return 0;
    for (int y = (0); y < (n); y++) scanf(" %s", g[n - y - 1]);
    vector<point> vp;
    for (int y = (1); y < (n); y++)
      for (int x = (1); x < (n); x++) {
        bool allg = true;
        for (int dy = (-1); dy < (1); dy++)
          for (int dx = (-1); dx < (1); dx++) {
            allg = allg && g[y + dy][x + dx] > '0';
          }
        if (allg) {
          vp.emplace_back(x, y, 0);
        }
      }
    vector<point> ch = constructConvexHull(vp);
    int m = int(ch.size());
    int make_pair = 0;
    for (int i = (1); i < (m); i++)
      if (ch[i].x < ch[make_pair].x ||
          (ch[i].x == ch[make_pair].x && ch[i].y < ch[make_pair].y))
        make_pair = i;
    printf("%d\n", m);
    for (int i = (0); i < (m); i++)
      printf("%lld %lld\n", ch[(make_pair + i) % m].x,
             ch[(make_pair + i) % m].y);
  }
}
