#include<cmath>
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
using namespace std;

const double eps = 1e-6, pi = acos(-1.0);
int sgn(double x){
    if(abs(x) < eps) return 0;
    else return x > 0 ? 1 : -1;
}

struct Point{
    double x, y;
    Point(){};
    Point(double x1, double y1){
        x = x1, y = y1;
    }
};
typedef Point Vector;
Vector operator + (Vector a, Vector b){
    return Vector(a.x + b.x, a.y + b.y);
}
Vector operator - (Vector a, Vector b){
    return Vector(a.x - b.x, a.y - b.y);
}
Vector operator * (Vector a, double b){
    return Vector(a.x * b, a.y * b);
}
double operator * (Vector a, Vector b){
    return a.x * b.x + a.y * b.y;
}
double operator % (Vector a, Vector b){
    return a.x * b.y - a.y * b.x;
}
bool operator == (Point a, Point b){
    return sgn(a.x - b.x) == 0 && sgn(a.y - b.y) == 0;
}

#define MAXN 100010
#define N 200
int n;
Point p[200], pv[MAXN];

struct Edge{
    int next, to;
}e[MAXN << 1];
int head[MAXN], ne, nv;
void add(int a, int b){
    int t = ++ne;
    e[t].to = b, e[t].next = head[a];
    head[a] = t;
}

bool inter(Point p1, Point p2, Point q1, Point q2){
    if(sgn((p1 - p2) % (q1 - q2)) == 0 ) return false;
    int t1 = sgn((p2 - p1) % (q1 - p1)) * sgn((p2 - p1) % (q2 - p1));
    int t2 = sgn((q2 - q1) % (p1 - q1)) * sgn((q2 - q1) % (p2 - q1));
    return t1 <= 0 && t2 <= 0;
}
Point getp(Point p1, Vector v1, Point p2, Vector v2){
    double t = ((p2 - p1) % v2) / (v1 % v2);
    return p1 + v1 * t;
}

vector<Point>seg[N], vp;

bool operator < (const Point a, const Point b){
    if(sgn(a.x - b.x) != 0) return sgn(a.x - b.x) < 0;
    else return sgn(a.y - b.y) < 0;
}
map<Point, int>mto;
set<pair<int,int> >se;
void build_edge(){
    for(int i = 0; i < n - 1; i++){
        seg[i].push_back(p[i]);
        seg[i].push_back(p[i + 1]);
        vp.push_back(p[i]);
        vp.push_back(p[i + 1]);
        for(int j = 0; j < n - 1; j++){
            if(inter(p[i], p[i+1], p[j], p[j+1]) == 0) continue;
            Point x = getp(p[i], p[i+1] - p[i], p[j], p[j+1] - p[j]);
            seg[i].push_back(x);
            vp.push_back(x);
        }
    }
    sort(vp.begin(), vp.end());
    nv = 0;
    for(int i = 0; i < vp.size(); i++){
        if(i > 0 && vp[i] == vp[i-1]) continue;
        mto[vp[i]] = ++nv;
        pv[nv] = vp[i];
    }
    
    for(int i = 1; i <= nv; i++) head[i] = -1;
    ne = 0;
    
    for(int i = 0; i < n - 1; i++){
        sort(seg[i].begin(), seg[i].end());
        for(int j = 1; j < seg[i].size(); j++){
            if(j > 0 && seg[i][j] == seg[i][j-1]) continue;
            int a = mto[seg[i][j]];
            int b = mto[seg[i][j-1]];
            if(a > b) swap(a, b);
            pair<int,int>pa = make_pair(a, b);
            if(se.find(pa) != se.end()) continue;
            se.insert(pa);
            add(a, b);
            add(b, a);
        }
    }
}

