#include <bits/stdc++.h>
using namespace std;
vector<vector<int> > init(int n, int v) {
  vector<vector<int> > ret;
  for (int i = 0; i < (n); ++i) {
    vector<int> l;
    l.resize(n);
    for (int j = 0; j < (n); ++j) l[j] = v;
    ret.push_back(l);
  }
  return ret;
}
void dump(const vector<vector<int> >& arr) {
  cout << " dump:\n";
  int n = arr.size();
  for (int i = 0; i < (n); ++i) {
    for (int j = 0; j < (n); ++j) {
      cout << arr[i][j] + 1 << " ";
    }
    cout << endl;
  }
}
bool discover(int n, const vector<string>& ma, vector<vector<int> >& has_p) {
  bool found = false;
  for (int i = 0; i < (n); ++i) {
    for (int j = 0; j < (n); ++j) {
      int points = ma[i][j] - '0';
      int has_point = 0;
      int no_point = 0;
      for (int u = 0; u < (2); ++u) {
        for (int v = 0; v < (2); ++v) {
          int i1 = i + u;
          int j1 = j + v;
          has_point += has_p[i1][j1] == 1;
          no_point += has_p[i1][j1] == -1;
        }
      }
      points -= has_point;
      int left_points = 4 - has_point - no_point;
      if ((points == 0 || points == left_points) && left_points > 0) {
        found = true;
        int val = points == 0 ? -1 : 1;
        for (int u = 0; u < (2); ++u) {
          for (int v = 0; v < (2); ++v) {
            int i1 = i + u;
            int j1 = j + v;
            if (has_p[i1][j1] == 0) {
              has_p[i1][j1] = val;
            }
          }
        }
      }
    }
  }
  return found;
}
pair<int, int> del(pair<int, int> a, pair<int, int> b) {
  return make_pair(a.first - b.first, a.second - b.second);
}
int dot(pair<int, int> a, pair<int, int> b) {
  return a.first * b.second - a.second * b.first;
}
int main() {
  int n;
  while (cin >> n) {
    if (n == 0) break;
    vector<string> ma;
    for (int i = 0; i < (n); ++i) {
      string line;
      cin >> line;
      ma.push_back(line);
    }
    vector<vector<int> > has_p = init(n + 1, 0);
    while (discover(n, ma, has_p))
      ;
    vector<pair<int, int> > points;
    for (int i = 0; i < (n + 1); ++i) {
      for (int j = 0; j < (n + 1); ++j) {
        if (has_p[i][j] == 1) {
          points.push_back(make_pair(j, n - i));
        }
      }
    }
    sort((points).begin(), points.end());
    vector<pair<int, int> > conv;
    conv.push_back(points[0]);
    conv.push_back(points[1]);
    for (int i = 2; i < (points.size()); ++i) {
      while (conv.size() > 1 &&
             dot(del(points[i], conv[conv.size() - 1]),
                 del(conv[conv.size() - 1], conv[conv.size() - 2])) <= 0)
        conv.pop_back();
      conv.push_back(points[i]);
    }
    int nl = conv.size();
    for (int i = points.size() - 2; i >= 0; i--) {
      while (conv.size() > 1 &&
             dot(del(points[i], conv[conv.size() - 1]),
                 del(conv[conv.size() - 1], conv[conv.size() - 2])) <= 0 &&
             conv.size() > nl) {
        conv.pop_back();
      }
      conv.push_back(points[i]);
    }
    conv.pop_back();
    cout << conv.size() << endl;
    for (int i = 0; i < (conv.size()); ++i)
      cout << conv[i].first << " " << conv[i].second << endl;
  }
  return 0;
}
