#include<fstream.h>
#define N 120001
typedef struct point
{double x,y;};
long n,i,imax,imin,nsus,njos,j,t,l;
point d[N],jos[N],sus[N],b[N];
double minx,maxx,k;
void merge(point a[N],long p,long q)
{long m=(p+q)/2,i,j,k,l;
if(p==q)
return;
merge(a,p,m);
merge(a,m+1,q);
for(i=p,j=m+1,k=p;i<=m||j<=q;)
if(j>q||(i<=m&&(a[i].x<a[j].x||(a[i].x==a[j].x&&a[i].y<a[j].y))))
b[k++]=a[i++];
else
b[k++]=a[j++];
for(l=p;l<=q;l++)
a[l]=b[l];}
double s(point p1,point p2,point p)
{return (p2.x-p1.x)*(p.y-p1.y)-(p.x-p1.x)*(p2.y-p1.y);}
int main()
{ifstream f("infasuratoare.in");
freopen("infasuratoare.out","w",stdout);
f>>n;
for(i=1;i<=n;i++)
f>>d[i].x>>d[i].y;
merge(d,1,n);
nsus=njos=imin=1;
imax=n;
sus[1]=jos[1]=d[imin];
for(i=2;i<n;i++)
{k=s(d[imin],d[imax],d[i]);
if(k<0)
{jos[++njos]=d[i];
while(njos>2&&s(jos[njos-2],jos[njos],jos[njos-1])>0)
jos[njos-1]=jos[njos--];}
else
if(k>0)
{sus[++nsus]=d[i];
while(nsus>2&&s(sus[nsus-2],sus[nsus],sus[nsus-1])<0)
sus[nsus-1]=sus[nsus--];}}
sus[++nsus]=jos[++njos]=d[imax];
t=nsus;
while(t>2)
if(s(sus[t-2],sus[t],sus[t-1])<0)
sus[t-1]=sus[nsus--];
else
t--;
l=njos;
while(l>2)
if(s(jos[l-2],jos[l],jos[l-1])>0)
jos[l-1]=jos[njos--];
else
l--;
printf("%ld\n",njos+nsus-2);
for(i=1;i<=njos;i++)
printf("%lf %lf\n",jos[i].x,jos[i].y);
for(j=nsus-1;j>=2;j--)
printf("%lf %lf\n",sus[j].x,sus[j].y);
f.close();
fclose(stdout);
return 0;}