#include<bits/stdc++.h>

using namespace std;

const int maxn=1e5+10; 

#define pt pair<double,double> 
#define x first 
#define y second 

double cross2( pt o , pt a , pt b ){
	return ( a.x - o.x )*( b.y - o.y ) - ( a.y - o.y )*( b.x - o.x );
} 
pt p[ maxn ];
int n; 
vector<pt> hull; 
void convexhull(){ 
	hull.push_back( p[ 0 ] ); 
	for( int i = 1 ; i < n ; i++ ){ 
		while( hull.size() > 1 && cross2( hull[ hull.size()-2 ] , hull.back() , p[ i ] ) > 0){
			hull.pop_back(); 
		}
		hull.push_back( p[ i ] );
	}
	int hs = hull.size(); 
	for( int i = n-2 ; i >= 0 ; i-- ){ 
		while( hull.size() > hs && cross2( hull[ hull.size()-2 ] , hull.back() , p[ i ] ) > 0){
			hull.pop_back();
		}
		hull.push_back( p[ i ] );
	}
} 
int main(){ 
	cin >> n; 
	for( int i = 0 ; i < n ; i++ ){
		cin >> p[ i ].x >> p[ i ].y;
	}
	sort( p , p+n ); 
	convexhull(); 
	//the first point is repeated at last! 
	hull.pop_back(); 
	cout << hull.size() << endl; 
	int my = 1e6 , mx = 1e6 , ind; 
	for( int i = 0 ; i < hull.size() ; i++ ){
		if( hull[i].y < my ){
			my = hull[i].y , mx = hull[ i ].x , ind = i;
		}
		else if( hull[ i ].y == my && mx > hull[ i ].x ){
			mx = hull[ i ].x , ind = i;
		}
	}
	for( int i = ind , cnt = hull.size() ; cnt ; cnt-- , i = ( i-1 + hull.size() ) % hull.size() ){
		cout << hull[ i ].x << " " << hull[ i ].y << endl;
	}
}
