#include <bits/stdc++.h>
using namespace std;
double safe_sqrt(double x) { return sqrt(max((double)0.0, x)); }
long long GI(long long& x) { return scanf("%lld", &x); }
const double PI = acos(-1.0);
double DEG_to_RAD(double d) { return d * PI / 180.0; }
double RAD_to_DEG(double r) { return r * 180.0 / PI; }
inline long long cmp(double a, double b) {
  return (a < b - 1e-6) ? -1 : ((a > b + 1e-6) ? 1 : 0);
}
struct Point {
  double x, y;
  Point(double x = 0.0, double y = 0.0) : x(x), y(y) {}
  Point operator+(const Point& a) const { return Point(x + a.x, y + a.y); }
  Point operator-(const Point& a) const { return Point(x - a.x, y - a.y); }
  Point operator*(double k) const { return Point(x * k, y * k); }
  Point operator/(double k) const { return Point(x / k, y / k); }
  bool operator<(const Point& rhs) const {
    return make_pair(y, x) < make_pair(rhs.y, rhs.x);
  }
  bool operator==(const Point& rhs) const {
    return make_pair(y, x) == make_pair(rhs.y, rhs.x);
  }
  double operator*(const Point& a) const { return x * a.x + y * a.y; }
  double operator%(const Point& a) const { return x * a.y - y * a.x; }
  long long cmp(Point q) const {
    if (long long t = ::cmp(x, q.x)) return t;
    return ::cmp(y, q.y);
  }
  Point conj() { return Point(x, -y); }
  double norm() { return x * x + y * y; }
  double len() { return sqrt(norm()); }
  Point rotate(double alpha) {
    double cosa = cos(alpha), sina = sin(alpha);
    return Point(x * cosa - y * sina, x * sina + y * cosa);
  }
};
long long ccw(Point a, Point b, Point c) { return cmp((b - a) % (c - a), 0); }
double area2(Point a, Point b, Point c) { return a % b + b % c + c % a; }
bool between(const Point& a, const Point& b, const Point& c) {
  return (fabs(area2(a, b, c)) < 1e-6 && (a.x - b.x) * (c.x - b.x) <= 0 &&
          (a.y - b.y) * (c.y - b.y) <= 0);
}
void ConvexHull(vector<Point>& pts) {
  sort(pts.begin(), pts.end());
  pts.erase(unique(pts.begin(), pts.end()), pts.end());
  vector<Point> up, dn;
  for (long long i = 0; i < pts.size(); i++) {
    while (up.size() > 1 && area2(up[up.size() - 2], up.back(), pts[i]) >= 0)
      up.pop_back();
    while (dn.size() > 1 && area2(dn[dn.size() - 2], dn.back(), pts[i]) <= 0)
      dn.pop_back();
    up.push_back(pts[i]);
    dn.push_back(pts[i]);
  }
  pts = dn;
  for (long long i = (long long)up.size() - 2; i >= 1; i--)
    pts.push_back(up[i]);
  if (pts.size() <= 2) return;
  dn.clear();
  dn.push_back(pts[0]);
  dn.push_back(pts[1]);
  for (long long i = 2; i < pts.size(); i++) {
    if (between(dn[dn.size() - 2], dn[dn.size() - 1], pts[i])) dn.pop_back();
    dn.push_back(pts[i]);
  }
  if (dn.size() >= 3 && between(dn.back(), dn[0], dn[1])) {
    dn[0] = dn.back();
    dn.pop_back();
  }
  pts = dn;
}
istream& operator>>(istream& cin, Point& p) {
  cin >> p.x >> p.y;
  return cin;
}
ostream& operator<<(ostream& cout, Point& p) {
  cout << p.x << ' ' << p.y;
  return cout;
}
bool in_convex(vector<Point>& l, Point p) {
  long long a = 1, b = l.size() - 1, c;
  if (((double)(l[a].x - l[0].x) * (double)(l[b].y - l[0].y) -
       (double)(l[a].y - l[0].y) * (l[b].x - l[0].x)) > 0)
    swap(a, b);
  if (((double)(l[a].x - l[0].x) * (double)(p.y - l[0].y) -
       (double)(l[a].y - l[0].y) * (p.x - l[0].x)) >= 0 ||
      ((double)(l[b].x - l[0].x) * (double)(p.y - l[0].y) -
       (double)(l[b].y - l[0].y) * (p.x - l[0].x)) <= 0)
    return false;
  while (abs(a - b) > 1) {
    c = (a + b) / 2;
    if (((double)(l[c].x - l[0].x) * (double)(p.y - l[0].y) -
         (double)(l[c].y - l[0].y) * (p.x - l[0].x)) > 0)
      b = c;
    else
      a = c;
  }
  return ((double)(l[b].x - l[a].x) * (double)(p.y - l[a].y) -
          (double)(l[b].y - l[a].y) * (p.x - l[a].x)) < 0;
}
vector<Point> cv123;
set<pair<long long, long long> > all123;
bool ok(long long x, long long y) {
  return all123.count(make_pair(x, y)) || in_convex(cv123, Point(x, y));
}
bool check(long long x, long long y) {
  return ok(x, y) && ok(x + 1, y) && ok(x, y + 1) && ok(x + 1, y + 1);
}
int main() {
  ios ::sync_with_stdio(0);
  cin.tie(0);
  cout << (fixed) << setprecision(9);
  long long n, m;
  while (GI(n) == 1 && GI(m) == 1 && n && m) {
    all123.clear();
    cv123.clear();
    for (long long i = (1), _b = (m); i <= _b; ++i) {
      long long x, y;
      GI(x);
      GI(y);
      all123.insert(make_pair(x, y));
      cv123.push_back(Point(x, y));
    }
    ConvexHull(cv123);
    set<pair<long long, long long> > candidates;
    for (auto p : all123) {
      long long x = p.first;
      long long y = p.second;
      candidates.insert(make_pair(x, y));
      candidates.insert(make_pair(x, y - 1));
      candidates.insert(make_pair(x - 1, y));
      candidates.insert(make_pair(x - 1, y - 1));
    }
    vector<Point> all;
    for (auto p : candidates) {
      if (check(p.first, p.second)) all.push_back(Point(p.first, p.second));
    }
    ConvexHull(all);
    if (ccw(all[0], all[1], all[2]) > 0) reverse(all.begin(), all.end());
    vector<pair<long long, long long> > res;
    for (auto p : all) {
      res.push_back(make_pair((long long)(round(p.x) + 1e-6),
                              (long long)(round(p.y) + 1e-6)));
    }
    long long start = 0;
    for (long long i = (1), _b = (((long long)(res).size()) - 1); i <= _b; ++i)
      if (res[i] < res[start]) start = i;
    cout << ((long long)(res).size()) << '\n';
    for (long long i = 0, _a = (((long long)(res).size())); i < _a; ++i) {
      long long u = (i + start) % ((long long)(res).size());
      cout << res[u].first << ' ' << res[u].second << '\n';
    }
  }
}
