#include <iostream>
#include <complex>
#include <vector>
#include <set>
#include <algorithm>
#include <cstdio>
using namespace std;

const double pi  = M_PI;
const double inf = 1e10;
const double eps = 1e-10;
typedef complex<double> point;

struct line : public vector<point> {
	line(const point& a, const point& b) { push_back(a); push_back(b); }
};

namespace std {
	bool operator<(const point& a, const point& b) {
		if(abs(a.real() - b.real()) > eps) return a.real() < b.real();
		if(abs(a.imag() - b.imag()) > eps) return a.imag() < b.imag();
		return false;
	}
}

point  vec  (const line&  l)                 { return l[1]-l[0]; }
double dot  (const point& a, const point& b) { return (a*conj(b)).real(); }
double cross(const point& a, const point& b) { return (conj(a)*b).imag(); }

int ccw(const point& a, const point& b, const point& c)
{
	point u=b-a, v=c-a;
	if(cross(u,v) > 0 ) return +1;
	if(cross(u,v) < 0 ) return -1;
	if(  dot(u,v) < 0 ) return +2;
	if(abs(u) < abs(v)) return -2;
	return 0;
}

int ccw(const line& s, const point& p) {
	return ccw(s[0], s[1], p);
}

bool intersectSP(const line& s, const point& p) {
	return abs(s[0]-p)+abs(s[1]-p) < abs(s[1]-s[0])+eps;
}

bool intersectSS(const line& s, const line& t) {
	return ccw(s,t[0])*ccw(s,t[1]) <= 0
		&& ccw(t,s[0])*ccw(t,s[1]) <= 0;
}

point crosspoint(const line& l, const line& m) {
	double A = cross(vec(l), vec(m));
	double B = cross(vec(l), l[1]-m[0]);
	if(abs(A) < eps) return m[0];
	return m[0] + B/A*vec(m);
}

struct node
{
	point pos;
	vector<int> to;

	node(const point& p) : pos(p) {}
};

// save1

vector<node> seg_arr(const vector<line>& lines)
{
	set<point> points;
	for(int i=0; i<lines.size(); i++) {
		points.insert(lines[i][0]);
		points.insert(lines[i][1]);
		for(int j=i+1; j<lines.size(); j++) {
			if(intersectSS(lines[i], lines[j])) {
				points.insert( crosspoint(lines[i], lines[j]) );
			}
		}
	}

	vector<node> graph;
	for(set<point>::iterator it=points.begin(); it!=points.end(); it++) {
		graph.push_back( node(*it) );
	}

	for(int i=0; i<lines.size(); i++) {
		vector<pair<double,int> > online;
		for(int j=0; j<graph.size(); j++) {
			if(intersectSP(lines[i], graph[j].pos)) {
				online.push_back( pair<double,int>(abs(lines[i][0]-graph[j].pos), j) );
			}
		}

		sort(online.begin(), online.end());
		for(int j=1; j<online.size(); j++) {
			int a = online[j-1].second;
			int b = online[j  ].second;
			graph[a].to.push_back(b);
			graph[b].to.push_back(a);
		}
	}

	return graph;
}

int main()
{
	int N;
	cin >> N;
	vector<point> points;

	int x,y;
	for(int i=0; i<N; i++) {
		cin >> x >> y;
		points.push_back( point(x,y) );
	}

	vector<line> lines;
	for(int i=1; i<points.size(); i++) {
		lines.push_back( line(points[i-1],points[i]) );
	}

	vector<node> graph = seg_arr(lines);




	int ma; double dist=inf;
	for(int i=0; i<graph.size(); i++) {
		double d = abs(graph[i].pos - point(1e7,1e7));
		if(d<dist) {
			dist = d;
			ma=i;
		}
	}


	double S=0;
	for(int k=0; k<graph[ma].to.size(); k++)
	{
		int mb = graph[ma].to[k];
		set<pair<int,int> > v;

		int a=ma, b=mb;
		double s = 0;
		while(true) {
			v.insert(pair<int,int>(a,b));
			s+=cross(graph[a].pos,graph[b].pos);

			int sc=0; double ang=inf;
			for(int i=0; i<graph[b].to.size(); i++) {
				int c = graph[b].to[i];
				point u = graph[a].pos - graph[b].pos;
				point v = graph[c].pos - graph[b].pos;
				double an = arg(u/v);
				if(an<eps) an+=2*pi;
				if(an<ang) {
					ang=an;
					sc=c;
				}
			}
			a=b; b=sc;
			if(!v.insert(pair<int,int>(a,b)).second) break;
		}
		S = max(S, abs(s/2));
	}

	printf("%.9lf\n", S);
}

Measured memory_bytes: 1632