#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <vector>
#include <math.h>
#include <iostream>
#define eps 1e-7
#define ld double

using namespace std;

int bj(ld a, ld b);

struct point
{
    ld x, y;
}pNow[20005], ps[20005], p[20005], ret;

int cmp(point a, point b)
{
    return (bj(a.x, b.x) == -1 || (bj(a.x, b.x) == 0 && bj(a.y, b.y) == -1));
}

int n, i, j, tot, tag, Now1, Now2;
int sel, sel2, k, st, t2;
int Ok[20005][105], Num[20005];
ld Ans, anss;
vector <int> Edge[20005];

ld Cross(ld x1, ld y1, ld x2, ld y2);
ld Cross(point a, point b, point c);
int xj(point p1, point p2, point p3, point p4);
int AddPoint(point Now);
int InLine(point a, point b, point c);

int main()
{
    cin >> n;
    for (i = 1; i <= n; i++)
        cin >> ps[i].x >> ps[i].y;
    tot = 0;
    for (i = 1; i < n; i++)
    {
        t2 = 0;
        for (j = 1; j < n; j++)
        {
            tag = 0;
            if (InLine(ps[j], ps[i], ps[i + 1]) == 1)
                pNow[++t2] = ps[j], tag = 1;
            if (InLine(ps[j + 1], ps[i], ps[i + 1]) == 1)
                pNow[++t2] = ps[j + 1], tag = 1;
            if (tag == 1)
                continue;
            if (xj(ps[j], ps[j + 1], ps[i], ps[i + 1]) == 1){
                pNow[++t2] = ret;
//                printf("%d %d %d %d\n", j, j + 1, i, i + 1);
            }
        }

        sort(pNow + 1, pNow + t2 + 1, cmp);
        for (j = 1; j <= t2; j++)
            Num[j] = AddPoint(pNow[j]);
        for (j = 1; j < t2; j++)
            if (Num[j] != Num[j + 1])
            	Edge[Num[j]].push_back(Num[j + 1]), Edge[Num[j + 1]].push_back(Num[j]);
    }
    
    for (i = 1; i <= tot; i++)
    	sort(Edge[i].begin(), Edge[i].end()), Edge[i].erase(unique(Edge[i].begin(), Edge[i].end()), Edge[i].end());
    /*printf("%d\n",tot);
    for (i = 1; i <= tot; i++)
    {
        printf("%lf %lf\n", p[i].x, p[i].y);
        for (j = 0; j < Edge[i].size(); j++)
            printf("%d ", Edge[i][j]);
        printf("\n");
    }*/

    Ans = 0;
    while (1)
    {
        for (i = 1; i <= tot; i++)
        {
            tag = 0;
            int ss = Edge[i].size();
            for (j = 0; j < ss; j++)
                if (Ok[i][j] == 0)
                {
                    tag = 1;
                    break;
                }

            if (tag == 1)
                break;
        }

        if (tag == 0)
            break;
        st = i;
        Now1 = i;
        Now2 = Edge[i][j];
        //printf("%d %d ", Now1, Now2);
        anss=0;
        Ok[i][j] = 1;
        while (1)
        {
            int ss = Edge[Now2].size(), ttt;
            sel = 0, sel2 = 0;
            for (i = 0; i < ss; i++)
            {
                k = Edge[Now2][i];
                if (k == Now1)
                {
                    ttt = i;
                    continue;
                }

                if (sel == 0)
                    sel = k, sel2 = i;
                else
                {
					if (bj(Cross(p[Now2], p[Now1], p[sel]), 0) >= 0)
					{
						if (bj(Cross(p[Now2], p[Now1], p[k]), 0) < 0)
							sel = k, sel2 = i;
						if (bj(Cross(p[Now2], p[sel], p[k]), 0) > 0)
							sel = k, sel2 = i;
					}
					
					else
					{
						if (bj(Cross(p[Now2], p[Now1], p[k]), 0) >= 0)
							continue;
						if (bj(Cross(p[Now2], p[sel], p[k]), 0) > 0)
							sel = k, sel2 = i;
					}
				}
            }

            if (sel == 0)
                sel = Now1, sel2 = ttt;
            if (Ok[Now2][sel2] == 1)
            	break;
            Ok[Now2][sel2] = 1;
            anss += (Cross(p[st], p[Now2], p[sel]));
            Now1 = Now2, Now2 = sel;
            //printf("%d ", Now2);
        }
         
        anss /= 2.0;
        if (anss < 0)
        	Ans -= anss;
        else
        	Ans += anss;
       // printf("%.5f\n",Ans);
    }
    
    cout.setf(ios::fixed);
    cout.precision(10); 
    cout << (Ans / 2.0) << endl;
    return 0;
}

int bj(ld a, ld b)
{
    if (a - b >  0 - eps && a - b < eps)
        return 0;
    if (a > b)
        return 1;
    return - 1;
}

ld Cross(ld x1, ld y1, ld x2, ld y2)
{
    return x1 * y2 - x2 * y1;
}

ld Cross(point a, point b, point c)
{
    return Cross(b.x - a.x, b.y - a.y, c.x - a.x, c.y - a.y);
}

int InLine(point a, point b, point c)
{
    if (bj(Cross(a, b, c), 0) != 0)
        return 0;
    if (bj(a.x, min(b.x, c.x)) >= 0 && bj(a.x, max(b.x, c.x)) <= 0 && bj(a.y, min(b.y, c.y)) >= 0 && bj(a.y, max(b.y, c.y)) <= 0)
        return 1;
    return 0;
}

int xj(point p1, point p2, point p3, point p4)
{
    ld s1, s2, s3, s4;
    int k1, k2, k3, k4;
    k1 = bj(s1 = Cross(p1, p2, p3), 0);
    k2 = bj(s2 = Cross(p1, p2, p4), 0);
    k3 = bj(s3 = Cross(p3, p4, p1), 0);
    k4 = bj(s4 = Cross(p3, p4, p2), 0);
    if ((k1 ^ k2) != -2 || (k3 ^ k4) != -2)
        return 0;
    ret.x = (p4.x * s1 - p3.x * s2) / (s1 - s2);
    ret.y = (p4.y * s1 - p3.y * s2) / (s1 - s2);
    return 1;
}

int AddPoint(point Now)
{
    int i;
    for (i = 1; i <= tot; i++)
        if (bj(p[i].x, Now.x) == 0 && bj(p[i].y, Now.y) == 0)
            return i;
    p[++tot] = Now;
    return tot;
}

Measured memory_bytes: 2980