#include <iostream>
#include <cstdio>
#include <queue>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <climits>
#include <vector>
#include <deque>
#include <set>
#include <map>
#include <list>
#include <stack>
#include <cctype>
#include <bitset>
#include <ctime>
#include <fstream>
#include <iomanip>
using namespace std;
/*
ifstream in("hull.in");
ofstream out("hull.out");
#define cin in
#define cout out
*/
#define MIN(x,y) (((x)<(y))?(x):(y))
#define MAX(x,y) (((x)>(y))?(x):(y))
#define ABS(x) (((x)<0)?(-(x)):(x))
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
const ld EPS = 0.0000001;
const ld PI = 3.141592653589793;
const int MAX_N = 111111;
int N, L, c_hull_ptr = 0;
struct Point{
int x, y;
Point& operator=(const Point& p) {
x = p.x; y = p.y;
return *this;
}
} points[MAX_N], c_hull[MAX_N], P;
bool cmp(const Point& p1, const Point& p2) {
// maybe, float's precision isn't enough?
float deltaY1 = p1.y - P.y, deltaY2 = p2.y - P.y;
float deltaX1 = p1.x - P.y, deltaX2 = p2.x - P.x;
float angle1 = atan2(deltaY1, deltaX1);
float angle2 = atan2(deltaY2, deltaX2);
if(angle1 < 0.0) angle1 += 2.0 * PI;
if(angle2 < 0.0) angle2 += 2.0 * PI;
if(angle1 == angle2)
if(p1.y != p2.y)
return p1.y < p2.y;
else if(p1.x != p2.x)
return p1.x < p2.x;
return angle1 < angle2;
}
void input() { // & searching for the starting point
cin >> N;
P.x = P.y = (1<<31)-1;
for(int i = 0; i < N; ++i) {
cin >> points[i].x >> points[i].y;
if(points[i].y < P.y)
P = points[i];
else if(points[i].y == P.y and points[i].x < P.x)
P = points[i];
}
}
bool left_turn(Point& p1, Point& p2, Point& p3) {
return (p1.x*p2.y + p3.x*p1.y + p2.x*p3.y - p3.x*p2.y - p1.x*p3.y - p2.x*p1.y) > 0;
}
void convex_hull() {
sort(points, points + N, cmp);
points[N++] = points[0];
// inserting first two points
c_hull[c_hull_ptr++] = points[0];
c_hull[c_hull_ptr++] = points[1];
// building convex hull
for(int i = 2; i <= N; ++i) {
if(!left_turn(c_hull[c_hull_ptr - 2], c_hull[c_hull_ptr - 1], points[i]))
c_hull_ptr--;
c_hull[c_hull_ptr++] = points[i];
}
// print result
cout << c_hull_ptr - 1 << '\n';
for(int i = 0; i < c_hull_ptr - 1; ++i)
cout << c_hull[i].x << " " << c_hull[i].y << '\n';
}
int main() {
ios_base::sync_with_stdio(0);
srand(time(0));
input();
convex_hull();
return 0;
}