Problem: You are given one polygonal line, which is a collection of line segments. Your task is to calculate the sum of areas enclosed by the polygonal line.

A point is defined to be "enclosed" if and only if the point is unreachable without crossing at least one line segment from the point at infinity.



Input

The first line contains one integers N (2 ≤ N ≤ 100). N is the number of segments.

Each of the following N lines consists of two integers Xi and Yi (-105 ≤ Xi, Yi ≤ 105, 1 ≤ i ≤ N) which represents a vertex. A polygonal line is the segments which connect (Xj, Yj) and (Xj+1, Yj+1) ((Xj, Yj) ≠ (Xj+1, Yj+1), 1 ≤ j ≤ N-1). The distance between a segment Sj and all vertices except the end points on segment Sj is guaranteed to be greater than 0.01.

Output

Output the answer in a line. The answer may be printed with an arbitrary number of decimal digits, but may not contain an absolute or relative error greater than or equal to 10-6.

Examples

Input

5
0 0
1 1
1 0
0 1
0 0


Output

0.5


Input

5
0 0
1 1
1 0
0 1
1 0


Output

0.25


Input

21
1 1
-1 1
-1 2
-2 2
-2 1
-1 1
-1 -1
-2 -1
-2 -2
-1 -2
-1 -1
1 -1
1 -2
2 -2
2 -1
1 -1
1 1
2 1
2 2
1 2
1 1


Output

8


Input

16
0 0
1 0
1 1
0 1
0 2
0 3
1 3
1 2
2 2
2 3
3 3
3 2
3 1
2 1
2 0
3 0


Output

0


Input

7
26 52
33 12
-51 68
16 61
43 -26
87 24
12 10


Output

2714.840579710

Solution (in CPP):

Solution:
#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;
}