#include <bits/stdc++.h>
using namespace std;
typedef long double ld;
struct Point
{
    ld x,y;
    Point():x(0),y(0){}
    Point(ld _x,ld _y):x(_x),y(_y){}
    Point operator +(const Point &p) const
    {return Point(x+p.x,y+p.y);}
    Point operator -(const Point &p) const
    {return Point(x-p.x,y-p.y);}
    ld operator *(const Point &p) const
    {return x*p.x+y*p.y;}
    ld operator %(const Point &p) const
    {return x*p.y-y*p.x;}   
    bool operator <(const Point &p) const
    {return tie(y,x) < tie(p.y,p.x);}
    bool operator ==(const Point &p) const
    {return tie(y,x) == tie(p.y,p.x);}
};
vector<Point> convex_hull(vector<Point> v)    
{
    //O(nlgn)
    sort(v.begin(),v.end(),[&](const Point &a,const Point &b){return tie(a.y,a.x) < tie(b.y,b.x);});
    v.erase(unique(v.begin(),v.end(),[&](const Point &a,const Point &b){return tie(a.y,a.x)==tie(b.y,b.x);}),v.end());
    if(v.size()<=2u) return v;

    vector<Point> up;
    for(auto p:v)
    {
        while(up.size()>=2u && (p-up.back())%(up.back()-up[up.size()-2])<0)
            up.pop_back();
        up.push_back(p);
    }
    vector<Point> dn;
    for(auto p:v)
    {
        while(dn.size()>=2u && (p-dn.back())%(dn.back()-dn[dn.size()-2])>0)
            dn.pop_back();
        dn.push_back(p);
    }
    reverse(dn.begin(),dn.end());
    up.insert(up.end(),dn.begin()+1,dn.end()-1);
    return move(up);
}

int main()
{
    int n;cin>>n;
    vector<Point> v(n);
    for(auto &p:v) cin>>p.x>>p.y;
    auto c=convex_hull(v);
    rotate(c.begin(),c.begin()+1,c.end());
    reverse(c.begin(),c.end());
    printf("%d\n",(int)c.size());
    for(auto p:c) cout<<p.x<<" "<<p.y<<endl;
    return 0;
}