#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<list>
#include<queue>
#include<stack>
#include<vector>
#include<set>
#include<map>
#include<bitset>
#include<string>
#define sgn(v) (abs((v))<eps?0:((v)<0?-1:1))
#define sqr(v) ((v)*(v))
#define MP make_pair
#define PB push_back
#define FI first
#define SE second
#define debug 0
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;
typedef pair<int,LL> PIL;
typedef pair<LL,int> PLI;
typedef pair<LL,LL> PLL;
typedef pair<double,int> PDI;
const double eps=1e-7;
const double pi=acos(-1);
const int maxn=200;
struct Point 
{
    double x,y;
    Point(double X=0,double Y=0)
    {
        x=X;y=Y;
    }
    Point operator -(const Point &p)
    {
        return Point(x-p.x,y-p.y);
    }
    Point operator +(const Point &p)
    {
        return Point(x+p.x,y+p.y);
    }
    Point operator *(const double &c)
    {
        return Point(x*c,y*c);
    }
    bool operator <(const Point &p)const
    {
        if(sgn(x-p.x))return x<p.x;
        else return y<p.y;
    }
    bool operator ==(const Point &p)const
    {
        return sgn(x-p.x)==0&&sgn(y-p.y)==0;
    }
    double len()
    {
        return sqrt(sqr(x)+sqr(y));
    }
    double arg()
    {
        return atan2(y,x);
    }
}pt[maxn];
double dot(Point p,Point q)
{
    return p.x*q.x+p.y*q.y;
}
double det(Point p,Point q)
{
    return p.x*q.y-p.y*q.x;
}
struct Segment
{
    Point st,ed;
};
Point Insect(Segment &p,Segment &q)
{
    double u=det(p.ed-p.st,q.st-p.st),v=det(p.st-p.ed,q.ed-p.st);
    return Point((q.st.x*v+q.ed.x*u)/(u+v),(q.st.y*v+q.ed.y*u)/(u+v));
}
vector<PDI> evs;
set<PII> s;
const int maxv=101*101;
const int maxe=maxv*6;
struct Edge
{
    int v,next;
}edge[maxe*2];
int head[maxv],ne,Next[maxe];
void add(int u,int v)
{
    if(s.find(MP(u,v))==s.end())
    {
        s.insert(MP(u,v));
        edge[ne].v=v;
        edge[ne].next=head[u];
        head[u]=ne++;
    }
}
vector<Point> tp;
bool vis[maxe];

bool On(Point p,Point &a,Point &b)
{
    double length=(a-p).len();
    if (sgn(length)==0) return true;
    return sgn(det(b - p, a - p)/length) == 0 && sgn(dot(b - p, a - p)) <= 0;
}
int main()
{
    int i,j,n;
    double ans=0,ret;
    Segment now,tmp;
    Point cp;
    scanf("%d",&n);
    for(i=0;i<n;++i)
    {
        scanf("%lf%lf",&pt[i].x,&pt[i].y);
        tp.push_back(pt[i]);
    }
    for(i=0;i+1<n;++i)
    {
        now.st=pt[i];now.ed=pt[i+1];
        for(j=i+1;j+1<n;++j)
        {
            tmp.st=pt[j];tmp.ed=pt[j+1];
            if(sgn(det(tmp.ed-tmp.st,now.ed-now.st)))
            {
                cp=Insect(now,tmp);
                if(sgn(dot(tmp.ed-cp,cp-tmp.st))>0&&sgn(dot(now.ed-cp,cp-now.st))>0)
                    tp.push_back(cp);
            }
        }
    }
    sort(tp.begin(),tp.end());
    tp.erase(unique(tp.begin(),tp.end()),tp.end());
    ne=0;
    memset(head,-1,sizeof(head));
    for(j=0;j+1<n;++j)
    {
        evs.clear();
        for(i=0;i<tp.size();++i)
        {
            now.st=pt[j];now.ed=pt[j+1];
			if(On(tp[i],pt[j],pt[j+1]))
                evs.PB(MP((tp[i]-now.st).len(),i));
        }
        sort(evs.begin(),evs.end());
        for(i=0;i+1<evs.size();++i)
            add(evs[i].SE,evs[i+1].SE),
            add(evs[i+1].SE,evs[i].SE);
    }
    for(i=0;i<tp.size();++i)
    {
        evs.clear();
        for(j=head[i];j!=-1;j=edge[j].next)
            evs.PB(MP( (tp[edge[j].v]-tp[i]).arg(),j));
        sort(evs.begin(),evs.end());
        for(j=0;j<evs.size();++j)
            Next[evs[(j+1)%evs.size()].SE^1]=evs[j].SE;
    }
    for(i=0;i<ne;++i)
        if(!vis[i])
        {
            j=i;
            ret=0;
            while(!vis[j])
            {
                vis[j]=true;
                ret+=det(tp[edge[j^1].v],tp[edge[j].v]);
                j=Next[j];
            }
            if(j==i&&sgn(ret)>0)
                ans+=ret/2;
        }
    printf("%.9f\n",ans);
    return 0;
}

Measured memory_bytes: 2048