Problem: You are given an strictly convex polygon with n vertices. It is guaranteed that no three points are collinear. You would like to take a maximum non intersecting path on the polygon vertices that visits each point at most once.

More specifically your path can be represented as some sequence of distinct polygon vertices. Your path is the straight line segments between adjacent vertices in order. These segments are not allowed to touch or intersect each other except at the vertices in your sequence.

Given the polygon, print the maximum length non-intersecting path that visits each point at most once.

Input

The first line of input will contain a single integer n (2 ≤ n ≤ 2 500), the number of points.

The next n lines will contain two integers xi, yi (|xi|, |yi| ≤ 109), denoting the coordinates of the i-th vertex.

It is guaranteed that these points are listed in clockwise order.

Output

Print a single floating point number, representing the longest non-intersecting path that visits the vertices at most once.

Your answer will be accepted if it has absolute or relative error at most 10 - 9. More specifically, if your answer is a and the jury answer is b, your answer will be accepted if <image>.

Example

Input

4
0 0
0 1
1 1
1 0


Output

3.4142135624

Note

One optimal path is to visit points 0,1,3,2 in order.

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
#pragma GCC optimize("O3")
#pragma GCC target("sse4")
using namespace std;
const double PI = acos(-1.0);
const long double eps = 1e-12;
const long double infl = 1e20;
template <class T>
inline int sgn(const T &x) {
  return (x > eps) - (x < -eps);
}
template <class T>
struct Point {
  T x, y;
  Point() : x(0), y(0) {}
  Point(const T &x, const T &y) : x(x), y(y) {}
  long double length() const { return sqrtl(x * x + y * y); }
  T length2() const { return x * x + y * y; }
  long double distance(const Point &rhs) const {
    return (rhs - *this).length();
  }
  T cross(const Point &lhs, const Point &rhs) const {
    return (lhs - *this) * (rhs - *this);
  }
  T dot(const Point &lhs, const Point &rhs) const {
    return (lhs - *this) & (rhs - *this);
  }
  long double distance_to_line(const Point &p, const Point &q) const {
    if (p == q)
      return distance(p);
    else
      return fabsl(cross(p, q) / p.distance(q));
  }
  long double distance_to_segment(const Point &p, const Point &q) const {
    if (p == q)
      return distance(p);
    else if (p.dot(q, *this) < 0)
      return distance(p);
    else if (q.dot(p, *this) < 0)
      return distance(q);
    else
      return distance_to_line(p, q);
  }
  bool on_line(const Point &p, const Point &q) const {
    return sgn(cross(p, q)) == 0;
  }
  bool on_halfline(const Point &p, const Point &q,
                   const bool &inclusive = true) const {
    if (*this == p)
      return inclusive;
    else
      return on_line(p, q) && sgn(p.dot(q, *this)) >= 0;
  }
  bool on_segment(const Point &p, const Point &q,
                  const bool &inclusive = true) const {
    if (*this == p || *this == q)
      return inclusive;
    else
      return on_line(p, q) && sgn(dot(p, q)) <= 0;
  }
  bool in_triangle(const Point &u, const Point &v, const Point &w,
                   const bool &inclusive = true) const {
    Point p[3] = {u, v, w};
    if (sgn(u.cross(v, w)) < 0) reverse(p, p + 3);
    for (int i = 0; i < 3; i++) {
      if (on_segment(p[i], p[(i + 1) % 3]))
        return inclusive;
      else if (sgn(cross(p[i], p[(i + 1) % 3])) < 0)
        return false;
    }
    return true;
  }
  bool in_angle(const Point &o, const Point &p, const Point &q,
                const bool &inclusive = true) const {
    if (on_halfline(o, p) || on_halfline(o, q)) return inclusive;
    int vs = sgn(o.cross(p, q)), ss = sgn(o.dot(p, q));
    if (vs == 0 && ss > 0) return false;
    int vp = sgn(o.cross(p, *this)), vq = sgn(o.cross(*this, q));
    if (sgn(o.cross(p, q)) >= 0)
      return vp > 0 && vq > 0;
    else
      return vp > 0 || vq > 0;
  }
  Point operator+(const Point &rhs) const {
    return Point(x + rhs.x, y + rhs.y);
  }
  Point operator-(const Point &rhs) const {
    return Point(x - rhs.x, y - rhs.y);
  }
  T operator*(const Point &rhs) const { return x * rhs.y - y * rhs.x; }
  T operator&(const Point &rhs) const { return x * rhs.x + y * rhs.y; }
  Point operator*(const T &rhs) const { return Point(x * rhs, y * rhs); }
  Point operator/(const T &rhs) const { return Point(x / rhs, y / rhs); }
  bool operator==(const Point &rhs) const { return x == rhs.x && y == rhs.y; }
  bool operator!=(const Point &rhs) const { return x != rhs.x || y != rhs.y; }
  inline int quadrant() const {
    if (x == 0 && y == 0)
      return -1;
    else if (x < 0 && y < 0)
      return 0;
    else if (x == 0 && y < 0)
      return 1;
    else if (x > 0 && y < 0)
      return 2;
    else if (x > 0 && y == 0)
      return 3;
    else if (x > 0 && y > 0)
      return 4;
    else if (x == 0 && y > 0)
      return 5;
    else if (x < 0 && y > 0)
      return 6;
    else
      return 7;
  }
  bool operator<(const Point &rhs) const {
    int lq = quadrant(), rq = rhs.quadrant();
    if (lq != rq) {
      return lq < rq;
    } else {
      int s = sgn(*this * rhs);
      return s != 0 ? s > 0 : sgn(length2() - rhs.length2()) < 0;
    }
  }
};
int n;
const int N = 2505;
Point<long double> p[N];
long double dp[N][N][2];
long double rec(int ind, int len, bool f) {
  if (len == 0) {
    return 0;
  }
  long double &ans = dp[ind][len][f];
  if (ans >= 0) {
    return ans;
  }
  int l, r;
  if (f) {
    r = ind;
    l = (ind + n - len) % n;
    int l2 = (l + 1) % n;
    int r2 = (r + n - 1) % n;
    ans = max(p[ind].distance(p[l]) + rec(l, len - 1, 0),
              p[ind].distance(p[r2]) + rec(r2, len - 1, 1));
  } else {
    l = ind;
    r = (ind + len) % n;
    int l2 = (l + 1) % n;
    int r2 = (r + n - 1) % n;
    ans = max(p[ind].distance(p[r]) + rec(r, len - 1, 1),
              p[ind].distance(p[l2]) + rec(l2, len - 1, 0));
  }
  return ans;
}
int32_t main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
      dp[i][j][0] = -1;
      dp[i][j][1] = -1;
    }
  }
  cin >> n;
  for (int i = 0; i < n; i++) {
    cin >> p[i].x >> p[i].y;
  }
  long double ans = 0;
  for (int i = 0; i < n; i++) {
    ans = max(ans, rec(i, n - 1, 0));
  }
  cout << fixed << setprecision(12);
  cout << ans << "\n";
}