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<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 99999999999999999
#define MOD 1000000007
//#define EPS 0.000000001
using namespace std;


#define NUM 105
#define EPS 0.00000001

struct Point{
	Point(double arg_x,double arg_y){
		x = arg_x;
		y = arg_y;
	}

	Point(){
		x = y = 0.0;
	}

	Point operator + (Point p){ return Point(x+p.x,y+p.y); }
	Point operator - (Point p){ return Point(x-p.x,y-p.y);}
	Point operator * (double a){ return Point(a*x,a*y); }
	Point operator / (double a){ return Point(x/a,y/a); }

	double abs(){ return sqrt(norm()); }
	double norm(){ return x*x + y*y; }

	bool operator<(const Point &p) const{
		return x != p.x? x < p.x: y < p.y;
	}

	bool operator == (const Point &p) const{
		return fabs(x-p.x) < EPS && fabs(y-p.y) < EPS;
	}

	double x,y;
};

double calc_dist(Point A,Point B){

	return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));
}

typedef Point Vector;
typedef vector<Point> Polygon;


struct Line{
	Point p[2];
	Line(Point p1,Point p2){
		p[0] = p1;
		p[1] = p2;
	}
	Line(){

	}
};

struct Info{
	Info(Point arg_cross_point,int arg_index){

		cross_point.x = arg_cross_point.x;
		cross_point.y = arg_cross_point.y;
		index = arg_index;
	}
	bool operator<(const struct Info &arg) const{
		return cross_point < arg.cross_point;
	}
	bool operator==(const struct Info &arg) const{
		return cross_point == arg.cross_point;
	}

	Point cross_point;
	int index;
};

struct Data{
	Data(){

		current = pre = 0;
	}
	Data(int arg_current,int arg_pre){
		current = arg_current;
		pre = arg_pre;
	}

	int current,pre;
};


int num_base_line;
Line base_line[NUM];
vector<Info> on_segment[NUM];
vector<Point> NODES;
vector<int> G[2*NUM*NUM];
bool visited[2*NUM*NUM];
Polygon p;


int func(double x1,double y1,double x2, double y2, double xp, double yp){
	double naiseki,norm1,norm2,gaiseki;
	norm1 = sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
	norm2 = sqrt((xp-x1)*(xp-x1)+(yp-y1)*(yp-y1));
	naiseki = (xp-x1)*(x2-x1)+(yp-y1)*(y2-y1);
	gaiseki = (x2-x1)*(yp-y1)-(xp-x1)*(y2-y1);
	if(gaiseki > EPS){
		return 1;
	}else if(gaiseki < -EPS){
		return -1;
	}
	if(naiseki < -EPS){
		return 2;
	}

	if(norm1 < norm2){
		return -2;
	}
	return 0;
}

bool is_Cross(Line a,Line b){

	if(func(a.p[0].x,a.p[0].y,a.p[1].x,a.p[1].y,b.p[0].x,b.p[0].y)*
			func(a.p[0].x,a.p[0].y,a.p[1].x,a.p[1].y,b.p[1].x,b.p[1].y) <= 0 &&
			func(b.p[0].x,b.p[0].y,b.p[1].x,b.p[1].y,a.p[0].x,a.p[0].y)*
			func(b.p[0].x,b.p[0].y,b.p[1].x,b.p[1].y,a.p[1].x,a.p[1].y) <= 0){
		return true;
	}
	return false;
}

Point calc_Cross_Point(double x1,double x2,double x3,double x4,double y1,double y2,double y3,double y4){
	Point ret;
	ret.x = ((x2-x1)*(y3*(x4-x3)+x3*(y3-y4))-(x4-x3)*(y1*(x2-x1)+x1*(y1-y2)))/((y2-y1)*(x4-x3)-(y4-y3)*(x2-x1));
	if(x1 != x2){
		ret.y = ((y2-y1)*ret.x+y1*(x2-x1)+x1*(y1-y2))/(x2-x1);
	}else{
		ret.y = ((y4-y3)*ret.x+y3*(x4-x3)+x3*(y3-y4))/(x4-x3);
	}
	return ret;
}

Point calc_Cross_Point(Point a,Point b,Point c,Point d){
	return calc_Cross_Point(a.x,b.x,c.x,d.x,a.y,b.y,c.y,d.y);
}

Point calc_Cross_Point(Line A,Line B){

	return calc_Cross_Point(A.p[0],A.p[1],B.p[0],B.p[1]);
}

double norm(Vector a){
	return a.x*a.x+a.y*a.y;
}

double abs(Vector a){
	return sqrt(norm(a));
}

double cross(Vector a,Vector b){
    return a.x*b.y-a.y*b.x;
}

double dot(Vector a,Vector b){
    return a.x*b.x + a.y*b.y;
}

