#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES
#include <iostream>
#include <cstdio>
#include <math.h>
#include <algorithm>
#include <vector>
const double EPS = 1e-9;
using namespace std;
class point {
public:
	double x, y;
	point(double a, double b) {
		x = a; y = b;
	}
	point operator - (point v) {
		return point(x - v.x, y - v.y);
	}
	point operator + (point v) {
		return point(x + v.x, y + v.y);
	}
};
class Vector {
public:
	double x, y;
	Vector(double a, double  b) {
		x = a;
		y = b;
	};
	Vector operator * (const Vector &v)const {
		return Vector(x*v.x, y* v.y);
	}
	Vector operator * (double a) {
		return Vector(x * a, y * a);
	}
	Vector operator - (Vector v) {
		return Vector(x - v.x, y - v.y);
	}
	Vector operator + (Vector v) {
		return Vector(x + v.x, y + v.y);
	}
};
typedef vector<Vector> polygon;
class circle {
public:
	point p;
	double r;
	circle(point a, double b) : p(a), r(b) {};

};
inline double dot(Vector v1, Vector v2) {
	return v1.x*v2.x + v1.y*v2.y;
}
inline double squ(Vector v) {
	return v.x*v.x + v.y*v.y;
}
inline double norm(Vector v) {
	return sqrt(squ(v));
}
inline void printv(Vector v) {
	printf("%.10f %.10f\n", v.x, v.y);
}
inline void printpp(pair<point, point> p) {
	printf("%.7f %.7f %.7f %.7f", p.first.x, p.first.y, p.second.x, p.second.y);
}
inline void printc(Vector v1, Vector v2) {
	printf("%.10f %.10f %.10f %.10f\n", v1.x, v1.y, v2.x, v2.y);
}
inline void printpg(polygon pg, int min) {
	cout << pg.size() << endl;
	for (int i = min; i < pg.size(); i++)
		//printf("%d %d\n", pg[i].x, pg[i].y);
		cout << pg[i].x << " " << pg[i].y << endl;
	for(int i = 0; i < min; i++) cout << pg[i].x << " " << pg[i].y << endl;
}
inline Vector pro(Vector base, Vector v, Vector be) {
	double a = dot(base, v) / squ(base);
	Vector v1 = base * a;
	return v1 + be;
}
inline Vector ref(Vector v, Vector be) {
	return (v - be)*2 + be;
}
inline double cross(Vector v1, Vector v2) {
	return v1.x*v2.y - v1.y*v2.x;
}
inline int ccw(Vector v1, Vector v2, Vector v3) {
	Vector a = v2 - v1;
	Vector b = v3 - v1;
	if (cross(a, b) < 0.0) return -1;
	else if (cross(a, b) > 0.0) return 1;
	else if (dot(a, b) < 0.0) return -2;
	else if (dot(a, b) > squ(a)) return 2;
	else return 0;
}
inline int inter(Vector v1, Vector v2, Vector v3, Vector v4) {
	return (ccw(v1, v2, v3) * ccw(v1, v2, v4) <= 0) && (ccw(v3, v4, v1) * ccw(v3, v4, v2) <= 0);
}
inline double disPP(Vector v1, Vector v2) {
	return norm(v2 - v1);
}
inline double disLP(Vector v1, Vector v2, Vector v3) {
	Vector a = v2 - v1;
	Vector b = v3 - v1;
	return fabs(cross(a, b) / norm(a));
}
inline double disSP(Vector v1, Vector v2, Vector v3) {
	Vector a = v2 - v1;
	Vector b = v3 - v1;
	Vector c = v1 - v2;
	Vector d = v3 - v2;
	if (dot(a, b) < 0.0) return disPP(v1, v3);
	else if (dot(c, d) < 0.0) return disPP(v2, v3);
	else return disLP(v1, v2, v3);
}
inline double disSS(Vector v1, Vector v2, Vector v3, Vector v4) {
	if (inter(v1, v2, v3, v4)) return 0;
	double a = disSP(v1, v2, v3);
	double b = disSP(v1, v2, v4);
	double c = disSP(v3, v4, v1);
	double d = disSP(v3, v4, v2);
	return min(min(a, b), min(c, d));
}
inline Vector getcross(Vector v1, Vector v2, Vector v3, Vector v4) {
	Vector v5 = pro(v2 - v1, v3 - v1, v1);
	Vector v6 = pro(v2 - v1, v4 - v1, v1);
	double a = disPP(v3, v5);
	double b = disPP(v4, v6);
	Vector vans = (v6 - v5)*a*(1 / (a + b)) + v5;
	return vans;

}
inline pair<Vector, Vector> getccl(double r, Vector o, Vector v1, Vector v2) {
	Vector ev = (v2 - v1)*(1 / norm(v2 - v1));
	Vector pr = pro(v2 - v1, o - v1, v1);
	double l = sqrt(r *r - squ(o - pr));
	Vector ans1 = ev * l + pr;
	Vector ans2 = pr - ev * l;
	if (ans1.x > ans2.x) swap(ans1, ans2);
	else if (ans1.x == ans2.x)
		if (ans1.y > ans2.y) swap(ans1, ans2);
	return make_pair(ans1, ans2);
}
inline pair<point, point> getccc(circle c1, circle c2) {
	Vector v1(c2.p.x - c1.p.x, c2.p.y - c1.p.y);
	double dis = norm(v1);
	double a = acos((dis*dis + c1.r*c1.r - c2.r*c2.r) / (2 * c1.r*dis));
	double b = atan2(c2.p.y - c1.p.y, c2.p.x - c1.p.x);
	point pa(c1.r*cos(a + b), c1.r*sin(a + b));
	point pb(c1.r*cos(b - a), c1.r*sin(b -a));
	point ans1(c1.p + pa);
	point ans2(c1.p + pb);
	if (ans1.x > ans2.x || ((ans1.x == ans2.x) && (ans1.y > ans2.y))) swap(ans1, ans2);
	return make_pair(ans1, ans2);
}
const int num = 100000;
inline bool lessX(const Vector &p1, const Vector &p2) {
	return (p1.x < p2.x) || ((p1.x == p2.x) && (p1.y < p2.y));
}
inline polygon getpg(polygon o) {
	sort(o.begin(), o.end(), lessX);
	polygon t, u;
	t.push_back(o[0]);
	t.push_back(o[1]);
	u.push_back(o[0]);
	u.push_back(o[1]);
	for (int i = 2; i < o.size(); i++) {
		for (int j = t.size(); (t.size() > 1) && (ccw(t[t.size() - 2], t[t.size() - 1], o[i]) == 1); j--)
			t.pop_back();
		t.push_back(o[i]);
	}
	for (int i = 2; i < o.size(); i++) {
		for (int j = u.size(); (u.size() > 1) && (ccw(u[u.size() - 2], u[u.size() - 1], o[i]) == -1); j--) {
			u.pop_back();
		}
		u.push_back(o[i]);
	}
	reverse(t.begin(), t.end());
	for (int i = 1; i < t.size() - 1; i++)
		u.push_back(t[i]);
	return u;
}
int main() {
	int n;
	double x, y;
	polygon o;
	cin >> n;
	for (int i = 0; i < n; i++) {
		cin >> x >> y;
		o.push_back(Vector(x, y));
	}
	polygon pg = getpg(o);
	int min = 0;
	for (int i = 1;  pg[i - 1].y > pg[i].y; i++) {
		min = i;
	}
	printpg(pg, min);
	return 0;
}

Measured memory_bytes: 9380