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

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);
    }
}

#define prev(G,i) (G[(i-1+G.size())%G.size()])
#define curr(G,i) (G[i%G.size()])
#define next(G,i) (G[(i+1)%G.size()])

typedef vector<Point> Polygon;

Polygon convex_hull(Polygon &ps){
    int N = ps.size(),j = 0;
    Polygon pg(N*2);
    sort(ps.begin(),ps.end(),sortY);
    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 pg(N);
    for(int i = 0 ; i < N ; i++){
        cin >> pg[i].x >> pg[i].y;
    }
    printf("%.12f\n",getPolygonDiameter(pg));
    return 0;
}