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

//Under construction.

public class guard_ab_wa {
    public static void main(String[] arg) {
        new guard_ab_wa().run();
    }

    StrictScanner in;
    PrintWriter out;

    public void run() {
        try {
            String problemName = this.getClass().getName().split("_")[0];
            in = new StrictScanner(new FileReader(problemName + ".in"));
            out = new PrintWriter(problemName + ".out");
            solve();
        } catch (Throwable e) {
            e.printStackTrace();
            System.exit(-1);
        } finally {
            out.close();
        }
    }

    final int MAXN = 100;
    final int MAX = 10000;

    void solve() throws Exception {
        int n = assertBetween(3, in.loadLine().nextInt(), MAXN, "n");
        BigInteger[][] p = new BigInteger[n][3];
        for (int i = 0; i < n; ++i) {
            p[i][0] = BigInteger.ONE;
            p[i][1] = BigInteger.valueOf(in.loadLine().nextInt());
            p[i][2] = BigInteger.valueOf(in.skipSpace().nextInt());
        }

        BigInteger sq = BigInteger.ZERO;
        for (int i = 0; i < n; ++i) {
            BigInteger[] a = p[i];
            BigInteger[] b = p[(i + 1) % n];
            sq = sq.add(vmul(a, b)[0]);
            assert !isZero(vmul(a, b)) : "Equal points";
            assert !smul(p[(i + 2) % n], vmul(a, b)).equals(BigInteger.ZERO) : "Three sequential points on a line";
            for (int j = 2; j < n - 1; ++j) {
                BigInteger[] c = p[(i + j) % n];
                BigInteger[] d = p[(i + j + 1) % n];
                assert !isZero(vmul(a, c)) : "Equal points";
                assert sign(smul(vmul(a, b), c)) == sign(smul(vmul(a, b), d)) || sign(smul(vmul(c, d), a)) == sign(smul(vmul(c, d), b)) : "Self-crossing";
            }
        }
        assert sq.compareTo(BigInteger.ZERO) <= 0 : "Wrong orientation!";

        long[] sgn = new long[n];

        BigInteger[][] e = new BigInteger[n][];
        BigInteger[][] lsh = new BigInteger[n][];
        BigInteger[][] rsh = new BigInteger[n][];
        for (int i = 0; i < n; ++i) {
            int next = (i + 1) % n;
            e[i] = vmul(p[next], p[i]);
            lsh[i] = qmul(e[i], p[next]);
            rsh[i] = qmul(e[i], p[i]);
        }

        for (int i = 0; i < n; ++i) {
            loop:
            for (int j = 0; j < n; ++j) {
                if (i == j) continue;
                BigInteger[] line = vmul(p[j], p[i]);

                for (int k = 0; k < n; ++k) {
                    sgn[k] = sign(smul(p[k], line));
                }
                BigInteger[] ish = qmul(line, p[i]);
                assert cmp(ish, qmul(line, p[j])) < 0 : "Change the sign";
                BigInteger[] bf = new BigInteger[]{BigInteger.ZERO, BigInteger.ONE.negate()};
                int fi = -1;
                for (int k = 0; k < n; ++k) {
                    int next = (k + 1) % n;
                    BigInteger[] sh = null;
                    if (sgn[k] * sgn[next] < 0) {
                        sh = qmul(line, vmul(line, e[k]));
                    } else if (sgn[k] == 0) {
                        int prev = (k + n - 1) % n;
                        if (sgn[next] * sgn[prev] < 0) {
                            sh = qmul(line, p[k]);
                        } else {
                        	BigInteger[] u = new BigInteger[]{p[k][2].subtract(p[prev][2]), p[k][1].subtract(p[prev][1])};
                        	BigInteger[] v = new BigInteger[]{p[next][2].subtract(p[k][2]), p[next][1].subtract(p[k][1])};
                            if (cmp(u, v) > 0) {
                                sh = qmul(line, p[k]);
                            } else {
                                continue;
                            }
                        }
                    }
                    if (sh != null) {
                        if (cmp(ish, sh) < 0) {
                            continue loop; //Not a ray up to infinity
                        } else if (cmp(sh, bf) > 0) {                            
                            bf = sh;
                            fi = k;
                        }
                    }
                }

                if (fi == -1) {
                    ish = new BigInteger[]{BigInteger.ZERO, BigInteger.ONE.negate()};
                }

                for (int k = 0; k < n; ++k) {
                    if (sgn[k] == 0) {
                        if (cmp(ish, qmul(line, p[k])) <= 0) {
                            lsh[k] = qmul(e[k], p[k]);
                            int prev = (k + n - 1) % n;
                            rsh[prev] = qmul(e[prev], p[k]);
                        }
                    }
                }
                if (fi != -1) {
                    BigInteger[] tsh = qmul(e[fi], vmul(line, e[fi]));
                    if (cmp(lsh[fi], tsh) > 0) {
                        lsh[fi] = tsh;
                    }
                    if (cmp(rsh[fi], tsh) < 0) {
                        rsh[fi] = tsh;
                    }
                }
            }
        }

        BigInteger[][] ans = new BigInteger[2 * n][];
        int m = 0;

        for (int i = 0; i < n; ++i) {
            if (cmp(lsh[i], rsh[i]) < 0) {
                BigInteger[] pl = getPoint(e[i], lsh[i]);
                if (m == 0 || !isZero(vmul(pl, ans[m - 1])) && !isZero(vmul(pl, ans[0]))) {
                    ans[m++] = pl;
                }
                BigInteger[] pr = getPoint(e[i], rsh[i]);
                if (m == 0 || !isZero(vmul(pr, ans[m - 1])) && !isZero(vmul(pr, ans[0]))) {
                    ans[m++] = pr;
                }
            }
        }

        out.println(m);
        for (int i = 0; i < m; ++i) {
            out.println(toString(ans[i]));
        }
    }

