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

using namespace std;

const long double eps = 1e-8;
const long double pi = acos(-1);
int dcmp(long double x)
{
    if (fabs(x) < eps) return 0;
    return x < 0 ? -1 : 1;
}

struct Point
{
    long double x, y;
    Point(long double x = 0, long double y = 0) : x(x), y(y) {}
    bool operator < (const Point& rhs) const
    {
        return x < rhs.x || (x == rhs.x && y < rhs.y);
    }
    bool operator == (const Point& rhs) const
    {
        return dcmp(x - rhs.x) == 0 && dcmp(y - rhs.y) == 0;
    }
};

typedef Point Vector;

Vector operator - (const Point& A, const Point& B)
{
    return Vector(A.x - B.x, A.y - B.y);
}

Vector operator + (const Point& A, const Point& B)
{
    return Vector(A.x + B.x, A.y + B.y);
}

Vector operator * (const Point& A, const long double& B)
{
    return Vector(A.x * B, A.y * B);
}

long double Cross(const Vector& A, const Vector& B)
{
    return A.x * B.y - A.y * B.x;
}

long double Dot(const Vector& A, const Vector& B)
{
    return A.x * B.x + A.y * B.y;
}

long double Length(const Vector& A)
{
    return sqrt(Dot(A, A));
}

long double RelativeAngle(const Vector& A, const Vector& B)
{
    long double c = Dot(A, B) / Length(A) / Length(B);
    if (c > 1) c = 1;
    else if (c < -1) c = -1;
    long double angle = acos(c);
    if (Cross(A, B) < 0) angle = pi * 2 - angle;
    return angle;
}

bool SegmentProperIntersection(Point a1, Point a2, Point b1, Point b2)
{
    long double c1 = Cross(a2 - a1, b1 - a1), c2 = Cross(a2 - a1, b2 - a1),
            c3 = Cross(b2 - b1, a1 - b1), c4 = Cross(b2 - b1, a2 - b1);
    return dcmp(c1) * dcmp(c2) < 0 && dcmp(c3) * dcmp(c4) < 0;
}

Point GetLineIntersection(Point P, Vector v, Point Q, Vector w)
{
    Vector u = P - Q;
    long double t = Cross(w, u) / Cross(v, w);
    return P + v * t;
}

bool OnSegment(Point p, Point a1, Point a2)
{
    return dcmp(Cross(a1 - p, a2 - p)) == 0 && dcmp(Dot(a1 - p, a2 - p)) <= 0;
}

Point s[100];
vector<Point> p;
vector<vector<pair<int, int> > > G;
vector<bool> vis;
int sz = 0;

int main()
{
    int N;
    scanf("%d", &N);
    for (int i = 0; i < N; ++i)
    {
        double x, y;
        scanf("%lf %lf", &x, &y);
        s[i].x = x;
        s[i].y = y;
        p.push_back(s[i]);
    }
    for (int i = 0; i < N - 1; ++i)
    {
        Point a1 = s[i];
        Point a2 = s[i + 1];
        for (int j = i + 1; j < N - 1; ++j)
        {
            Point b1 = s[j];
            Point b2 = s[j + 1];
            if (SegmentProperIntersection(a1, a2, b1, b2))
            {
                p.push_back(GetLineIntersection(a1, a2 - a1, b1, b2 - b1));
            }
        }
    }
    sort(p.begin(), p.end());
    p.erase(unique(p.begin(), p.end()), p.end());
    G.resize(p.size());
    for (int i = 0; i < N - 1; ++i)
    {
        Point a1 = s[i];
        Point a2 = s[i + 1];
        vector<pair<long double, int> > tmp;
        for (int j = 0; j < p.size(); ++j)
        {
            if (OnSegment(p[j], a1, a2))
            {
                tmp.push_back(make_pair(Length(p[j] - a1), j));
            }
        }
        sort(tmp.begin(), tmp.end());
        for (int j = 0; j < tmp.size() - 1; ++j)
        {
            G[tmp[j].second].push_back(make_pair(tmp[j + 1].second, 0));
            G[tmp[j + 1].second].push_back(make_pair(tmp[j].second, 0));
        }
    }
    for (int i = 0; i < p.size(); ++i)
    {
        sort(G[i].begin(), G[i].end());
        G[i].erase(unique(G[i].begin(), G[i].end()), G[i].end());
        for (int j = 0; j < G[i].size(); ++j)
        {
            G[i][j].second = sz++;
        }
    }
    vis.resize(sz, 0);
    int from = 0;
    int to = G[0][0].first;
    for (int i = 1; i < G[0].size(); ++i)
    {
        int v = G[0][i].first;
        if (atan2(p[v].y - p[0].y, p[v].x - p[0].x) <
            atan2(p[to].y - p[0].y, p[to].x - p[0].x))
        {
            to = v;
        }
    }
    long double area = 0;
    do
    {
        int nto = from;
        int fromidx = 0;
        int idx = 0;
        long double angle = 1e9;
        for (int i = 0; i < G[to].size(); ++i)
        {
            int v = G[to][i].first;
            if (v == from)
            {
                fromidx = G[to][i].second;
                continue;
            }
            if (vis[G[to][i].second]) continue;
            long double nangle = RelativeAngle(p[from] - p[to], p[v] - p[to]);
            if (nangle < angle) nto = v, angle = nangle, idx = G[to][i].second;
        }
        if (nto == from) idx = fromidx;
        if (vis[idx]) while (1);
        vis[idx] = true;
        area += Cross(p[from], p[to]) / 2;
        from = to;
        to = nto;
    }
    while (from);
    printf("%.10f\n", (double)area);
    return 0;
}

Measured memory_bytes: 1308