#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;   }