#include <bits/stdc++.h>

using namespace std;

typedef long long int64;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef complex<double> point;
typedef vector<point> polygon;

double cross(point a, point b) { return imag(conj(a) * b); }

double area2(point a, point b, point c) { return cross(b - a, c - a); }

double dot(point a, point b) { return real(conj(a) * b); }

int ccw(point a, point b, point c)
{
	b -= a; c -= a;
	if (cross(b, c) > 0) return +1; // counter clockwise
	if (cross(b, c) < 0) return -1; // clockwise
	if (dot(b, c) < 0) return +2; // c--a--b on line
	if (dot(b, b) < dot(c, c)) return -2; // a--b--c on line
	return 0;
}

namespace std
{
	bool operator<(point a, point b)
	{
		if (a.real() != b.real())
			return a.real() < b.real();
		return a.imag() < b.imag();
	}
}


polygon convex_hull(vector<point> &P)
{
	int n = P.size(), k = 0;
	vector<point> h(2 * n);
	sort(P.begin(), P.end());
	for (int i = 0; i < n; h[k++] = P[i++])
		while (k >= 2 && ccw(h[k - 2], h[k - 1], P[i]) <= 0) --k;
	for (int i = n - 2, t = k + 1; i >= 0; h[k++] = P[i--])
		while (k >= t && ccw(h[k - 2], h[k - 1], P[i]) <= 0) --k;
	return polygon(h.begin(), h.begin() + k - (k > 1));
}


double sqr(double v){
	return v * v;
}

double dist(point a, point b){
	return sqrt(sqr(a.real() - b.real()) + sqr(a.imag() - b.imag()));
}


#define NEXT(i) (((i) + 1) % n)

vector<pii> get_points (polygon &P)
{
	vector<pii> ans;
	int n = P.size();

	if (P.size() == 2)
		ans.push_back(make_pair(0, 1));

	if (P.size() < 3)
		return ans;

	int q0 = 0;

	while (abs(area2(P[n - 1], P[0], P[NEXT(q0)])) > 
		   abs(area2(P[n - 1], P[0], P[q0])))
		++q0;

	for (int q = q0, p = 0; q != 0 && p <= q0; ++p)
	{
		ans.push_back(make_pair(p, q));

		while (abs(area2(P[p], P[NEXT(p)], P[NEXT(q)])) > 
			   abs(area2(P[p], P[NEXT(p)], P[q])))
		{
			q = NEXT(q);

			if (p != q0 || q != 0)
				ans.push_back(make_pair(p, q));
			else
				return ans;
		}

		if (abs(area2(P[p], P[NEXT(p)], P[NEXT(q)])) == 
			    abs(area2(P[p], P[NEXT(p)], P[q])))
		{
			if (p != q0 || q != n - 1)
				ans.push_back(make_pair(p, NEXT(q)));
			else
				ans.push_back(make_pair(NEXT(p), q));
		}
	}

	return ans;
}

/*
	Gets the farthest pair of points of the given points.
	(maybe TLE using double)

	TESTED [POJ 2187]
*/
pair<point, point> farthest_pair (polygon &P)
{
	P = convex_hull(P);
	vector<pii> pairs = get_points(P);

	double best = 0;
	pair<point, point> ans;

	for (int i = 0; i < pairs.size(); ++i)
	{
		point p1 = P[pairs[i].first];
		point p2 = P[pairs[i].second];
		double dist = norm(p1- p2);

		if (dist > best)
		{
			best = dist;
			ans = make_pair(p1, p2);
		}
	}

	return ans;
}

int main()
{
	ios_base::sync_with_stdio(0);
	cin.tie(0);

	int n; cin >> n;
	vector<point> v(n);
	for (int i = 0; i < n; ++i){
		double x, y; cin >> x >> y;
		v[i] = point(x, y);
	}
	pair<point,point> fp = farthest_pair(v);
	double ans = dist(fp.first, fp.second);

	cout.precision(15);
	cout << fixed << ans << endl;

	return 0;
}