#include <bits/stdc++.h>

using namespace std;

#define MP make_pair
#define PB push_back
#define LL long long
#define int LL
#define VI vector<int>
#define LD long double
#define PII pair<int,int>
#define ALL(x) (x).begin(), (x).end()
#define SZ(x) ((int)(x).size())
#define FOR(i,a,b) for (int i = (a); i <= (b); i++)
#define REP(i,n) FOR(i,0,(int)(n)-1)
#define RE(i,n) FOR(i,1,n)
#define R(i,n) REP(i,n)
#define FI first
#define SE second
#define st FI
#define nd SE

template<class C> void mini(C&a4, C b4) { a4 = min(a4, b4); }
template<class C> void maxi(C&a4, C b4) { a4 = max(a4, b4); }

template<class TH> void _dbg(const char *sdbg, TH h){cerr<<sdbg<<"="<<h<<"\n";}
template<class TH, class... TA> void _dbg(const char *sdbg, TH h, TA... a) {
  while(*sdbg!=',')cerr<<*sdbg++;cerr<<"="<<h<<","; _dbg(sdbg+1, a...);
}

template<class T> ostream &operator<<(ostream &os, vector<T> V) {
  os << "["; for (auto vv : V) os << vv << ","; return os << "]";
}

#ifdef LOCAL
#define debug(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#else
#define debug(...) (__VA_ARGS__)
#define cerr if(0)cout
#endif

LD Sq(LD x) {
  return x * x;
}

const LD kEps = 1e-9;
struct Point {
  LD x, y;
  Point operator-(Point p) { return {x - p.x, y - p.y}; }
  Point operator+(Point p) { return {x + p.x, y + p.y}; }
  Point operator*(LD f) { return {x * f, y * f}; }
  bool operator<(const Point& A) const {
    if (abs(A.x - x) > kEps) { return x < A.x; }
    return y < A.y;
  }
  friend ostream& operator<<(ostream& out, Point p) {
    return out<<"("<<p.x<<", "<<p.y<<")";
  }
};

LD Dist(Point A, Point B) {
  return sqrt(Sq(A.x - B.x) + Sq(A.y - B.y));
}

LD CrossProd(Point A, Point B) {
  return A.x * B.y - A.y * B.x;
}

LD CrossProd(Point A, Point B, Point C) {
  B = B - A;
  C = C - A;
  return CrossProd(B, C);
}

struct Line {
  Point p[2];
  Point& operator[](int a) {
    return p[a];
  }
};
    


vector<Point> InterLineLine(Point A, Point B, Point P, Point Q) {
  LD tr_area = CrossProd(A, P, Q);
  LD quad_area = CrossProd(A, P, B) + CrossProd(A, B, Q);
  if (abs(quad_area) < kEps) {
    return {};
  }
  return {A + (B - A) * (tr_area / quad_area)};
} 

const int N = 222;
Point pts[N];

bool PtOnLine(Point A, Line l) {
  return abs(CrossProd(l[0], A, l[1])) < kEps;
}

bool PtOnSeg(Point A, Point P, Point Q) {
  return abs(Dist(P, Q) - Dist(A, P) - Dist(A, Q)) < kEps;
}

int32_t main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout << fixed << setprecision(11);
  cerr << fixed << setprecision(6);
  
  
  int n;
  cin>>n;
  RE (i, n) {
    int x, y;
    cin>>x>>y;
    pts[i] = {(LD)x, (LD)y};
  }
  pts[n + 1] = pts[1];
  pts[n + 2] = pts[2];
  LD area = 0;
  RE (ii, n) {
    area += CrossProd(pts[ii], pts[ii + 1]);
  }
  if (area < 0) {
    reverse(pts + 1, pts + n + 3);
  }
  debug(pts[1], pts[2]);
  LD res = 0;
  RE (ii, n) {
    RE (jj, ii - 1) {
      Line l = {pts[ii], pts[jj]};
      vector<Point> inters;
      RE (k, n) {
        bool b1 = PtOnLine(pts[k], l),
             b2 = PtOnLine(pts[k + 1], l),
             b3 = PtOnLine(pts[k + 2], l);
        if (!b2 && !b1) {
          vector<Point> hehs = InterLineLine(pts[ii], pts[jj], pts[k], pts[k + 1]);
          if (hehs.empty()) { continue; }
          if (PtOnSeg(hehs[0], pts[k], pts[k + 1])) {
            inters.PB(hehs[0]);
          }
        } else if (b1 && !b2) {
        } else if (b1 || b3) {
          if (CrossProd(pts[k], pts[k + 1], pts[k + 2]) > 0) {
            inters.PB(pts[k + 1]);
          }
        } else {
          if ((CrossProd(l[1] - l[0], pts[k + 1] - pts[k]) > 0) == (CrossProd(l[1] - l[0], pts[k + 2] - pts[k + 1]) > 0)) {
            inters.PB(pts[k + 1]);
          }
        }
      }
      sort(ALL(inters));
      debug(inters);
      if (SZ(inters) % 2) {
        debug(pts[ii], pts[jj]);
      }
      assert(SZ(inters) % 2 == 0);
      for (int i = 0; i < SZ(inters); i += 2) {
        maxi(res, Dist(inters[i], inters[i + 1]));
      }
    }
  }
  
  cout<<res<<endl;
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
}
