#include <cstdio>           // printf(), scanf()
#include <vector>
#include <algorithm>        // sort(), reverse()

using namespace std;
static const double EPS = 1e-10;

static const int COUNTER_CLOCKWISE = 1;
static const int CLOCKWISE = -1;
static const int ONLINE_BACK = 2;
static const int ONLINE_FRONT = -2;
static const int ON_SEGMENT = 0;

class Point
{
public:
	double x, y;

	Point(int x = 0, int y = 0): x(x), y(y) {}
	Point operator - (Point p) { return Point(x - p.x, y - p.y); }

	bool operator < (const Point &p) const {
		return y != p.y ? y < p.y : x < p.x;
	}
};

typedef Point Vector;
typedef vector<Point> Polygon;

double
norm(Vector a)
{
	return a.x * a.x + a.y * a.y;
}

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

int
ccw(Point p0, Point p1, Point p2)
{
	Vector a = p1 - p0;
	Vector b = p2 - p0;

	if (cross(a, b) > EPS)
		return COUNTER_CLOCKWISE;

	if (cross(a, b) < -EPS)
		return CLOCKWISE;

	if (dot(a, b) < -EPS)
		return ONLINE_BACK;

	if (norm(a) < norm(b))
		return ONLINE_FRONT;

	return ON_SEGMENT;
}

Polygon
andrewScan(Polygon s)
{
	Polygon u, l;
	int res;

	if (s.size() < 3)
		return s;

	sort(s.begin(), s.end()); // x, y ??????????????????????????????
	// x ????°????????????????????????? u ?????????
	u.push_back(s[0]);
	u.push_back(s[1]);

	// x ?????§???????????????????????? l ?????????
	l.push_back(s[s.size() - 1]);
	l.push_back(s[s.size() - 2]);

	// ??????????????¨?????????
	for (unsigned int i = 2; i < s.size(); ++i)
	{
		for (int n = u.size(); n >= 2; --n)
		{
			res = ccw(u[n - 2], u[n - 1], s[i]);
			if (res == CLOCKWISE || res == ONLINE_FRONT)
				break;

			u.pop_back();
		}

		u.push_back(s[i]);
	}

	// ??????????????¨?????????
	for (int i = s.size() - 3; i >= 0; --i)
	{
		for (int n = l.size(); n >= 2; --n)
		{
			res = ccw(l[n - 2], l[n - 1], s[i]);
			if (res == CLOCKWISE || res == ONLINE_FRONT)
				break;

			l.pop_back();
		}

		l.push_back(s[i]);
	}

	// ????¨????????????????????????????????????????????????????
	reverse(l.begin(), l.end());
	for (int i = u.size() - 2; i >= 1; --i)
		l.push_back(u[i]);

	return l;
}

int
main(int argc, char** argv)
{
	int n;
	Polygon s, r;
	Point p;

	scanf("%d", &n);
	while (n--)
	{
		scanf("%lf %lf", &p.x, &p.y);
		s.push_back(p);
	}

	r = andrewScan(s);
	printf("%ld\n", r.size());
	for (unsigned int i = 0; i < r.size(); ++i)
		printf("%.0f %.0f\n", r[i].x, r[i].y);

	return 0;
}