#include <bits/stdc++.h>
using namespace std;

const double EPS = 1e-10;
const double PI = acos(-1.0);

int sign(double x) {  //???????????°???????°???????????¢?
    return abs(x) < EPS ? 0 : x < 0 ? -1 : 1;
}

struct Point { //????????????
    double x, y;
    Point(double x=0.0, double y=0.0) : x(x), y(y) {}
    Point operator + (const Point &rhs) const {  //????????????
        return Point(x + rhs.x, y + rhs.y);
    }
    Point operator - (const Point &rhs) const {  //????????????
        return Point(x - rhs.x, y - rhs.y);
    }
    Point operator * (double p) const {  //???????????\??????
        return Point(x * p, y * p);
    }
    Point operator / (double p) const {  //???????????\??????
        return Point(x / p, y / p);
    }
    bool operator < (const Point &rhs) const {  //??????????????????
        return x < rhs.x || (x == rhs.x && y < rhs.y);
    }
    bool operator == (const Point &rhs) const {  //??????????????????
        return sign(x - rhs.x) == 0 && sign(y - rhs.y) == 0;
    }
    void read() {
        scanf("%lf%lf", &x, &y);
    }
    void print() {
        printf("(%.2f, %.2f)\n", x, y);
    }
};
typedef Point Vector;  //???????????????

double dot(Vector A, Vector B) {  //??????????§???????????????????????§??????????????§??????????????????????????????????????§????
    return A.x * B.x + A.y * B.y;
}
double cross(Vector A, Vector B) {  //??????????§??????????????????????????§???¢???????????¢?§????????????????????????????????????????
    return A.x * B.y - A.y * B.x;
}
double polar_angle(Vector A) {  //??????????§?
    return atan2(A.y, A.x);
}
double length(Vector A) {  //???????????????????§?
    return sqrt(dot(A, A));
}
double angle(Vector A, Vector B) {  //????????¬?§?????????¶??????????§?
    return acos(dot(A, B)/length(A)/length(B));
}
Vector rotate(Vector A, double rad) {  //???????????¬????????¶???
    return Vector(A.x*cos(rad)-A.y*sin(rad), A.x*sin(rad)+A.y*cos(rad));
    //????????´?????¬????????¶????????????????????¢??¬??????x'=xcos(theta)+ysin(theta), y'=ycos(theta)-xsin(theta)
}
Vector normal(Vector A) {  //?????????????????????????????????A????????¶??????
    double len = length(A);
    return Vector(-A.y/len, A.x/len);
}

typedef vector<Point> Polygon;  //????????¢?????????????????¨?????°????????????????????¢poly????\????

/*
*????????????????°´?????????Andrew??????????????\??????????????????????????????????????????
*?????????????????????<=????????????????????????<
*??¶??´?????????O(NlogN)
*/
Polygon convex_hull(Polygon P) {
    sort(P.begin(), P.end());  //??????
    P.erase(unique(P.begin(), P.end()), P.end());  //???????????????
    int n = P.size(), k = 0;
    Polygon Q(n*2);
    for (int i=0; i<n; ++i) {
        while (k > 1 && cross(Q[k-1]-Q[k-2], P[i]-Q[k-2]) < 0) k--;
        Q[k++] = P[i];
    }
    for (int t=k, i=n-2; i>=0; --i) {
        while (k > t && cross(Q[k-1]-Q[k-2], P[i]-Q[k-2]) < 0) k--;
        Q[k++] = P[i];
    }
    Q.resize(k-1);
    return Q;
}

int main() {
    int n;
    scanf("%d", &n);
    vector<Point> P;
    for(int i = 0; i < n; i ++) {
        Point p; p.read();
        P.push_back(p);
    }
    Polygon C = convex_hull(P);
   printf("%d\n", C.size());
    int s = 0;
    while(C[s].y > C[s+1].y) s++;
    for(int i = s; i < C.size(); i ++) {
        printf("%.0f %.0f\n", C[i].x, C[i].y);
    }
    for(int i = 0; i < s; i ++) {
        printf("%.0f %.0f\n", C[i].x, C[i].y);
    }

}

Measured memory_bytes: 9176