Problem: Find the diameter of a convex polygon g. In other words, find a pair of points that have maximum distance between them.

Constraints

* 3 ≤ n ≤ 80000
* -100 ≤ xi, yi ≤ 100
* No point in the g will occur more than once.

Input


n
x1 y1
x2 y2
:
xn yn


The first integer n is the number of points in g.

In the following lines, the coordinate of the i-th point pi is given by two real numbers xi and yi. The coordinates of points are given in the order of counter-clockwise visit of them. Each value is a real number with at most 6 digits after the decimal point.

Output

Print the diameter of g in a line. The output values should be in a decimal fraction with an error less than 0.000001.

Examples

Input

3
0.0 0.0
4.0 0.0
2.0 2.0


Output

4.00


Input

4
0.0 0.0
1.0 0.0
1.0 1.0
0.0 1.0


Output

1.414213562373

Solution (in CPP):

Solution:
#include <bits/stdc++.h>

using namespace std;

#define EPS 1e-10
#define equal(a,b) (fabs(a-b) < EPS)
#define not_equal(a,b) (!equal(a,b))
#define lt(a,b) (a-b < -EPS)

struct Point{
  double x,y;

  Point(){}
  Point(double x,double y) : x(x),y(y) {}

  Point operator + (const Point &p)const{ return Point(x+p.x,y+p.y); }
  Point operator - (const Point &p)const{ return Point(x-p.x,y-p.y); }
  Point operator * (const double &k)const{ return Point(x*k,y*k); }
};

double dot(const Point &a,const Point &b){ return a.x*b.x+a.y*b.y; }
double cross(const Point &a,const Point &b){ return a.x*b.y - b.x*a.y; }
double norm(const Point &p){ return dot(p,p); }
double dist(const Point &a,const Point &b){
  return sqrt(pow(a.x-b.x,2) + pow(a.y-b.y,2));
}

#define COUNTER_CLOCKWISE 1
#define CLOCKWISE -1
#define ONLINE_BACK 2
#define ONLINE_FRONT -2
#define ON_SEGMENT 0
typedef Point Vector;

int ccw(Point p0,Point p1,Point p2){
  Vector a = p1 - p0;
  Vector b = p2 - p0;
  if(cross(a,b) > EPS){ return COUNTER_CLOCKWISE; }
  if(cross(a,b) < -EPS){ return CLOCKWISE; }
  if(dot(a,b) < -EPS){ return ONLINE_BACK; }
  if(norm(a) < norm(b)){ return ONLINE_FRONT; }
  return ON_SEGMENT;
}

bool sortX(Point p1,Point p2){
  if(p1.x != p2.x){
    return (p1.x - p2.x < -EPS);
  }else{
    return (p1.y - p2.y < -EPS);
  }
}

bool sortY(Point p1,Point p2){
  if(p1.y != p2.y){
    return (p1.y - p2.y < -EPS);
  }else{
    return (p1.x - p2.x < -EPS);
  }
}

typedef vector<Point> Polygon;

Polygon convex_hull(Polygon &ps){
  int N = ps.size(),j = 0;
  Polygon pg(N*2);
  sort(ps.begin(),ps.end(),sortX);
  for(int i = 0 ; i < N ; i++,j++){
    while(j >= 2 && ccw(pg[j-2],pg[j-1],ps[i]) == -1){
      j--;
    }
    pg[j] = ps[i];
  }
  int k = j+1;
  for(int i = N-2 ; i >= 0 ; i--,j++){
    while(j >= k && ccw(pg[j-2],pg[j-1],ps[i]) == -1){
      j--;
    }
    pg[j] = ps[i];
  }
  pg.resize(j-1);
  return pg;
}

double getPolygonDiameter(Polygon &p){
  Polygon np = convex_hull(p);
  int N = np.size();
  if(N == 2){ return dist(np[0],np[1]); }
  int i = 0,j = 0;
  for(int k = 0 ; k < N ; k++){
    if(!sortX(np[i],np[k])){ i = k; }
    if(sortX(np[j],np[k])){ j = k; }
  }
  double res = 0;
  int si = i,sj = j;
  while(i != sj || j != si){
    res = max(res,dist(np[i],np[j]));
    Point p1 = np[(i+1)%N]-np[i];
    Point p2 = np[(j+1)%N]-np[j];
    if(cross(p1,p2) < 0){
      i = (i + 1) % N;
    }else{
      j = (j + 1) % N;
    }
  }
  return res;
}

int main(){
  int N;
  cin >> N;
  Polygon p(N);
  for(int i = 0 ; i < N ; i++){
    cin >> p[i].x >> p[i].y;
  }
  printf("%.10f\n",getPolygonDiameter(p));
  return 0;
}