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<cmath>
#include<cstdio>
#include<vector>
#include<algorithm>

#define rep(i,n) for(int i=0;i<(n);i++)

using namespace std;

const double EPS=1e-8;
const double INF=1e77;
const double PI=acos(-1);

template<class T>
struct point{
	T x,y;
	point operator+(const point &a)const{ return (point){x+a.x,y+a.y}; }
	point operator-(const point &a)const{ return (point){x-a.x,y-a.y}; }
};

template<class T>
point<T> operator*(T c,const point<T> &a){ return (point<T>){c*a.x,c*a.y}; }

bool operator<(const point<double> &a,const point<double> &b){
	return a.x+EPS<b.x || abs(a.x-b.x)<EPS && a.y+EPS<b.y;
}

bool operator==(const point<double> &a,const point<double> &b){
	return abs(a.x-b.x)<EPS && abs(a.y-b.y)<EPS;
}

template<class T>
struct line{
	point<T> a,b;
};

template<class T>
struct segment{
	point<T> a,b;
	operator line<T>()const{ return (line<double>){a,b}; }
};

template<class T>
struct polygon:vector< point<T> >{
	polygon(){}
	polygon(int n):vector< point<T> >(n){}
};

template<class T>
T dot(const point<T> &a,const point<T> &b){ return a.x*b.x+a.y*b.y; }

template<class T>
T cross(const point<T> &a,const point<T> &b){ return a.x*b.y-a.y*b.x; }

template<class T>
double arg(const point<T> &a){
	double t=atan2(a.y,a.x);
	return t<0?t+2*PI:t;
}

enum{CCW=1,CW=-1,ON=0};
int ccw(const point<double> &a,const point<double> &b,const point<double> &c){
	double rdir=cross(b-a,c-a);
	if(rdir> EPS) return CCW;
	if(rdir<-EPS) return CW;
	return ON;
}

point<double> get_intersect(const line<double> &L1,const line<double> &L2){
	double a1=cross(L1.b-L1.a,L2.b-L2.a);
	double a2=cross(L1.b-L1.a,L1.b-L2.a);
	if(abs(a1)<EPS) return L1.a;
	return L2.a+a2/a1*(L2.b-L2.a);
}

template<class T>
T dist(const point<T> &a,const point<T> &b){
	return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}

bool cover(const segment<double> &S,const point<double> &p){
	return dist(S.a,p)+dist(p,S.b)<dist(S.a,S.b)+EPS;
}

bool intersect(const segment<double> &S1,const segment<double> &S2){
	if(max(S1.a.x,S1.b.x)+EPS<min(S2.a.x,S2.b.x)
	|| max(S1.a.y,S1.b.y)+EPS<min(S2.a.y,S2.b.y)
	|| max(S2.a.x,S2.b.x)+EPS<min(S1.a.x,S1.b.x)
	|| max(S2.a.y,S2.b.y)+EPS<min(S1.a.y,S1.b.y)) return false;
	return ccw(S1.a,S1.b,S2.a)*ccw(S1.a,S1.b,S2.b)<=0
		&& ccw(S2.a,S2.b,S1.a)*ccw(S2.a,S2.b,S1.b)<=0;
}

template<class T>
T area2(const polygon<T> &G){
	int n=G.size();
	T a=0;
	rep(i,n) a+=cross(G[i],G[(i+1)%n]);
	return abs(a);
}

int main(){
	int n; scanf("%d",&n);
	polygon<double> F(n);
	rep(i,n) scanf("%lf%lf",&F[i].x,&F[i].y);

	// arrangement!!!!!!!
	vector< point<double> > P=F;
	rep(i,n-1) for(int j=i+1;j<n-1;j++) {
		segment<double> S1={F[i],F[i+1]};
		segment<double> S2={F[j],F[j+1]};
		if(intersect(S1,S2)){
			P.push_back(get_intersect(S1,S2));
		}
	}
	sort(P.begin(),P.end());
	P.erase(unique(P.begin(),P.end()),P.end());

	int N=P.size();
	vector<int> G[20000];
	rep(i,n-1){
		segment<double> S={F[i],F[i+1]};
		vector< point<double> > Q;
		rep(j,N) if(cover(S,P[j])) Q.push_back(P[j]);
		sort(Q.begin(),Q.end());
		rep(j,(int)Q.size()-1){
			int u=find(P.begin(),P.end(),Q[ j ])-P.begin();
			int v=find(P.begin(),P.end(),Q[j+1])-P.begin();
			G[u].push_back(v);
			G[v].push_back(u);
		}
	}

	// trace
	// 最初の二点を決める
	int u_start0=0;
	rep(u,N) if(P[u].y<P[u_start0].y) u_start0=u;
	int u_start1=-1;
	rep(i,G[u_start0].size()){
		int v=G[u_start0][i];
		if(u_start1==-1 || arg(P[v]-P[u_start0])<arg(P[u_start1]-P[u_start0])) u_start1=v;
	}

	vector<int> path;
	path.push_back(u_start0);
	int u=u_start1,u_prev=u_start0;
	do{
		path.push_back(u);

		double theta=arg(P[u_prev]-P[u]);
		int u_next=-1;
		double theta_next=INF;
		rep(i,G[u].size()){
			int v=G[u][i];
			double theta_tmp=arg(P[v]-P[u]);
			while(theta_tmp<theta+EPS) theta_tmp+=2*PI;
			if(theta_tmp<theta_next){
				theta_next=theta_tmp;
				u_next=v;
			}
		}

		u_prev=u;
		u=u_next;
	}while(u!=u_start1 || u_prev!=u_start0);

	polygon<double> ans;
	rep(i,path.size()) ans.push_back(P[path[i]]);
	printf("%.15f\n",area2(ans)/2);

	return 0;
}