double angle(Vector v1, Vector v2){
    double a = atan2(v1.y, v1.x) - atan2(v2.y, v2.x);
    while(sgn(a) < 0) a += 2 * pi;
    while(sgn(a - 2 * pi) >= 0) a -= 2 * pi;
    a = min(a, 2 * pi - a);
    return a;
}
double cal(Vector v1, Vector v2){
    if(sgn(v1 % v2) == 0)
    {
        if(sgn(v1 * v2) > 0) return 0;
        else return -pi;
    }
    else{
        double a = angle(v1, v2);
        if(sgn(v1 % v2) > 0) a = - a;
        return a;
    }
}
int findone(int w, int v){
    double maxi = -100;
    Vector v1 = pv[v] - pv[w];
    int ans = 0;
    for(int i = head[v]; i != -1; i = e[i].next){
        int to = e[i].to;
        Vector v2 = pv[to] - pv[v];
        double a = cal(v1, v2);
        if(sgn(a - maxi ) > 0){
            maxi = a;
            ans = to;
        }
    }
    return ans;
}

vector<Point>route;
void solve(){
    int w = 1;
    Point minp = Point(1e9, 1e9);
    for(int i = 1; i <= nv; i++){
        if(pv[i] < minp){
            w = i;
            minp = pv[i];
        }
    }
    int v = 1;
    double mini = 1e9;
    for(int i = head[w]; i != -1; i = e[i].next){
        int to = e[i].to;
        Vector v1 = pv[to] - pv[w];
        double a = atan2(v1.y, v1.x);
        if(sgn(a - mini) < 0){
            mini = a;
            v = to;
        }
    }
    int w1 = w;
    //just go
    while(true){
        route.push_back(pv[w]);
        int newv = findone(w, v);
        w = v;
        v = newv;
        if(w == w1) break;
    }
}

int main(){
    scanf("%d",&n);
    for(int i = 0; i < n; i++){
        int x, y;
        scanf("%d%d",&x,&y);
        p[i] = Point(x, y);
    }
    build_edge();
    
    solve();
    
    //cal ans
    double ans = 0.0;
    for(int i = 0; i < route.size(); i++){
        int j = i + 1 == route.size() ? 0 : i + 1;
        ans += route[i] % route[j];
    }
    ans = abs(ans);
    ans = ans * 0.5;
    
    printf("%.10f\n",ans);
    
    return 0;
}
### Prompt

Your task is to create 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<cmath>
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
using namespace std;

const double eps = 1e-6, pi = acos(-1.0);
int sgn(double x){
    if(abs(x) < eps) return 0;
    else return x > 0 ? 1 : -1;
}

struct Point{
    double x, y;
    Point(){};
    Point(double x1, double y1){
        x = x1, y = y1;
    }
};
typedef Point Vector;
Vector operator + (Vector a, Vector b){
    return Vector(a.x + b.x, a.y + b.y);
}
Vector operator - (Vector a, Vector b){
    return Vector(a.x - b.x, a.y - b.y);
}
Vector operator * (Vector a, double b){
    return Vector(a.x * b, a.y * b);
}
double operator * (Vector a, Vector b){
    return a.x * b.x + a.y * b.y;
}
double operator % (Vector a, Vector b){
    return a.x * b.y - a.y * b.x;
}
bool operator == (Point a, Point b){
    return sgn(a.x - b.x) == 0 && sgn(a.y - b.y) == 0;
}

#define MAXN 100010
#define N 200
int n;
Point p[200], pv[MAXN];

struct Edge{
    int next, to;
}e[MAXN << 1];
int head[MAXN], ne, nv;
void add(int a, int b){
    int t = ++ne;
    e[t].to = b, e[t].next = head[a];
    head[a] = t;
}

bool inter(Point p1, Point p2, Point q1, Point q2){
    if(sgn((p1 - p2) % (q1 - q2)) == 0 ) return false;
    int t1 = sgn((p2 - p1) % (q1 - p1)) * sgn((p2 - p1) % (q2 - p1));
    int t2 = sgn((q2 - q1) % (p1 - q1)) * sgn((q2 - q1) % (p2 - q1));
    return t1 <= 0 && t2 <= 0;
}
Point getp(Point p1, Vector v1, Point p2, Vector v2){
    double t = ((p2 - p1) % v2) / (v1 % v2);
    return p1 + v1 * t;
}

vector<Point>seg[N], vp;

