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<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<list>
#include<queue>
#include<stack>
#include<vector>
#include<set>
#include<map>
#include<bitset>
#include<string>
#define sgn(v) (abs((v))<eps?0:((v)<0?-1:1))
#define sqr(v) ((v)*(v))
#define MP make_pair
#define PB push_back
#define FI first
#define SE second
#define debug 0
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;
typedef pair<int,LL> PIL;
typedef pair<LL,int> PLI;
typedef pair<LL,LL> PLL;
typedef pair<double,int> PDI;
const double eps=1e-9;
const double pi=acos(-1);
const int maxn=200;
struct Point 
{
    double x,y;
    Point(double X=0,double Y=0)
    {
        x=X;y=Y;
    }
    Point operator -(const Point &p)
    {
        return Point(x-p.x,y-p.y);
    }
    Point operator +(const Point &p)
    {
        return Point(x+p.x,y+p.y);
    }
    Point operator *(const double &c)
    {
        return Point(x*c,y*c);
    }
    bool operator <(const Point &p)const
    {
        if(sgn(x-p.x))return x<p.x;
        else return y<p.y;
    }
    bool operator ==(const Point &p)const
    {
        return sgn(x-p.x)==0&&sgn(y-p.y)==0;
    }
    double len()
    {
        return sqrt(sqr(x)+sqr(y));
    }
    double arg()
    {
        return atan2(y,x);
    }
}pt[maxn];
double dot(Point p,Point q)
{
    return p.x*q.x+p.y*q.y;
}
double det(Point p,Point q)
{
    return p.x*q.y-p.y*q.x;
}
struct Segment
{
    Point st,ed;
};
Point Insect(Segment &p,Segment &q)
{
    double u=det(p.ed-p.st,q.st-p.st),v=det(p.st-p.ed,q.ed-p.st);
    return Point((q.st.x*v+q.ed.x*u)/(u+v),(q.st.y*v+q.ed.y*u)/(u+v));
}
vector<PDI> evs;
set<PII> s;
const int maxv=101*101;
const int maxe=maxv*6;
struct Edge
{
    int v,next;
}edge[maxe*2];
int head[maxv],ne,Next[maxe];
void add(int u,int v)
{
    if(s.find(MP(u,v))==s.end())
    {
        s.insert(MP(u,v));
        edge[ne].v=v;
        edge[ne].next=head[u];
        head[u]=ne++;
    }
}
vector<Point> tp;
bool vis[maxe];

bool Onsegment(Point p,Point &a,Point &b)
{
    double length=(a-p).len();
    if (sgn(length)==0) return true;
	length=(length+(b-p).len())/2;
    return sgn(det(b - p, a - p)/length) == 0 && sgn(dot(b - p, a - p)/length) <= 0;
}
int main()
{
    int i,j,n;
    double ans=0,ret;
    Segment now,tmp;
    Point cp;
    scanf("%d",&n);
    for(i=0;i<n;++i)
    {
        scanf("%lf%lf",&pt[i].x,&pt[i].y);
        tp.push_back(pt[i]);
    }
    for(i=0;i+1<n;++i)
    {
        now.st=pt[i];now.ed=pt[i+1];
        for(j=i+1;j+1<n;++j)
        {
            tmp.st=pt[j];tmp.ed=pt[j+1];
            if(sgn(det(tmp.ed-tmp.st,now.ed-now.st)))
            {
                cp=Insect(now,tmp);
                if(sgn(dot(tmp.ed-cp,cp-tmp.st))>0&&sgn(dot(now.ed-cp,cp-now.st))>0)
                    tp.push_back(cp);
            }
        }
    }
    sort(tp.begin(),tp.end());
    tp.erase(unique(tp.begin(),tp.end()),tp.end());
    ne=0;
    memset(head,-1,sizeof(head));
    for(j=0;j+1<n;++j)
    {
        evs.clear();
        for(i=0;i<tp.size();++i)
        {
            now.st=pt[j];now.ed=pt[j+1];
			if(Onsegment(tp[i],pt[j],pt[j+1]))
                evs.PB(MP((tp[i]-now.st).len(),i));
        }
        sort(evs.begin(),evs.end());
        for(i=0;i+1<evs.size();++i)
            add(evs[i].SE,evs[i+1].SE),
            add(evs[i+1].SE,evs[i].SE);
    }
    for(i=0;i<tp.size();++i)
    {
        evs.clear();
        for(j=head[i];j!=-1;j=edge[j].next)
            evs.PB(MP( (tp[edge[j].v]-tp[i]).arg(),j));
        sort(evs.begin(),evs.end());
        for(j=0;j<evs.size();++j)
            Next[evs[(j+1)%evs.size()].SE^1]=evs[j].SE;
    }
    for(i=0;i<ne;++i)
        if(!vis[i])
        {
            j=i;
            ret=0;
            while(!vis[j])
            {
                vis[j]=true;
                ret+=det(tp[edge[j^1].v],tp[edge[j].v]);
                j=Next[j];
            }
            if(j==i&&sgn(ret)>0)
                ans+=ret/2;
        }
    printf("%.9f\n",ans);
    return 0;
}