double calc_S(Polygon g){

	int N = g.size();
	double ret = 0;

	for(int i = 0; i < g.size(); i++){
		ret += cross(g[i],g[(i+1)%N]);
	}
	return ret/2.0;
}

Point calc_minus(Point a,Point b){
    Point ret;

    ret.x = a.x-b.x;
    ret.y = a.y-b.y;

    return ret;
}

double calc_len(Vector a){
    return sqrt(a.x*a.x+a.y*a.y);
}

double getDistanceLP(Line l,Point p){
    return fabs(cross(calc_minus(l.p[1],l.p[0]),calc_minus(p,l.p[0]))/calc_len(calc_minus(l.p[1],l.p[0])));
}

double getDistanceSP(Line l,Point p){
	if(dot(calc_minus(l.p[1],l.p[0]),calc_minus(p,l.p[0])) < 0.0)return calc_len(calc_minus(p,l.p[0]));
	if(dot(calc_minus(l.p[0],l.p[1]),calc_minus(p,l.p[1])) < 0.0)return calc_len(calc_minus(p,l.p[1]));
	return getDistanceLP(l,p);
}

double calc_theta(Vector vec){

	double ret = atan2(vec.y,vec.x);

    if(ret < 0){
    	ret += 2*M_PI;
    }

    return ret;
}

void recursive(int current,int pre,int start,int first_next){

	p.push_back(NODES[current]);

	double min_theta = BIG_NUM;
	double pre_theta = calc_theta(NODES[pre]-NODES[current]);

	int next_node = -1;

	for(int i = 0; i < G[current].size(); i++){

		int tmp_next = G[current][i];

		double	tmp_theta = calc_theta(NODES[tmp_next]-NODES[current]);

		while(tmp_theta < pre_theta+EPS){

			tmp_theta += 2*M_PI;
		}

		if(tmp_theta < min_theta){
			min_theta = tmp_theta;
			next_node = tmp_next;
		}

	}
	if(current == start && next_node == first_next)return;
	recursive(next_node,current,start,first_next);
}

int main(){

	int num_point;

	scanf("%d",&num_point);

	Polygon polygon;

	for(int loop = 0; loop < num_point; loop++){

		Point point;
		scanf("%lf %lf",&point.x,&point.y);

		polygon.push_back(point);
		NODES.push_back(point);
	}

	for(int i = 0; i < num_point-1; i++){

		Point A = polygon[i];
		Point B = polygon[(i+1)%num_point];

		base_line[i].p[0] = A;
		base_line[i].p[1] = B;
	}

	num_base_line = num_point-1;

	for(int i = 0; i < num_base_line-1; i++){
		for(int k = i+1; k < num_base_line; k++){
			if(!is_Cross(base_line[i],base_line[k]))continue;

			if(base_line[i].p[0] == base_line[k].p[0] || base_line[i].p[0] == base_line[k].p[1] ||
					base_line[i].p[1] == base_line[k].p[0] || base_line[i].p[1] == base_line[k].p[1])continue;

			NODES.push_back(calc_Cross_Point(base_line[i],base_line[k]));
		}
	}

	sort(NODES.begin(),NODES.end());
	NODES.erase(unique(NODES.begin(),NODES.end()),NODES.end());

	for(int i = 0; i < num_base_line; i++){
		for(int k = 0; k < NODES.size(); k++){
			if(NODES[k] == base_line[i].p[0] || NODES[k] == base_line[i].p[1]){
				on_segment[i].push_back(Info(NODES[k],k));
				continue;
			}

			if(getDistanceSP(base_line[i],NODES[k]) > EPS)continue;

			on_segment[i].push_back(Info(NODES[k],k));
		}
	}

	for(int i = 0; i < num_base_line; i++){

		sort(on_segment[i].begin(),on_segment[i].end());
		on_segment[i].erase(unique(on_segment[i].begin(),on_segment[i].end()),on_segment[i].end());

		for(int k = 1; k < on_segment[i].size(); k++){

			int from = on_segment[i][k-1].index;
			int to = on_segment[i][k].index;

			G[from].push_back(to);
			G[to].push_back(from);
		}
	}

	double min_y = BIG_NUM;
	int start;

	for(int i = 0; i < NODES.size(); i++){

		if(min_y > NODES[i].y){
			min_y = NODES[i].y;
			start = i;
		}
	}

	int first_next = -1;
	for(int i = 0; i < G[start].size(); i++){

		int tmp_next = G[start][i];

		if(first_next == -1 || calc_theta(NODES[tmp_next]-NODES[start]) < calc_theta(NODES[first_next]-NODES[start])){

			first_next =tmp_next;
		}
	}

	p.push_back(NODES[start]);

	recursive(first_next,start,start,first_next);

	printf("%.10lf\n",calc_S(p));

	return 0;
}