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 <iostream>
#include <vector>
#include <string>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <map>
#include <set>
#include <cmath>

#define REP(i,k,n) for(int i=k;i<n;i++)
#define rep(i,n) for(int i=0;i<n;i++)
#define INF 1<<30
#define pb push_back
#define mp make_pair
#define EPS 1e-8
#define equals(a,b) fabs((a) - (b)) < EPS

using namespace std;
typedef long long ll;
typedef pair<int,int> P;

struct Point {
	double x, y;

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

	Point operator+(const Point &o) const { return Point(x+o.x, y+o.y); }

	Point operator-(const Point &o) const { return Point(x-o.x, y-o.y); }

	Point operator*(const double m) const { return Point(x*m, y*m); }

	Point operator/(const double d) const { return Point(x/d, y/d); }

	bool operator<(const Point &o) const { return x != o.x ? x < o.x : y < o.y; }

	bool operator==(const Point &o) const { return fabs(x-o.x) < EPS && fabs(y-o.y) < EPS; }
};

ostream& operator << (ostream& os, const Point& p) {
	os << "(" << p.x << ", " << p.y << ")";
	return os;
}

double dot(Point a, Point b) { return a.x * b.x + a.y * b.y; }
double cross(Point a, Point b) { return a.x * b.y - a.y * b.x; }
double atan(Point p) { return atan2(p.y, p.x); }
double norm(Point p) { return p.x * p.x + p.y * p.y; }
double abs(Point p) { return sqrt(norm(p)); }
double distancePP(Point p, Point o) { return sqrt(norm(o - p)); }

int ccw(Point a, Point b, Point c) {
	b = b-a;
	c = c-a;

	if(cross(b, c) > 0.0) return +1;	//conter clockwise
	if(cross(b, c) < 0.0) return -1;	//clockwise
	if(dot(b, c) < 0.0) return +2;	//a on Seg(b,c)
	if(norm(b) < norm(c)) return -2;	//b on Seg(a,c)
	return 0;	//c on Seg(a,b)
}

// bool cmp_y(const Point& a,const Point& b) {
// 	if(a.y != b.y) return a.y < b.y;
// 	return a.x < b.x;
// }

vector<Point> convex_hull(vector<Point> ps) {   
	int n = ps.size();
	sort(ps.begin(),ps.end());

	int k = 0;
	vector<Point> convex(n*2);

	rep(i, n) {
		while (k > 1 && ccw(convex[k-2], convex[k-1], ps[i]) == -1 ) {
			k--;
		}
		convex[ k++ ] = ps[i];
	}

	for(int i = n - 2, t = k; i >= 0; i--) {
		while (k > t && ccw(convex[k-2], convex[k-1], ps[i]) == -1 ) {
			k--;
		}
		convex[ k++ ] = ps[i];
	}

	convex.resize(k-1);
	return convex;
}

double convex_diameter(const vector<Point>& ps) {
	vector<Point> qs = convex_hull(ps);
	int n = qs.size();

	if(n == 2) return distancePP(qs[0], qs[1]);

	int i = 0, j = 0;
	rep(k, n) {
		if(!(qs[i] < qs[k])) i = k;
		if(qs[j] < qs[k]) j = k;
	}

	double ret = 0;
	int si = i, sj = j;
	while(i != sj || j != si) {
		ret = max(ret, distancePP(qs[i], qs[j]));
		if( cross(qs[(i+1)%n] - qs[i], qs[(j+1)%n] - qs[j]) < 0) {
			i = (i + 1) % n;
		} else {
			j = (j + 1) % n;
		}
	}
	return ret;
}

int main() {
	int n;
	cin >> n;

	vector<Point> v(n);
	rep(i, n) cin >> v[i].x >> v[i].y;

	cout << fixed;
	cout.precision(20);
	cout << convex_diameter(v) << endl;

	return 0;
}