#include<cstdio>
#include<cstring>
#include<map>
#include<queue>
#include<vector>
#include<string>
#include<cmath>
#include<iostream>
#include<algorithm>

using namespace std;

#define MP make_pair
#define PB push_back
#define foreach(e,x) for(__typedef(x.begin()) e=x.begin(); e!=x.end(); ++e)

typedef long long LL;
typedef vector<int> VI;
typedef pair<int, int> mapII;

const int MAX_N = 100000 + 10;
const double EPS = 1e-7;

int sign(double x)
{
	return x < - EPS ? -1 : x > EPS;
}

struct Point
{
	double x, y;
	Point() {}
	Point(double _x, double _y) {
		x = _x; y = _y;
	}
	void read() {
		scanf("%lf%lf", &x, &y);
	}
	void write() {
		printf("%.10f %.10f\n", x, y);
	}
	Point operator + (const Point &that) const {
		return Point(x + that.x, y + that.y);
	}
	Point operator - (const Point &that) const {
		return Point(x - that.x, y - that.y);
	}
	Point operator / (const double &that) const {
		return Point(x / that, y / that);
	}
	Point operator * (const double &that) const {
		return Point(x * that, y * that);
	}
	int operator < (const Point &that) const {
		if (sign(x - that.x)) return sign(x - that.x) < 0;
		return sign(y - that.y) < 0;
	}
	double det(const Point &that) const {
		return x * that.y - y * that.x;
	}
	double polar() {
		return atan2(y, x);
	}
	int on(Point u, Point v) {
		return sign((u - *this).det(v - *this)) == 0 && sign(x - u.x) * sign(x - v.x) <= 0 && sign(y - u.y) * sign(y - v.y) <= 0;
	}
};

#define cross(p1,p2,p3) ((p2.x-p1.x)*(p3.y-p1.y)-(p3.x-p1.x)*(p2.y-p1.y))

#define crossOp(p1,p2,p3) sign(cross(p1,p2,p3))

int N;
int totId;
map<Point, int> points;
Point poly[MAX_N], a[MAX_N], origin;
int tot;
int sqn[MAX_N];
vector< pair<int, int> > adj[MAX_N];

Point isSS(Point u1, Point u2, Point v1, Point v2)
{
	double a1 = cross(v1, v2, u1), a2 = -cross(v1, v2, u2);
	return (u1 * a2 + u2 * a1) / (a1 + a2);
}

void getIntersection(Point u1, Point u2, Point v1, Point v2)
{
	if (sign((u2 - u1).det(v2 - v1)) == 0) return;
	if (crossOp(u1, u2, v1) * crossOp(u1, u2, v2) <= 0 && crossOp(v1, v2, u1) * crossOp(v1, v2, u2) <= 0) {
		Point ss = isSS(u1, u2, v1, v2);
		if (points.find(ss) == points.end()) {
			a[totId] = ss;
			points[ss] = totId ++;
		}
	}
}

int intersect(Point u1, Point u2, Point v1, Point v2)
{
	if (sign((u2 - u1).det(v2 - v1)) == 0) return false;
	return (crossOp(u1, u2, v1) * crossOp(u1, u2, v2) < 0 && crossOp(v1, v2, u1) * crossOp(v1, v2, u2) < 0);
}

int cmp(const pair<int, int> &u, const pair<int, int> v)
{
	return (a[u.first] - origin).polar() < (a[v.first] - origin).polar();
}

int cmp2(const int &u, const int &v)
{
	return a[u] < a[v];
}

void dfs(int u, int e)
{
	if (adj[u][e].second) return;
	adj[u][e].second = true;
	sqn[tot ++] = u;
	int v = adj[u][e].first;
	for(int i = 0; i < (int)adj[v].size(); ++ i) {
		if (adj[v][i].first == u) {
			dfs(v, (i - 1 + adj[v].size()) % adj[v].size());
			return;
		}
	}
}

Point pointSqn[MAX_N];

void insert(Point p)
{
	if (points.find(p) == points.end()) {
		a[totId] = p;
		points[p] = totId ++;
	}
	sqn[tot ++] = points[p];
}

void solve()
{
	scanf("%d", &N);
	for(int i = 0; i < N; ++ i) {
		poly[i].read();
	}
	Point u1, u2, v1, v2;
	totId = 0;

	for(int i = 0; i < N - 1; ++ i) {
		u1 = poly[i]; u2 = poly[i + 1];
		tot = 0;
		for(int j = 0; j < N - 1; ++ j) {
			v1 = poly[j]; v2 = poly[j + 1];
			if (intersect(u1, u2, v1, v2)) {
				insert(isSS(u1, u2, v1, v2));
			}
			if (v1.on(u1, u2)) {
				insert(v1);
			}
			if (v2.on(u1, u2)) {
				insert(v2);
			}
		}
		sort(sqn, sqn + tot, cmp2);
		tot = unique(sqn, sqn + tot) - sqn;
		/*
		cout << "show line " << endl;
		u1.write(); u2.write();
		cout << endl;
		*/
		for(int j = 0; j < tot; ++ j) {
			//a[sqn[j]].write();
			if (j) adj[sqn[j]].push_back(make_pair(sqn[j - 1], 0));
			if (j + 1 < tot) adj[sqn[j]].push_back(make_pair(sqn[j + 1], 0));
		}
		//cout << "show over" << endl;
	}

	for(int i = 0; i < totId; ++ i) {
		origin = a[i];
		sort(adj[i].begin(), adj[i].end(), cmp);
		adj[i].resize(unique(adj[i].begin(), adj[i].end()) - adj[i].begin());
	}

	/*
	for(int i = 0; i < totId; ++ i) {
		cout << "show " << endl;
		a[i].write();
		for(int j = 0; j < adj[i].size(); ++ j) {
			a[adj[i][j].first].write();
		}
		cout << endl;
	}
	*/
	double ans = 0, area;
	for(int i = 0; i < totId; ++ i) {
		for(int j = 0; j < (int)adj[i].size(); ++ j) {
			if (adj[i][j].second) continue;
			tot = 0;
			dfs(i, j);
			area = 0;
			//cout << "show area" << endl;
			for(int k = 0; k < tot; ++ k) {
				//a[sqn[k]].write();
				area += a[sqn[k]].det(a[sqn[(k + 1) % tot]]);
			}
			//cout << endl;
			if (area < 0) ans += - area;
		}
	}
	printf("%.10f\n", ans * 0.5);
}

int main()
{
	solve();
	return 0;
}

Measured memory_bytes: 6236