#include <bits/stdc++.h>

using namespace std;
using uint = unsigned int;
using ll = long long;
using ull = unsigned long long;
constexpr ll TEN(int n) { return (n==0) ? 1 : 10*TEN(n-1); }
template<class T> using V = vector<T>;
template<class T> using VV = V<V<T>>;

using D = double;
const D PI = acos(D(-1)), EPS = 1e-10;

struct Pt2 {
    D x, y;
    Pt2() {}
    Pt2(D _x, D _y) : x(_x), y(_y) {}
    Pt2 operator+(const Pt2 &r) const { return Pt2(x+r.x, y+r.y); }
    Pt2 operator-(const Pt2 &r) const { return Pt2(x-r.x, y-r.y); }
    Pt2 operator*(const Pt2 &r) const { return Pt2(x*r.x-y*r.y, x*r.y+y*r.x); }
    Pt2& operator+=(const Pt2 &r) { return *this=*this+r; }
    Pt2& operator-=(const Pt2 &r) { return *this=*this-r; }
    Pt2& operator*=(const Pt2 &r) { return *this=*this*r; }
    
    Pt2 operator-() const { return Pt2(-x, -y); }

    D abs() const { return sqrt(x*x + y*y); }
    D rabs() const { return max(x, y); } // robust abs
    D arg() const { return atan2(y, x); }

    pair<D, D> to_pair() const { return make_pair(x, y); }
    static Pt2 polar(D le, D th) { return Pt2(le*cos(th), le*sin(th)); }
};
template<class T> ostream& operator<<(ostream& os, const Pt2 &p) {
    os << "(" << p.x << ", " << p.y << ")";
    return os;
}
using P = Pt2;


int sgn(D a) {
    if (abs(a) <= EPS) return 0;
    return (a < 0) ? -1 : 1;
}
//relative sign
int rsgn(D a, D f) {
    if (abs(a) <= f*EPS) return 0;
    return (a < 0) ? -1 : 1;
}
bool near(P a, P b) { return !sgn((a-b).abs()); }

bool lessP(P l, P r) {
    if (sgn(r.x-l.x)) return l.x < r.x;
    if (sgn(r.y-l.y)) return l.y < r.y;
    return false;
}

D cross(P a, P b) { return a.x*b.y - a.y*b.x; }
D dot(P a, P b) { return a.x*b.x + a.y*b.y; }

// -2, -1, 0, 1, 2 : front, clock, on, cclock, back
int ccw(P b, P c) {
    int s = rsgn(cross(b, c), b.rabs());
    if (s) return s;
    if (!sgn(c.rabs()) || !sgn((c-b).rabs())) return 0;
    if (dot(b, c) < 0) return 2;
    if (dot(-b, c-b) < 0) return -2;
    return 0;
}
int ccw(P a, P b, P c) { return ccw(b-a, c-a); }


using Pol = V<P>;

Pol convex_up(const Pol &p, int l, int r, int e1 = -1, int e2 = -1) {
    Pol up;
    for (int i = l; i <= r; i++) {
        if (i == e1 || i == e2) continue;
        P d = p[i];
        while (up.size() > 1 && ccw(up[up.size()-2], up[up.size()-1], d) == 1) up.pop_back();
        up.push_back(d);
    }
    return up;
}

Pol convex_down(const Pol &p, int l, int r, int e1 = -1, int e2 = -1) {
    Pol down;
    for (int i = l; i <= r; i++) {
        if (i == e1 || i == e2) continue;
        P d = p[i];
        while (down.size() > 1 && ccw(down[down.size()-2], down[down.size()-1], d) == -1) down.pop_back();
        down.push_back(d);
    }
    return down;
}

D line_len(const Pol &p) {
    int n = int(p.size());
    D sm = 0;
    for (int i = 0; i < n-1; i++) {
        sm += (p[i+1]-p[i]).abs();
    }
    return sm;
}

bool operator<(const P &x, const P &y) { return lessP(x, y); }


