#define _USE_MATH_DEFINES
#include <algorithm>
#include <array>
#include <climits>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>

using int32 = std::int_fast32_t;
using int64 = std::int_fast64_t;
using uint32 = std::uint_fast32_t;
using uint64 = std::uint_fast64_t;
using intl32 = std::int_least32_t;
using intl64 = std::int_least64_t;
using uintl32 = std::uint_least32_t;
using uintl64 = std::uint_least64_t;

static constexpr long double PI = 3.1415926535897932;
struct angle {
	long double r;
	angle() :r(0) {}
	angle(long double r_) :r(arr(std::fmod(r_, 2.0 * PI) + 2.0 * PI)) {}
	static long double arr(const long double &o) { return o < 2.0 * PI - eps ? o : o - 2.0 * PI; }
	static angle make(const long double &o) { angle ret;ret.r = o;return ret; }
	const angle operator+(const angle &o)const { return make(arr(r + o.r)); }
	const angle operator-(const angle &o)const { return make(arr(r - o.r + 2.0 * PI)); }
	const angle operator*(const long double &o)const { return angle(r * o); }
	const angle operator/(const long double &o)const { return angle(r / o); }
	angle &operator+=(const angle &o) { return *this = *this + o; }
	angle &operator-=(const angle &o) { return *this = *this - o; }
	angle &operator*=(const long double &o) { return *this = *this * o; }
	angle &operator/=(const long double &o) { return *this = *this / o; }
	const angle operator~()const { return make(arr(3.0 * PI - r)); }
	const angle operator-()const { return make(arr(2.0 * PI - r)); }
	const bool operator==(const angle &o)const { return std::abs(r - o.r) <= eps; }
	const bool operator!=(const angle &o)const { return std::abs(r - o.r) > eps; }
	const bool operator< (const angle &o)const { return r <  o.r; }
	const bool operator<=(const angle &o)const { return r <= o.r; }
	const bool operator> (const angle &o)const { return r >  o.r; }
	const bool operator>=(const angle &o)const { return r >= o.r; }
	explicit operator bool()const { return r > eps; }
	explicit operator long double()const { return r; }
	const long double sin()const { return std::sin(r); }
	const long double cos()const { return std::cos(r); }

	const long double degree()const { return r*(180.0 / PI); }
	const long double ratio()const { return r / (2.0 * PI); }
private:
	static constexpr long double eps = 0.000000001;
};
angle operator"" _deg(long  double x) { return angle(x*(PI / 180.0)); }
angle operator"" _rat(long double x) { return angle(x * 2.0 * PI); }
angle operator"" _rad(long double x) { return angle(x); }
struct pvec {
	static constexpr long double eps = 0.0000000001;
	long double x, y;
	pvec() :x(0), y(0) {}
	pvec(long double x_, long double y_) :x(x_), y(y_) {}
	pvec(long double abs_, angle r) :x(abs_*r.cos()), y(abs_*r.sin()) {}
	const pvec operator+(const pvec &o)const { return pvec(x + o.x, y + o.y); }
	const pvec operator-(const pvec &o)const { return pvec(x - o.x, y - o.y); }
	const pvec operator*(const pvec &o)const { return pvec(x*o.x - y*o.y, x*o.y + y*o.x); }
	const pvec operator/(const pvec &o)const { return pvec(x*o.x + y*o.y, y*o.x - x*o.y) / abs2(); }
	const pvec operator*(const long double &o)const { return pvec(x * o, y * o); }
	const pvec operator/(const long double &o)const { return pvec(x / o, y / o); }
	pvec &operator+=(const pvec &o) { return *this = *this + o; }
	pvec &operator-=(const pvec &o) { return *this = *this - o; }
	pvec &operator*=(const pvec &o) { return *this = *this * o; }
	pvec &operator/=(const pvec &o) { return *this = *this / o; }
	pvec &operator*=(const long double &o) { return *this = *this * o; }
	pvec &operator/=(const long double &o) { return *this = *this / o; }

	const pvec operator+()const { return *this; }
	const pvec operator-()const { return pvec(-x, -y); }
	const pvec operator~()const { return pvec(x, -y); }

	explicit operator bool()const { return std::abs(x) > eps || std::abs(y) > eps; }
	const bool operator==(const pvec &o)const { return std::abs(x - o.x) <= eps&&std::abs(y - o.y) <= eps; }
	const bool operator!=(const pvec &o)const { return std::abs(x - o.x) > eps || std::abs(y - o.y) > eps; }

	const long double abs()const { return mysqrt(abs2()); }
	const long double abs2()const { return x*x + y*y; }
	const angle arg()const {
		if (x > eps) return angle(std::atan(y / x));
		if (x < eps) return angle(std::atan(y / x) + PI);
		return angle();
	}
	static const long double dot(const pvec &l, const pvec &r) { return l.x*r.x + l.y*r.y; }
	static const long double cross(const pvec &l, const pvec &r) { return l.x*r.y - l.y*r.x; }

	static const bool C_x(const pvec &l, const pvec &r) {
		if (l.x != r.x) return l.x < r.x;
		return l.y < r.y;
	}
	friend std::istream &operator>>(std::istream &is, pvec &o) {
		long double x_, y_;is >> x_ >> y_;o = pvec(x_, y_);return (is);
	}
private:
	static const long double mysqrt(const long double &x) {
		long double h = 0.5*x;
		std::uint_fast64_t t = 0x5FE6EB50C7B537AAl
			- (*(std::uint_fast64_t*)&x >> 1);
		long double r = *(long double*)&t;
		r *= 1.5 - h*r*r;
		r *= 1.5 - h*r*r;
		r *= 1.5 - h*r*r;
		return r*x;
	}
};

std::vector<pvec> convex_hull(std::vector<pvec> &points) {
	static constexpr long double eps = 0;
	std::sort(points.begin(), points.end(), pvec::C_x);
	uint32 k = 0;
	const uint32 n = points.size();
	std::vector<pvec> ret(n * 2);
	for (uint32 i = 0;i < n;++i) {
		while (k > 1 && pvec::cross(ret[k - 1] - ret[k - 2],
			points[i] - ret[k - 1]) < -eps)--k;
		ret[k++] = points[i];
	}
	for (uint32 i = n - 2, t = k;~i;--i) {
		while (k > t && pvec::cross(ret[k - 1] - ret[k - 2],
			points[i] - ret[k - 1]) < -eps)--k;
		ret[k++] = points[i];
	}
	ret.resize(k - 1);
	return ret;
}
int main(void) {
	//std::ios::sync_with_stdio(false);
	//std::cin.tie(0);
	uint32 n;
	std::cin >> n;
	std::vector<pvec> p(n);
	for (uint32 i = 0;i < n;++i) {
		std::cin >> p[i];
	}
	p = convex_hull(p);
	std::cout << p.size() << "\n";
	double min = 1001;
	uint32 mindex;
	for (auto itr = p.begin();itr != p.end();++itr) {
		if (min > itr->y) {
			mindex = itr - p.begin();
			min = itr->y;
		}
	}
	for (uint32 i = mindex;i < p.size();++i) {
		std::cout << p[i].x << " " << p[i].y << "\n";
	}
	for (uint32 i = 0;i < mindex;++i) {
		std::cout << p[i].x << " " << p[i].y << "\n";
	}
	return 0;
}


Measured memory_bytes: 12328