#include <bits/stdc++.h>
using namespace std;

struct Point {
  int x, y;
  Point(int _x, int _y) : x(_x), y(_y) {}
};

struct Vector {
  int x, y;
  Vector(int _x, int _y) : x(_x), y(_y) {};
  Vector(Point f, Point t) : x(t.x - f.x), y(t.y - f.y) {};
  bool clockwise(Vector v){ return x*v.y<y*v.x; }
};

int n;
vector<Point> v,s;

bool ok(Point p3){
  if(s.size()<=1)return true;
  Point p1=*(s.rbegin()+1);
  Point p2=*s.rbegin();
  // printf("OK (%d,%d) (%d,%d) (%d,%d) %d\n",p1.x,p1.y,p2.x,p2.y,p3.x,p3.y,Vector(p1,p2).cross(Vector(p2,p3))>=0);
  // printf("(%d,%d)->(%d,%d) . (%d,%d)->(%d,%d) = %d\n",p1.x,p1.y,p2.x,p2.y,p2.x,p2.y,p3.x,p3.y,Vector(p1,p2).dot(Vector(p2,p3)));
  return !Vector(p1,p2).clockwise(Vector(p2,p3));
}

void print_stack(){
  for(Point p:s){ printf("(%d,%d) ",p.x,p.y); } printf("\n");
}

void consider(Point p){
  // printf("Consider (%d,%d)\n",p.x,p.y);
  while(!ok(p))s.pop_back();
  s.push_back(p);
  // print_stack();
}

void convex_hull() {
  sort(v.begin(),v.end(),[](const Point& a,const Point& b){
    if(a.y!=b.y)return a.y<b.y;
    return a.x<b.x;
  });
  for(int i=0;i<v.size();++i)consider(v[i]);
  for(int i=v.size()-2;i>=0;--i)consider(v[i]);
  s.pop_back();
}

int main() {
  cin>>n;
  for(int i=0;i<n;++i){
    int x,y;cin>>x>>y;
    v.push_back(Point(x,y));
  }
  convex_hull();
  cout<<s.size()<<endl;
  for(int i=0;i<s.size();++i){
    cout<<s[i].x<<" "<<s[i].y<<endl;
  }
}