D solve(V<P> v, bool one = false) {
    int n = int(v.size());
    map<P, int> mp;
    for (int i = 0; i < n; i++) mp[v[i]] = i;
    
    auto up = convex_up(v, 0, n-1);
    auto down = convex_down(v, 0, n-1);

    int un = int(up.size()), dn = int(down.size());
    V<D> bufu, bufd;
    for (int i = 1; i < un-1; i++) {
        D base = (up[i-1]-up[i]).abs() + (up[i]-up[i+1]).abs();
        bufu.push_back(base - line_len(convex_up(v, mp[up[i-1]], mp[up[i+1]], mp[up[i]])));
    }

    for (int i = 1; i < dn-1; i++) {
        D base = (down[i-1]-down[i]).abs() + (down[i]-down[i+1]).abs();
        bufd.push_back(base - line_len(convex_down(v, mp[down[i-1]], mp[down[i+1]], mp[down[i]])));
    }

    D ans = -1e100;
    D uma = -1e100, dma = -1e100;
    for (int i = 1; i < un-2; i++) {
        ans = max(ans, uma + bufu[i]);
        uma = max(uma, bufu[i-1]);
    }
    for (int i = 1; i < dn-2; i++) {
        ans = max(ans, dma + bufd[i]);
        dma = max(dma, bufd[i-1]);
    }
    for (auto d: bufu) uma = max(uma, d);
    for (auto d: bufd) dma = max(dma, d);

    if (one) return max(uma, dma);

    ans = max(ans, uma + dma);

    for (int i = 1; i < un-1; i++) {
        D base = (up[i-1]-up[i]).abs() + (up[i]-up[i+1]).abs();
        auto npo = convex_up(v, mp[up[i-1]], mp[up[i+1]], mp[up[i]]);
        base -= line_len(npo);
        int m = int(npo.size());
        for (int j = 1; j < m-1; j++) {
            D base2 = (npo[j-1]-npo[j]).abs() + (npo[j]-npo[j+1]).abs();
            ans = max(ans, base + base2 - line_len(convex_up(v, mp[npo[j-1]], mp[npo[j+1]], mp[npo[j]], mp[up[i]])));
        }
    }

    for (int i = 1; i < dn-1; i++) {
        D base = (down[i-1]-down[i]).abs() + (down[i]-down[i+1]).abs();
        auto npo = convex_down(v, mp[down[i-1]], mp[down[i+1]], mp[down[i]]);
        base -= line_len(npo);
        int m = int(npo.size());
        for (int j = 1; j < m-1; j++) {
            D base2 = (npo[j-1]-npo[j]).abs() + (npo[j]-npo[j+1]).abs();
            ans = max(ans, base + base2 - line_len(convex_down(v, mp[npo[j-1]], mp[npo[j+1]], mp[npo[j]], mp[down[i]])));
        }
    }

    for (int i = 1; i < un-2; i++) {
        D base = (up[i-1]-up[i]).abs() + (up[i]-up[i+1]).abs() + (up[i+1]-up[i+2]).abs();
        ans = max(ans, base - line_len(convex_up(v, mp[up[i-1]], mp[up[i+2]], mp[up[i]], mp[up[i+1]])));
    }
    for (int i = 1; i < dn-2; i++) {
        D base = (down[i-1]-down[i]).abs() + (down[i]-down[i+1]).abs() + (down[i+1]-down[i+2]).abs();
        ans = max(ans, base - line_len(convex_down(v, mp[down[i-1]], mp[down[i+2]], mp[down[i]], mp[down[i+1]])));
    }

    return ans;
}


D naive(V<P> v) {
    int n = int(v.size());
    auto up = convex_up(v, 0, n-1);
    auto down = convex_down(v, 0, n-1);

    return line_len(up) + line_len(down);
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << setprecision(20);

    int n;
    cin >> n;
    V<P> v(n);
    for (int i = 0; i < n; i++) {
        D x, y;
        cin >> x >> y;
        v[i] = P(x, y);
        v[i] *= P::polar(1, 13.4514);
    }
    sort(begin(v), end(v));
    
    D ma = -1;
    D base = naive(v);
    ma = max(ma, base-naive(V<P>(begin(v), end(v)-2)));
    ma = max(ma, base-naive(V<P>(begin(v)+1, end(v)-1)));
    ma = max(ma, base-naive(V<P>(begin(v)+2, end(v))));

    ma = max(ma, base-naive(V<P>(begin(v), end(v)-1))+solve(V<P>(begin(v), end(v)-1), true));
    ma = max(ma, base-naive(V<P>(begin(v)+1, end(v)))+solve(V<P>(begin(v)+1, end(v)), true));

    ma = max(ma, solve(v));
    cout << ma << endl;

    return 0;
}



Measured memory_bytes: 14344