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;
const double inf = 1e20;
const double eps = 1e-8;
const int N = 2e5 + 100;
int sgn (double x) {
    if (fabs (x) < eps) return 0;
    if (x < 0) return -1;
    return 1;
}
struct point {
    double x, y;
    point () {}
    point (double _x, double _y) {
        x = _x, y = _y;
    }
    void input () {
        scanf ("%lf %lf", &x, &y);
    }
    point operator - (const point &b) const {
        return point (x - b.x, y - b.y);
    }
    bool operator == (const point &b) const {
        return sgn (x - b.x) == 0 && sgn (y - b.y) == 0;
    }
    bool operator < (const point &b) const {
        if (sgn (y - b.y) == 0) return x < b.x;
        return y < b.y;
    }
    double operator * (const point &b) const {
        return x * b.x + y * b.y;
    }
    double operator ^ (const point &b) const {
        return x * b.y - y * b.x;
    }
    double cross (point a, point b) {
        return (point (a - *this) ^ point (b - *this));
    }
    double hot (point a, point b) {
        return (point (a - *this) * point (b - *this));
    }
    double len () {
        return hypot (x, y);
    }
};
struct polygon {
    int n;
    point ps[N];
    void input () {
        cin >> n;
        for (int i = 0; i < n; i++) ps[i].input ();
    }
    void getconvex (polygon &convex) {
        sort (ps, ps + n);
        int &top = convex.n;
        top = 0;
        convex.ps[top++] = ps[0];
        for (int i = 1; i < n; i++) {
            while (top >= 2 && convex.ps[top - 2].cross (convex.ps[top - 1], ps[i]) < 0) top--;
            convex.ps[top++] = ps[i];
        }
        int t = 0;
        for (int i = n - 2; i >= 0; i--) {
            while (t && convex.ps[top - 2].cross (convex.ps[top - 1], ps[i]) < 0) top--, t--;
            if (!i) break;
            convex.ps[top++] = ps[i];
            t++;
        }
    }
} s;
int main () {
    double ans = 0;
    int n;
    s.input ();
    n = s.n;
    s.n *= 2;
    for (int i = n; i < s.n; i++) s.ps[i] = s.ps[i - n];
    for (int i = 0; i < n / 2 + 1; i++) {
        int l = i + 1, r = i + n;
        while (l <= r) {
            int mid = l + r >> 1, flag1, flag2;
            if (point (s.ps[mid] - s.ps[i]).len () > point (s.ps[mid - 1] - s.ps[i]).len ()) flag1 = 1;
            else flag1 = 0;
            if (point (s.ps[mid] - s.ps[i]).len () > point (s.ps[mid + 1] - s.ps[i]).len ()) flag2 = 1;
            else flag2 = 0;
            if (flag1 && flag2) {
                ans = max (ans, point (s.ps[mid] - s.ps[i]).len ());
                break;
            } else if (flag1 && !flag2) l = mid + 1;
            else r = mid - 1;
        }
    }
    printf ("%.12f\n" ,ans);
    return 0;
}