#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);
}
### Prompt

Generate a cpp solution to the following 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

### Response

```cpp
#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);
}
```