bool operator < (const Point a, const Point b){
    if(sgn(a.x - b.x) != 0) return sgn(a.x - b.x) < 0;
    else return sgn(a.y - b.y) < 0;
}
map<Point, int>mto;
set<pair<int,int> >se;
void build_edge(){
    for(int i = 0; i < n - 1; i++){
        seg[i].push_back(p[i]);
        seg[i].push_back(p[i + 1]);
        vp.push_back(p[i]);
        vp.push_back(p[i + 1]);
        for(int j = 0; j < n - 1; j++){
            if(inter(p[i], p[i+1], p[j], p[j+1]) == 0) continue;
            Point x = getp(p[i], p[i+1] - p[i], p[j], p[j+1] - p[j]);
            seg[i].push_back(x);
            vp.push_back(x);
        }
    }
    sort(vp.begin(), vp.end());
    nv = 0;
    for(int i = 0; i < vp.size(); i++){
        if(i > 0 && vp[i] == vp[i-1]) continue;
        mto[vp[i]] = ++nv;
        pv[nv] = vp[i];
    }
    
    for(int i = 1; i <= nv; i++) head[i] = -1;
    ne = 0;
    
    for(int i = 0; i < n - 1; i++){
        sort(seg[i].begin(), seg[i].end());
        for(int j = 1; j < seg[i].size(); j++){
            if(j > 0 && seg[i][j] == seg[i][j-1]) continue;
            int a = mto[seg[i][j]];
            int b = mto[seg[i][j-1]];
            if(a > b) swap(a, b);
            pair<int,int>pa = make_pair(a, b);
            if(se.find(pa) != se.end()) continue;
            se.insert(pa);
            add(a, b);
            add(b, a);
        }
    }
}

double angle(Vector v1, Vector v2){
    double a = atan2(v1.y, v1.x) - atan2(v2.y, v2.x);
    while(sgn(a) < 0) a += 2 * pi;
    while(sgn(a - 2 * pi) >= 0) a -= 2 * pi;
    a = min(a, 2 * pi - a);
    return a;
}
double cal(Vector v1, Vector v2){
    if(sgn(v1 % v2) == 0)
    {
        if(sgn(v1 * v2) > 0) return 0;
        else return -pi;
    }
    else{
        double a = angle(v1, v2);
        if(sgn(v1 % v2) > 0) a = - a;
        return a;
    }
}
int findone(int w, int v){
    double maxi = -100;
    Vector v1 = pv[v] - pv[w];
    int ans = 0;
    for(int i = head[v]; i != -1; i = e[i].next){
        int to = e[i].to;
        Vector v2 = pv[to] - pv[v];
        double a = cal(v1, v2);
        if(sgn(a - maxi ) > 0){
            maxi = a;
            ans = to;
        }
    }
    return ans;
}

vector<Point>route;
void solve(){
    int w = 1;
    Point minp = Point(1e9, 1e9);
    for(int i = 1; i <= nv; i++){
        if(pv[i] < minp){
            w = i;
            minp = pv[i];
        }
    }
    int v = 1;
    double mini = 1e9;
    for(int i = head[w]; i != -1; i = e[i].next){
        int to = e[i].to;
        Vector v1 = pv[to] - pv[w];
        double a = atan2(v1.y, v1.x);
        if(sgn(a - mini) < 0){
            mini = a;
            v = to;
        }
    }
    int w1 = w;
    //just go
    while(true){
        route.push_back(pv[w]);
        int newv = findone(w, v);
        w = v;
        v = newv;
        if(w == w1) break;
    }
}

int main(){
    scanf("%d",&n);
    for(int i = 0; i < n; i++){
        int x, y;
        scanf("%d%d",&x,&y);
        p[i] = Point(x, y);
    }
    build_edge();
    
    solve();
    
    //cal ans
    double ans = 0.0;
    for(int i = 0; i < route.size(); i++){
        int j = i + 1 == route.size() ? 0 : i + 1;
        ans += route[i] % route[j];
    }
    ans = abs(ans);
    ans = ans * 0.5;
    
    printf("%.10f\n",ans);
    
    return 0;
}
```