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 rep(i, a, b) for(int i = a; i < (b); ++i)
#define trav(a, x) for(auto& a : x)
#define all(x) x.begin(), x.end()
#define sz(x) (int)(x).size()
#define scanf nope
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;

template <class T>
struct Point {
	typedef Point P;
	T x, y;
	explicit Point(T x=0, T y=0) : x(x), y(y) {}
	bool operator<(P p) const { return x<p.x||(x==p.x && y<p.y);}
	bool operator==(P p) const { return x==p.x && y==p.y; }
	P operator+(P p) const { return P(x+p.x, y+p.y); }
	P operator-(P p) const { return P(x-p.x, y-p.y); }
	P operator*(T d) const { return P(x*d, y*d); }
	P operator/(T d) const { return P(x/d, y/d); }
	T dot(P p) const { return x*p.x + y*p.y; }
	T cross(P p) const { return x*p.y - y*p.x; }
	T cross(P p1, P p2) const { return (p1 - *this).cross(p2 - *this); }
	T dist2() const { return x*x + y*y; }
	double dist() const { return sqrt((double)dist2()); }
	// angle to x-axis in interval [-pi, pi]
	double angle() const { return atan2(y, x); }
	P unit() const { return *this/dist(); } // makes dist()=1
	P perp() const { return P(-y, x); } // rotates +90 degrees
	P normal() const { return perp().unit(); }
	// returns point rotated 'a' radians ccw around the origin
	P rotate(double a) const {
		return P(x*cos(a)-y*sin(a),x*sin(a)+y*cos(a)); }
};

typedef Point<double> P;
pair<vi, vi> ulHull(const vector<P>& S) {
    vector<int> Q(sz(S));
    iota(all(Q), 0);
    sort(all(Q), [&S](int a, int b){ return S[a] < S[b]; });
    vi U, L;
    trav(it, Q) {
        while (sz(U) > 1 && S[U[sz(U)-2]].cross(S[it], S[U.back()]) <= 0) U.pop_back();
        while (sz(L) > 1 && S[L[sz(L)-2]].cross(S[it], S[L.back()]) >= 0) L.pop_back();
        U.push_back(it);
        L.push_back(it);
    }
    return make_pair(U, L);
}

vi convexHull(const vector<P>& S) {
    vi u, l;
    tie(u, l) = ulHull(S);
    if (sz(S) <= 1) return u;
    u.pop_back();
    reverse(all(u));
    u.pop_back();
    u.insert(u.end(), all(l));
    if (sz(u) == 2 && S[u[0]] == S[u[1]]) u.pop_back();
    return u;
}

vector<pii> antipodal(const vector<P>& S, const vi& U, const vi& L) {
    vector<pii> A;
    int i = 0;
    int j = sz(L) - 1;
    while (i < sz(U) - 1 || j > 0) {
        A.emplace_back(U[i], L[j]);
        if (i == sz(U) - 1) --j;
        else if (j == 0) ++i;
        else if ((S[U[i+1]].y - S[U[i]].y) * (S[L[j]].x - S[L[j-1]].x) >
                 (S[U[i+1]].x - S[U[i]].x) * (S[L[j]].y - S[L[j-1]].y)) ++i;
        else --j;
    }
    return A;
}

pii polygonDiameter(const vector<P>& S) {
    vi U, L;
    tie(U, L) = ulHull(S);
    pair<double, pii> ans;
    trav(it, antipodal(S, U, L)) {
        ans = max(ans, make_pair((S[it.first] - S[it.second]).dist2(), it));
    }
    return ans.second;
}

int main() {
    int N;
    cin >> N;
        vector<P> P(N);
        rep(i,0,N) cin >> P[i].x >> P[i].y;
        pii ret = polygonDiameter(P);
        cout << setprecision(10) << fixed << (P[ret.first] - P[ret.second]).dist() << endl;
}