#include <cstdio>
#include <vector>
#include <algorithm>
#include <cmath>

using namespace std;

const double eps = 1e-9;

struct Point {
    double x, y;
    
    Point () : x(0), y(0) {}
    Point (double _x, double _y) : x(_x), y(_y) {}

    Point operator - (const Point & p) const
    {
        return Point(x - p.x, y - p.y);
    }

    Point operator + (const Point & p) const
    {
        return Point(x + p.x, y + p.y);
    }

    Point operator * (double k) const
    {
        return Point(x * k, y * k);
    }

    double operator % (const Point & p) const
    {
        return x * p.x + y * p.y;
    }

    double operator * (const Point & p) const
    {
        return x * p.y - y * p.x;
    }

    bool operator == (const Point & p) const
    {
        return fabs(x - p.x) < eps && fabs(y - p.y) < eps;
    }

    void print() const
    {
        printf("%.10lf %.10lf\n", x, y);
    }
};

struct ComparePointsByDir {
    Point dir;
    ComparePointsByDir(const Point & _dir) : dir(_dir) {}

    bool operator () (const Point & p1, const Point & p2)
    {
        return p1 % dir < p2 % dir;
    }
};

struct ComparePairsByDir {
    ComparePointsByDir comparator;
    ComparePairsByDir(const ComparePointsByDir & _comparator) : comparator(_comparator) {}

    bool operator () (const pair<int, Point> & p1, const pair<int, Point> & p2)
    {
        return comparator(p1.second, p2.second);
    }
};

struct Segment {
    Point p1, p2;
    int i1, i2;

    Segment(const Point & _p1, const Point & _p2, int _i1, int _i2) : p1(_p1), p2(_p2), i1(_i1), i2(_i2) {}
};

struct Ray {
    Point p1, dir;

    Ray(const Point & _p1, const Point & _dir) : p1(_p1), dir(_dir) {}
};

vector <Point> p;
int n;

bool inOneSide(const Ray & ray, int i)
{
    return (ray.dir * (p[(i + n - 1) % n] - p[i])) * (ray.dir * (p[i + 1] - p[i])) > -eps;
}

bool isStopped(const Ray & ray, int i)
{
    Point v1 = p[(i + n - 1) % n] - p[i];
    Point v2 = p[i + 1] - p[i];
    double vmul1 = (ray.dir * v1);
    double vmul2 = (ray.dir * v2);
    double mul = vmul1 * vmul2;
    if (mul < -eps)
        return true;
    if (mul > eps)
        return false;
    if (fabs(vmul1) < eps)
        return ray.dir % v1 < 0 && ray.dir * v2 > 0;
    if (fabs(vmul2) < eps)
        return ray.dir % v2 < 0 && ray.dir * v1 < 0;
    throw 42;
}

bool intersects(const Ray & ray, const Segment & seg, Point & result, bool & stopped)
{
    double vmul = ray.dir * (seg.p2 - seg.p1);
    if (fabs(vmul) < eps)
        return false;

    double tRay = (seg.p1 - ray.p1) * (seg.p2 - seg.p1) / vmul;
    double tSeg = (ray.p1 - seg.p1) * ray.dir / (-vmul);

    if (tRay < eps || tSeg < -eps || tSeg > 1 + eps)
        return false;

    stopped = true;
    if (fabs(tSeg) < eps && !isStopped(ray, seg.i1))
        stopped = false;
    if (fabs(tSeg - 1) < eps && !isStopped(ray, seg.i2))
        stopped = false;
    result = ray.p1 + ray.dir * tRay;
    return true;
}

int main()
{
    freopen("guard.in", "r", stdin);
    freopen("guard.out", "w", stdout);

    scanf("%d", &n);
    for (int i = 0; i < n; ++i)
    {
        double x, y;
        scanf("%lf %lf", &x, &y);
        p.push_back(Point(x, y));
    }
    p.push_back(p[0]);

    vector <Segment> segs;
    for (int i = 0; i < n; ++i)
        segs.push_back(Segment(p[i], p[i + 1], i, (i + 1) % n));

    vector < vector <Point> > points(n);

    for (int i = 0; i < n; ++i)
        for (int j = 0; j < n; ++j)
        {
            if (i == j)
                continue;
            Ray ray(p[i], p[i] - p[j]);
            Point q;
            bool stopped;
            bool ok = true;
            for (int k = 0; k < n; ++k)
                ok &= !intersects(ray, segs[k], q, stopped) || !stopped;

            ray.dir = Point(0, 0) - ray.dir;
            ok &= !isStopped(ray, i);
            if (!ok)
                continue;
          #ifdef DEBUG
            printf("ray %d -> %d\n", i, j);
            fflush(stdout);
          #endif

            points[i].push_back(p[i]);
            points[(i + n - 1) % n].push_back(p[i]);
            ComparePointsByDir comparator(ray.dir);
            Point cur;
            int num = -1;
            vector < pair<int, Point> > inters;
            for (int k = 0; k < n; ++k)
            {
                if (intersects(ray, segs[k], q, stopped))
                {
                    inters.push_back(make_pair(k, q));
                    if (stopped && (num == -1 || comparator(q, cur)))
                    {
                        num = k;
                        cur = q;
                    }
                }
            }
            sort(inters.begin(), inters.end(), ComparePairsByDir(comparator));
            bool end = false;
            for (int i = 0; i < int(inters.size()); ++i)
            {
                if (end && !(inters[i].second == cur))
                    break;
              #ifdef DEBUG
                printf("num = %d  ", inters[i].first);
                inters[i].second.print();
              #endif
                points[inters[i].first].push_back(inters[i].second);
                if (inters[i].second == cur)
                    end = true;
            }                              
        }

    vector <Point> res;
    for (int i = 0; i < n; ++i)
    {
        sort(points[i].begin(), points[i].end(), ComparePointsByDir(p[i + 1] - p[i]));
        points[i].erase(unique(points[i].begin(), points[i].end()), points[i].end());
        if (points[i].size() == 1)
            continue;
        res.insert(res.end(), points[i].begin(), points[i].end());
    }

    res.erase(unique(res.begin(), res.end()), res.end());
    if (res[0] == res.back())
        res.pop_back();

    vector <Point> many = res;
    res.clear();
    res.push_back(many[0]);
    many.push_back(many[0]);
    for (int i = 1; i < int(many.size()) - 1; ++i)
    {
        if (fabs((many[i] - many[i - 1]) * (many[i + 1] - many[i])) > 1e-8)
            res.push_back(many[i]);
    }

    printf("%d\n", int(res.size()));
    for (int i = 0; i < int(res.size()); ++i)
        res[i].print();

    return 0;
}