#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <string>
#include <vector>
#include <cmath>
#define eps 1.0e-8
#define sgn(f) ((f)<(-eps)?-1:((f)>eps))
using namespace std;
typedef long double df;
const double pi=acos(-1.0);
struct point
{
    df x,y;
    point(df _x=0,df _y=0):x(_x),y(_y){};
    point operator + (point a) {return point(x+a.x, y+a.y);}
    point operator - (point a) {return point(x-a.x, y-a.y);}
    point operator * (df p) {return point(x*p, y*p);}
    point operator / (df p) {return point(x/p, y/p);}
    bool operator == (point a) {return sgn(x-a.x)==0&&sgn(y-a.y)==0;}
    bool operator < (const point a) const {return (sgn(x-a.x)<0) || ((sgn(x-a.x)==0)&&(sgn(y-a.y)<0));}
};
typedef point Vector;
df dmult(Vector a,Vector b) {return a.x*b.x+a.y*b.y;}
df xmult(Vector a,Vector b) {return a.x*b.y-a.y*b.x;}
df xmult(point a,point b,point o) {return (a.x-o.x)*(b.y-o.y)-(a.y-o.y)*(b.x-o.x);}
df dis(Vector a) {return sqrt(a.x*a.x+a.y*a.y);}
df dis(point a,point b) {return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}
df angle(Vector v) {return atan2(v.y,v.x);}
df RelativeAngle(Vector v,Vector u)
{
    df c=dmult(v,u)/sqrt((v.x*v.x+v.y*v.y)*(u.x*u.x+u.y*u.y));
    //if(sgn(c-1)>0) c=1;
    //if(sgn(c+1)<0) c=-1;
	df angle=acos(c);
	if(sgn(xmult(v,u))<0) angle=2*pi-angle;
	return angle;
}
bool check(point sa,point sb,point ta,point tb)
{
    if(sgn(xmult(sa,sb,ta))*sgn(xmult(sa,sb,tb))!=-1) return false;
    if(sgn(xmult(ta,tb,sa))*sgn(xmult(ta,tb,sb))!=-1) return false;
    return true;
}
bool isonsegment(point a,point b,point c)
{
    if(sgn(xmult(a,b,c))) return false;
    if(sgn(c.x-min(a.x,b.x))<0||sgn(c.x-max(a.x,b.x))>0) return false;
    if(sgn(c.y-min(a.y,b.y))<0||sgn(c.y-max(a.y,b.y))>0) return false;
    return true;
}
int GetLineIntersection(point p,Vector v,point q,Vector w,point &ans)
{
    if(sgn(xmult(v,w))==0)
    {
        if(sgn(xmult(p-q,w))==0) return 2;
        else return 0;
    }
    ans=p+v*xmult(w,p-q)/xmult(v,w);
    return 1;
}

point tp[6666];
int N,cnt,head[6666];
vector< pair<int,int> >g;
struct  edge
{
	int to,nxt;
	bool vis;
	edge() {}
	edge(int a,int b) {to=a;nxt=b;vis=false;}
}e[233333];
void addedge(int a,int b) {e[cnt]=edge(b,head[a]);head[a]=cnt++;}
void init()
{
	N=0;
	cnt=0;
	g.clear();
	memset(head,-1,sizeof(head));
}
void FindBorder(int n,point *p,vector<point>&ans)
{
    //初始化
    ans.clear();
    init();

    //求点去重
    Vector vt[233];
    for(int i=0;i<n;++i) vt[i]=p[i+1]-p[i];
    tp[N++]=p[n];
    for(int i=0;i<n;++i)
	{
	    tp[N++]=p[i];
		for(int j=i+1;j<n;++j)
		{
			if(check(p[i],p[i+1],p[j],p[j+1]))
			{
			    GetLineIntersection(p[i],vt[i],p[j],vt[j],tp[N]);
			    N++;
			}
		}
	}
	sort(tp,tp+N);
	N=unique(tp,tp+N)-tp;

	//建?去重
	for(int i=0;i<n;++i)
	{
		vector< pair<df,int> >q;
		for(int j=0;j<N;++j) if(isonsegment(p[i],p[i+1],tp[j])) q.push_back(make_pair(dis(tp[j]-p[i]),j));
		sort(q.begin(),q.end());
		for(int j=0;j<q.size()-1;++j)
		{
			g.push_back(make_pair(q[j].second,q[j+1].second));
			g.push_back(make_pair(q[j+1].second,q[j].second));
		}
	}
	sort(g.begin(),g.end());
    g.erase(unique(g.begin(),g.end()),g.end());
	for(int i=0;i<g.size();++i) addedge(g[i].first,g[i].second);

	//?似于卷包裹法求?廓
	ans.push_back(tp[0]);
	int from=0,to=e[head[0]].to;
	for(int i=head[0];i!=-1;i=e[i].nxt)
	{
		int v=e[i].to;
		if(angle(tp[v]-tp[0])<angle(tp[to]-tp[0])) to=v;
	}
	while(1)
	{
		int nto=from,idx=0,fromidx=0;
		df angle=1e9;
		for(int i=head[to];i!=-1;i=e[i].nxt)
		{
			int v=e[i].to;
			if(v==from)
			{
				fromidx=i;
				continue;
			}
			if(e[i].vis) continue;
			df nangle=RelativeAngle(tp[from]-tp[to],tp[v]-tp[to]);
			if(nangle<angle)
			{
				nto=v;
				angle=nangle;
				idx=i;
			}
		}
		if(nto==from) idx=fromidx;
		e[idx].vis=true;
		ans.push_back(tp[to]);
		from=to;
		to=nto;
		if(from==0) break;
	};

}
int main ()
{
    int n;
    scanf("%d",&n);
    n--;
    point s[105];
    for(int i=0;i<=n;++i)
    {
        double x,y;
        scanf("%lf%lf",&x,&y);
        s[i].x=x;
        s[i].y=y;
    }
    vector<point>q;
    FindBorder(n,s,q);
    df area=0;
    for(int i=0;i<q.size()-1;++i) area+=xmult(q[i],q[i+1]);
    area*=0.5;
    printf("%.10f\n",(double)area);
    return 0;
}

Measured memory_bytes: 1792