    public String toString(BigInteger[] p) {
        return p[1].doubleValue() / p[0].doubleValue() + " " + p[2].doubleValue() / p[0].doubleValue();
    }

    BigInteger[] getPoint(BigInteger[] line, BigInteger[] sh) {
        return vmul(new BigInteger[]{sh[1], sh[0].multiply(line[2]), sh[0].multiply(line[1]).negate()}, line);
    }

    int sign(BigInteger v) {
    	return v.signum();        
    }

    boolean isZero(BigInteger[] a) {
        return sign(a[0]) == 0 && sign(a[1]) == 0 && sign(a[2]) == 0;
    }

    BigInteger smul(BigInteger[] a, BigInteger[] b) {
        return a[0].multiply(b[0]).add(a[1].multiply(b[1])).add(a[2].multiply(b[2]));
    }

    BigInteger[] vmul(BigInteger[] a, BigInteger[] b) {
        return new BigInteger[]{
                a[1].multiply(b[2]).subtract(a[2].multiply(b[1])),
                a[2].multiply(b[0]).subtract(a[0].multiply(b[2])),
                a[0].multiply(b[1]).subtract(a[1].multiply(b[0]))};
    }

    BigInteger[] qmul(BigInteger[] l, BigInteger[] p) {
        return new BigInteger[]{p[0].multiply(BigInteger.valueOf(sign(p[0]))), l[1].multiply(p[2]).subtract(l[2].multiply(p[1])).multiply(BigInteger.valueOf(sign(p[0])))};
    }

    int cmp(BigInteger[] f1, BigInteger[] f2) {
        return sign(f1[1].multiply(f2[0]).subtract(f2[1].multiply(f1[0])));
    }

    int assertBetween(int l, int m, int r, String name) {
        assert l <= m && m <= r : "Variable " + name + " = " + m + " not in bounds [" + l + ", " + r + "]";
        return m;
    }

    class StrictScanner extends BufferedReader {

        private String cs;
        private int cpos;

        public StrictScanner(Reader a) {
            super(a);
        }

        boolean eoln() {
            return cpos == cs.length();
        }

        StrictScanner loadLine() throws IOException {
            assert cs == null || eoln();
            cs = readLine();
            cpos = 0;
            return this;
        }

        char nextChar() {
            return cs.charAt(cpos++);
        }

        String nextToken() {
            StringBuilder sb = new StringBuilder();
            while (cpos < cs.length() && cs.charAt(cpos) != ' ') {
                sb.append(cs.charAt(cpos));
                ++cpos;
            }
            return sb.toString();
        }

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

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

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

        StrictScanner skipSpace() {
            char c = nextChar();
            assert c == ' ';
            return this;
        }
    }
}
