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 dist2(const point &p) const{ point t = p - *this;
        return t.x * t.x + t.y * t.y;}    
    double dist(const point &p) const{
        return sqrt(dist2(p));}
    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;
    vector<double> d;
    polygonS(int size) : size(size) { v.reserve(size); d.reserve(size);}
    point &operator[](int i){return (i < size) ? (i >= 0) ? v[i] : v[i + size] : v[i - size];}
    double & distN(int i){return (i < size) ? (i >= 0) ? d[i] : d[i + size] : d[i - size];}
};
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){
    r = r * r;
    double cdk = x3 + y3 * k, k21 = k * k + 1,  d = sqrt(r * k21),
    m = (x3 * x3 + y3 * y3 - r) / (2 * (cdk * cdk - r * 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};
}
bool remS(polygonS &s, int i , int j, double rem){
    point p;
    if (!p.crossLines(s[i - 1], s[i], s[j], s[j + 1])) return false;
    if (s[i].crossP(p, s[i + 1]) < 0) return false; 
    double d1 = p.dist2(s[i]), d2 = p.dist2(s[j]);
    rem = rem * rem - d1 - d2;
    if (rem <= 0) return false;
    return (rem * rem - 4 * d1 * d2 > 0 );
}
int main()
{   
    int numVerS, pf1{}, pf2{};
    point v0, pv; 
    double remStr, dsum{}, pr{}, areaS{}, areaF{};
    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 > 0) { 
            double d = s[i - 1].dist(s[i]);
            s.distN(i - 1) = dsum += d;
            if (i > 1) remStr -= d;
        }
    }
    {double d = s[numVerS - 1].dist(s[0]);
    s.distN(numVerS - 1) = dsum += d; remStr -= d;}
    bool bs{}, pull = true;
    for (int i = 0, j = 1, k = 0; i < numVerS ; )
    {
        if (j == numVerS) j = 0;
        if (pull){
            pull = false;
            if (remS(s, i, j, remStr)) {
                if (bs) {
                    double rem; bs = false;
                    int l = j , h = i + numVerS , m;
                    while(l < h){
                        m = (l + h) / 2;
                        rem = remStr + s.distN(m) - s.distN(j - 1);
                        if (remS(s, i, m + 1 , rem))
                            l = m + 1;
                        else 
                            h = m;
                    }    
                    remStr +=s.distN(h) - s.distN(j - 1); j = h + 1  ;
                }else
                {
                    remStr += s.distN(j) - s.distN(j - 1); j++; 
                    pull = true; bs =true;
                    continue;}
            }
            point p = archPoint2(s[i - 1], s[i], s[j], remStr);
            if (k == 0)
                v0 = p;
            if (k > 0)
                areaS += segArea(s[pf1], s[pf2], pv, p, pr);
            if (k > 1) 
                areaF += 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) {
            s.distN(i) +=dsum;
            remStr -= s.distN(i) - s.distN(i - 1); i++;
            pull = true;
            continue;
        }
        areaS += segArea(s[pf1], s[pf2], pv, p, pr);
        if (k > 1) areaF += v0.crossP(pv, p) ;
        pv = p;
        pf1 = i;
        pf2 = j+1;
        remStr += s.distN(j) - s.distN(j - 1); j++;
        pr = remStr;
        k++; 
    }
    cout << setprecision(16) << (areaF + areaS + segArea(s[pf1], s[pf2], pv, v0, pr)) / 2 << endl;
}