#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;
}
