Problem: Imagine a board with n pins put into it, the i-th pin is located at (x_i, y_i). For simplicity, we will restrict the problem to the case where the pins are placed in vertices of a convex polygon.

Then, take a non-stretchable string of length l, and put it around all the pins. Place a pencil inside the string and draw a curve around the pins, trying to pull the string in every possible direction. The picture below shows an example of a string tied around the pins and pulled by a pencil (a point P).

<image>

Your task is to find an area inside this curve. Formally, for a given convex polygon S and a length l let's define a fiber shape F(S, l) as a set of points t such that the perimeter of the convex hull of S ∪ \\{t\} does not exceed l. Find an area of F(S, l).

Input

The first line contains two integers n and l (3 ≤ n ≤ 10^4; 1 ≤ l ≤ 8 ⋅ 10^5) — the number of vertices of the polygon S and the length of the string. Next n lines contain integers x_i and y_i (-10^5 ≤ x_i, y_i ≤ 10^5) — coordinates of polygon's vertices in counterclockwise order. All internal angles of the polygon are strictly less than π. The length l exceeds the perimeter of the polygon by at least 10^{-3}.

Output

Output a single floating-point number — the area of the fiber shape F(S, l). Your answer will be considered correct if its absolute or relative error doesn't exceed 10^{-6}. 

Examples

Input


3 4
0 0
1 0
0 1


Output


3.012712585980357


Input


4 5
0 0
1 0
1 1
0 1


Output


5.682061989789656


Input


5 17
0 0
2 -1
3 0
4 3
-1 4


Output


37.719371276930820

Note

The following pictures illustrate the example tests.

<image> <image>

<image>

Solution (in CPP):

Solution:
#include <iostream>
#include <vector>
#include <cmath>
#include <iomanip>
using namespace std;
const double pi12 = 1.57079632679489661923;
struct point {
    double x, y;
    point operator-(const point & p) const{
        return {x - p.x, y - p.y};}
    double crossP(const point &p) const{
        return x * p.y - y * p.x;}
    double crossP(const point &p1, const point &p2) const{
        return (p1.x - x) * (p2.y - y) - (p1.y - y) * (p2.x - x);}
    double dotP(const point &p) const{
        return x * p.x + y * p.y;}
    double dist(const point &p) const{ point t = p - *this;
        return sqrt(t.x * t.x + t.y * t.y);}
    double dist2(const point &p) const{ point t = p - *this;
        return t.x * t.x + t.y * t.y;} 
    bool crossLines(const point &p1,const point &p2,const point &p3,const point &p4){
        point d12 = p1 - p2, d34 = p3 - p4;
        double den = d12.crossP(d34);
        if (abs(den) < 1.e-7) return false;
        x = (p1.crossP(p2) * d34.x - d12.x * p3.crossP(p4)) / den;
        y = (p1.crossP(p2) * d34.y - d12.y * p3.crossP(p4)) / den;
        return true;}
    int quadrant() const {
        return signbit(x) ^ signbit(y) * 3;}
    int quaT(const point &p, const double t) const{
        int k = p.quadrant() - quadrant();
        if(k < 0) k += 4;
        k -= (k & 1) ^ signbit(t);
        return (k < 0) ? k = 3 : k;}
};
struct polygonS {
    int size;
    vector<point> v;
    polygonS(int size) : size(size) { v.reserve(size);}
    point &operator[](int i){return (i < size) ? (i >= 0) ? v[i] : v[size - 1] : v[0];}
};
double sectE(const point &v0, const point &v1, double ab){
    double ta = v0.crossP(v1) / v0.dotP(v1) * ab;
    int k = v0.quaT(v1, ta);
    if (ta < 0) ta = - 1. / ta;
    return atan(ta) + k * pi12;
}
double segArea(const point &f1, const point &f2, const point &v1, const point &v2, double r){
    point v0{(f1.x + f2.x) / 2., (f1.y + f2.y) /2.};
    double dx = f1.x - v0.x, dy = f1.y - v0.y,
    a = r / 2., b = sqrt(a * a - dx * dx - dy * dy); dx = a / b;
    return a * b * (sectE(f1 - v0, v2 - v0, dx) - sectE(f1 - v0, v1 - v0, dx)) - v0.crossP(v1, v2);
}
double root2(double x3, double y3, double dx, double k, double r){
    double r2 = r * r, cdk = x3 + y3 * k, k21 = k * k + 1,  d = r * sqrt(k21),
    m = (x3 * x3 + y3 * y3 - r2) / (2. * (cdk * cdk - r2 * k21)),
    x = m * (cdk + d);
    if (signbit(x) != signbit(dx))
        x = m * (cdk - d);
    return x;
}
point archPoint2(const point &p1, const point &p2, const point &p3, double r){
    double x, y;
    point d32 = p3 - p2; point d21 = p2 - p1;
    if (abs(d21.x) > abs(d21.y)){
        double k = d21.y / d21.x;
        x = root2(d32.x, d32.y, d21.x, k , r );
        y = p2.y + k * x;
        x += p2.x;}
    else{
        double k = d21.x / d21.y;
        y = root2(d32.y, d32.x, d21.y, k , r );
        x = p2.x + k * y;
        y += p2.y;}    
    return {x, y};
}
int main()
{   
    int numVerS, pf1{}, pf2{};
    point v0, pv; 
    double remStr, pr{}, areaFS{};
    ios_base::sync_with_stdio(false), cin.tie(nullptr);
    cin >> numVerS >> remStr;
    polygonS s(numVerS);
    for (int i = 0; i < numVerS; ++i){
        cin >> s[i].x >> s[i].y;
        if (i > 1) remStr -= s[i - 1].dist(s[i]);
    }
    remStr -= s[numVerS - 1].dist(s[0]);
    bool pull = true;
    for (int i = 0, j = 1, k = 0;  i < numVerS ; )
    {
        if (j == numVerS) j = 0;
        if (pull){
            pull = false;
            point p;
            if (p.crossLines(s[i - 1], s[i], s[j], s[j + 1])){
                if (s[i].crossP(p, s[i + 1]) > 0) { 
                    double d1 = p.dist2(s[i]), d2 = p.dist2(s[j]),
                    rem = remStr * remStr - d1 - d2;
                    if (rem > 0) 
                        if (rem * rem - 4 * d1 * d2 > 0 ){
                        remStr += s[j].dist(s[j + 1]); j++; 
                        pull = true;
                        continue;
                    }
                }
            }
            p = archPoint2(s[i - 1], s[i], s[j], remStr);
            if (k == 0)
                v0 = p;
            if (k > 0)
                areaFS += segArea(s[pf1], s[pf2], pv, p, pr);
            if (k > 1) 
                areaFS += v0.crossP(pv, p) ;
            pv = p;
            pf1 = i;
            pf2 = j;
            pr = remStr;
            k++;
        }
        point p = archPoint2(s[j + 1], s[j], s[i], remStr);
        if (s[i].crossP(p, s[i + 1]) < 0) {
            remStr -= s[i].dist(s[i + 1]); i++;
            pull = true;
            continue;
        }
        areaFS += segArea(s[pf1], s[pf2], pv, p, pr);
        if (k > 1) areaFS += v0.crossP(pv, p) ;
        pv = p;
        pf1 = i;
        pf2 = (j + 1 < numVerS) ? (j + 1) : 0;
        remStr += s[j].dist(s[j + 1]); j++;
        pr = remStr;
        k++; 
    }
    areaFS += segArea(s[pf1], s[pf2], pv, v0, pr);
    cout << setprecision(16) << areaFS / 2 << endl;
}