#include <set>
#include <map>
#include <ctime>
#include <cmath>
#include <queue>
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define PII pair<int,int>
#define FOR(i,a,b) for (int i=(a);i<=(b);++i)
#define ROF(i,b,a) for (int i=(b);i>=(a);--i)
typedef long long LL;
inline int read(){
	int x=0,f=1; char ch=getchar();
	while (ch<'0'||ch>'9') { if (ch=='-') f=-1; ch=getchar(); }
	while (ch>='0'&&ch<='9') { x=x*10+ch-'0'; ch=getchar(); }
	return x*f;
}

const int MAXN=300005;
const double eps=1e-8,INF=1e20,PI=3.141592653589793238462;
struct list{
	int l,lt[MAXN],nt[MAXN],x[MAXN];
	void clear(){ l=0; memset(lt,0,sizeof(lt)); }
	void addedge(int a,int b){ l++; nt[l]=lt[a]; lt[a]=l; x[l]=b; }
}E;
struct P{
	double x,y;
	P(double xx=0,double yy=0):x(xx),y(yy){}
	double len()const{ return sqrt(x*x+y*y); }
	P operator +(const P &E)const{ return P(x+E.x,y+E.y); }
	P operator -(const P &E)const{ return P(x-E.x,y-E.y); }
	P operator *(const double &f)const{ return P(x*f,y*f); }
	P operator /(const double &f)const{ return P(x/f,y/f); }
	double operator *(const P &E)const{ return x*E.y-E.x*y; }
	double operator ^(const P &E)const{ return x*E.x+y*E.y; }
	bool operator <(const P &E)const{ return (x<E.x)||(x==E.x&&y<E.y); }
}A[MAXN],B[MAXN];
double arctan(P a){ double ret=atan2(a.y,a.x); return (ret<eps ? ret+PI*2:ret); }
inline double dist(P a,P b){ return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); }
inline double dot(P a,P b,P c){ return (a-c)^(b-c); }
inline double cross(P a,P b,P c){ return (a-c)*(b-c); }
struct line{
	double a,b,c;
	line(double aa=0,double bb=0,double cc=0):a(aa),b(bb),c(cc){}
};
inline line get_line(P u,P v){ return line(v.y-u.y,u.x-v.x,v*u); }
P Cramer(line l1,line l2){
	double det=l1.a*l2.b-l1.b*l2.a;
	if (fabs(det)<=eps) return P(INF,INF);
	return P((-l1.c*l2.b+l1.b*l2.c)/det,(-l1.a*l2.c+l1.c*l2.a)/det);
}
double ans;
int n,m,l,a[MAXN],b[MAXN];
int cmp(int x,int y){ return B[x]<B[y]; }
int main(){
	n=read(); E.clear(); l=0;
	FOR(i,1,n) { A[i].x=read(); A[i].y=read(); }
	FOR(i,1,n-1) {
		m=0;
		FOR(j,1,n-1)
		if (j!=i) {
			P D=Cramer(get_line(A[i],A[i+1]),get_line(A[j],A[j+1]));
			if ((D.x-A[i].x)*(D.x-A[i+1].x)>eps||(D.y-A[i].y)*(D.y-A[i+1].y)>eps) continue;
			if ((D.x-A[j].x)*(D.x-A[j+1].x)>eps||(D.y-A[j].y)*(D.y-A[j+1].y)>eps) continue;
			B[a[++m]=++l]=D;
			FOR(k,1,l-1) if (dist(B[k],B[l])<=eps) { l--; a[m]=k; break; }
			//printf("%d %d %d\n",i,j,a[m]);
		}
		B[a[++m]=++l]=A[i];
		FOR(k,1,l-1) if (dist(B[k],B[l])<=eps) { l--; a[m]=k; break; }
		B[a[++m]=++l]=A[i+1];
		FOR(k,1,l-1) if (dist(B[k],B[l])<=eps) { l--; a[m]=k; break; }
		
		sort(a+1,a+1+m,cmp);
		FOR(i,1,m-1)
		if (dist(B[a[i]],B[a[i+1]])>eps) E.addedge(a[i],a[i+1]),E.addedge(a[i+1],a[i]);
	}
	//FOR(i,1,l) printf("%.3lf %.3lf %d\n",B[i].x,B[i].y,i);
	/*FOR(i,1,l) {
		printf("%d:",i);
		for (int k=E.lt[i];k;k=E.nt[k]) printf("%d ",E.x[k]);
		printf("\n");
	}*/
	int x=1,y,z,s;
	double alpha=0,tmp=0;
	FOR(i,2,l) if (B[i]<B[x]) x=i;
	y=E.x[E.lt[x]]; z=s=x;
	for (int i=E.lt[x];i;i=E.nt[i]) {
		int j=E.x[i];
		if (cross(B[j],B[y],B[x])>eps) y=j;
	}
	ans=0;
	while (1) {
		//printf("%d %d %.10lf\n",x,y,alpha);
		ans+=B[x]*B[y];
		if (y==s) break;
		z=x; x=y; y=E.x[E.lt[x]];
		alpha=arctan(B[y]-B[x])-arctan(B[z]-B[x]);
		if (alpha<=eps) alpha+=PI*2;
		for (int i=E.lt[x];i;i=E.nt[i]) {
			int j=E.x[i];
			tmp=arctan(B[j]-B[x])-arctan(B[z]-B[x]);
			if (tmp<=eps) tmp+=PI*2;
			//printf("%d %.10lf %.10lf %.10lf %.5lf %.10lf %.10lf %.5lf\n",j,tmp,(B[j]-B[x]).x,(B[j]-B[x]).y,arctan((B[j]-B[x])),(B[z]-B[x]).x,(B[z]-B[x]).y,arctan((B[z]-B[x])));
			if (tmp<alpha) {
				alpha=tmp;
				y=j;
			}
		}
	}
	printf("%.10lf\n",fabs(ans)/2);
	
	return 0;
}

/*
5
1 1
2 3
3 4
2 5
4 2

*/

Measured memory_bytes: 14180