// Задача "Гигантский квадратный коллайдер"
// 4-ая Личная интернет-олимпиада сезона 2008-2009
// Автор задачи:  Владимир Ульянцев, ulyantsev@rain.ifmo.ru
// Автор решения: Владимир Ульянцев, ulyantsev@rain.ifmo.ru

// Решение рассматривает каждую пару точек как сторону квадрата.
// Понятно, что если ответ должен содержать одну точку,
// то в исходном множестве содержится и диагональ и две стороны искомого квадрата
// Как следствие, в данном случае не важно, что достраивать --- диагональ или сторону

// Для поиска точки в исходном множестве используется HashSet

import java.io.*;
import java.math.*;
import java.util.*;

public class collider2_vu implements Runnable {

	public static void main(String[] args) {
		new Thread(new collider2_vu()).start();
	}

	BufferedReader br;

	StringTokenizer st;

	PrintWriter out;

	String FNAME = "collider2_vu".substring(0, "collider2_vu".indexOf('_'));

	public void run() {
		Locale.setDefault(Locale.US);
		try {
			br = new BufferedReader(new FileReader(FNAME + ".in"));
			out = new PrintWriter(FNAME + ".out");
			solve();
			out.close();
		} catch (Throwable e) {
			e.printStackTrace();
			System.exit(239);
		}
	}

	String nextToken() {
		while (st == null || !st.hasMoreTokens()) {
			try {
				st = new StringTokenizer(br.readLine());
			} catch (Exception e) {
				return "0";
			}
		}
		return st.nextToken();
	}

	int nextInt() {
		return Integer.parseInt(nextToken());
	}

	double nextDouble() {
		return Double.parseDouble(nextToken());
	}

	long nextLong() {
		return Long.parseLong(nextToken());
	}

	BigInteger nextBigInteger() {
		return new BigInteger(nextToken());
	}

	void MyAssert(boolean u, String message) {
		if (!u) {
			throw new Error("Assertion failed!!! " + message);
		}
	}

	void inBounds(long x, long l, long r, String name) {
		MyAssert(l <= x && x <= r, name + " is not in bounds!!! " + x
				+ " is not in [" + l + ", " + r + "]");
	}

	class Point {
		int x, y;
		
		Point(int x, int y) {
			this.x = x;
			this.y = y;
		}
		
		public int hashCode() {
			return (int)1e8 * x + y;
		}
		
		public boolean equals(Object o) {
			Point p = (Point)o;
			return (x == p.x) && (y == p.y);
		}
		
		public String toString() {
			return x + " " + y;
		}
	}

	
	void Assertions() {
		inBounds(n, 1, 1500, "n");
		for (int i = 0; i < n; i++) {
			inBounds(pt[i].x, -100000000, 100000000, "Point[" + i + "].x");
			inBounds(pt[i].y, -100000000, 100000000, "Point[" + i + "].y");
			for (int j = 0; j < i; j++) {
				MyAssert(!pt[i].equals(pt[j]), "Point[" + i + "] = Point[" + j
						+ "]");
			}
		}
	}

	int n;
	Point[] pt;
	HashSet<Point> hash;
	ArrayList<Point> ans;
	int ansSize;

	Point rotateCl(Point o, Point p) {
		return new Point(o.x + p.y - o.y, o.y - p.x + o.x);
	}

	Point rotateOvCl(Point o, Point p) {
		return new Point(o.x - p.y + o.y, o.y + p.x - o.x);
	}

	void relaxAns(Point h, Point g) {
		int a = hash.contains(h) ? 0 : 1;
		int b = hash.contains(g) ? 0 : 1;
		
		if (a + b < ansSize) {
			ans = new ArrayList<Point>();
			if (a == 1) {
				ans.add(h);
			}
			if (b == 1) {
				ans.add(g);
			}
			ansSize = ans.size();
		}
	}

	private void solve() throws IOException {
		n = nextInt();
		pt = new Point[n];
		for (int i = 0; i < n; i++) {
			pt[i] = new Point(nextInt(), nextInt());
		}
		Assertions();

		hash = new HashSet<Point>();
		for (Point p : pt) {
			hash.add(p);
		}

		ans = new ArrayList<Point>();
		ansSize = 3;
		ans.add(new Point(pt[0].x + 239, pt[0].y));
		ans.add(new Point(pt[0].x + 239, pt[0].y + 239));
		ans.add(new Point(pt[0].x, pt[0].y + 239));

		for (int i = 0; i < n; i++) {
			for (int j = 0; j < i; j++) {
				relaxAns(rotateCl(pt[i], pt[j]), rotateOvCl(pt[j], pt[i]));
				relaxAns(rotateOvCl(pt[i], pt[j]), rotateCl(pt[j], pt[i]));
			}
		}

		out.println(ans.size());
		for (Point p : ans) {
			out.println(p.toString());
		}
	}
}
