#include <bits/stdc++.h>

using namespace std;

typedef long long int64;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef complex<int64> point;
typedef vector<point> polygon;

int64 dot(point a, point b) { return real(conj(a) * b); }

int64 cross(point a, point b) { return imag(conj(a) * b); }

int64 area2(point a, point b, point c) { return cross(b - a, c - a); }

namespace std
{
	bool operator<(point a, point b)
	{
		if (a.real() != b.real())
			return a.real() < b.real();
		return a.imag() < b.imag();
	}
}

polygon convex_hull(vector<point> &P)
{
	int n = P.size(), k = 0;
	vector<point> h(2 * n);
	sort(P.begin(), P.end());
	for (int i = 0; i < n; h[k++] = P[i++])
		while (k >= 2 && area2(h[k - 2], h[k - 1], P[i]) < 0) --k;
	for (int i = n - 2, t = k + 1; i >= 0; h[k++] = P[i--])
		while (k >= t && area2(h[k - 2], h[k - 1], P[i]) < 0) --k;
	return polygon(h.begin(), h.begin() + k - (k > 1));
}


int main()
{
	ios_base::sync_with_stdio(0);
	cin.tie(0);

	int n; cin >> n;
	polygon v(n);
	for (int i = 0; i < n; ++i){
		int64 x, y; cin >> x >> y;
		v[i] = point(x, y);
	}

	polygon ch = convex_hull(v);
	int idx = 0;
	n = (int)ch.size();
	for (int i = 0; i < n; ++i){
		if (ch[i].imag() < ch[idx].imag()) idx = i;
		else if (ch[i].imag() == ch[idx].imag() && ch[i].real() < ch[idx].real()) idx = i;
	}
	cout << n << endl;
	for (int i = 0; i < n; ++i){
		point cur = ch[(i + idx) % n];
		cout << cur.real() << " " << cur.imag() << endl;
	}

	return 0;
}