#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
#include <cmath>
#define EPS 1e-10
using namespace std;
//add????????????1e-10???EPS??????????????????????????¨?????£?????????
//EPS????????????????????????????????????0???????????¨???????????????
//??????????¶?????????\???????????¨???????±?????????????????????£?????????????????????????????????
double add(double a,double b){
    if(fabs(a+b)<EPS*(fabs(a)+fabs(b)))return 0.0;
    return a+b;
}

class P{
public:
    double x,y;
    P(double x=0.0,double y=0.0):x(x),y(y){}
    P operator +(P p){
        return P(add(x,p.x),add(y,p.y));
    }
    P operator -(P p){
        return P(add(x,-p.x),add(y,-p.y));
    }
    P operator *(double d){
        return P(x*d,y*d);
    }
    P operator /(double d){
        return P(x/d,y/d);
    }
    bool operator<(const P &p)const{
        if(fabs(add(x,-p.x))<EPS)return y<p.y;
        return x<p.x;
    }
};

typedef P Vector;
typedef vector<P> Polygon;

double norm(Vector p){
    return add(p.x*p.x,p.y*p.y);
}

double abs(Vector p){
    return sqrt(norm(p));
}

double dot(Vector a,Vector b){
    return add(a.x*b.x,a.y*b.y);
}
//cross???
double cross(Vector a,Vector b){
    return add(a.x*b.y,-a.y*b.x);
}
//ccw??????????????°??¨??????
int ccw(P p0,P p1,P p2){
	//????±???????????????????????????¢????????????????????????????????????
    Vector a=p1-p0;
    Vector b=p2-p0;
    //??????????????????1??????????????????????????´0???????????????????????§?????????
    //???????????????????????§???????????´?????¶?????¨????????????????????????
    if(cross(a,b)>EPS)return 1;
    return -1;
}
//andrewscan?????¬???????????????????????£??????????°????????????°???????????????????????????
//????????????????????????????????§????????°??????????????????????????????
//vector????????????????????¨??????????????????
Polygon andrewScan(Polygon s){
    Polygon u,l;
    if(s.size()<3)return s;
    //???????????´??¢??????
    sort(s.begin(),s.end());
    //?¬???????????????\??????
    u.push_back(s[0]);
    u.push_back(s[1]);
    l.push_back(s[s.size()-1]);
    l.push_back(s[s.size()-2]);
    for(int i=2;i<s.size();i++){
    	//?????????????????????????§??????????????????????ccw?????????????????°???????????????
    	//?????????-1??????????????§????????????????¨??????????????????§?¶?????????????
        for(int n=u.size();n>=2 && ccw(u[n-2],u[n-1],s[i])!=-1;n--){
            //????????£??????ccw?????£?????????pop?????????????????????
        	u.pop_back();
        }
        //??????????¬???????????????\?????????
        u.push_back(s[i]);
    }
   //???????????????????????´????????????????????????????????????????§??????????????§??????????????????£?????????
    for(int i=s.size()-3;i>=0;i--){
        for(int n=l.size();n>=2 && ccw(l[n-2],l[n-1],s[i])!=-1;n--){
            l.pop_back();
        }
        l.push_back(s[i]);
    }
    //reverse??§??????????????????????????????????????????Polygon???????????¬???????????§
    //x???????????´?????????y????????????????????§???????????????x????????????????????????
    //???????????£???x?????????
    reverse(l.begin(),l.end());
    for(int i=u.size()-2;i>=1;i--){
        l.push_back(u[i]);
    }
    return l;
}

int main(void){
    int n;
    //????????´????¨???? typedef vector<p> Polygon;
    //typedef P Vector;
    Polygon g;
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        P p;
        scanf("%lf %lf",&p.x,&p.y);
        g.push_back(p);
    }
    //andrewScan(g)
    Polygon res=andrewScan(g);
    printf("%d\n",res.size());
    int f=0;
    //???????°??????????????????¢?????????????????????
    //?????????????????°?¬?????????????????????????????¨??????§?????????
    for(int i=1;i<res.size();i++){
        if(res[f].y>res[i].y || (res[f].y==res[i].y && res[f].x>res[i].x)){
            f=i;
        }
    }
    for(int i=0;i<res.size();i++){
    	//?????????????????????????¨???¨??????size??????????????????
        printf("%d %d\n",(int)res[(i+f)%res.size()].x,(int)res[(i+f)%res.size()].y);
    }
    return 0;
}

Measured memory_bytes: 9996