#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <vector>
using namespace std;
typedef long double Coordinate; // for int change it to long long
struct Point
{
Coordinate x, y;
Coordinate length2()const{return x*x + y*y;}
long double length()const{return sqrt((long double)length2());}
};
struct CompareX
{
bool operator () (const Point &a, const Point &b) const
{
return a.x < b.x || (a.x == b.x && a.y < b.y);
}
};
typedef vector<Point> Poligonal;
const Coordinate EPS = 1e-15; // for int change it to 0
Point operator - (const Point &a, const Point &b) { return {a.x - b.x, a.y - b.y}; }
Coordinate operator * (const Point &a, const Point &b) { return a.x * b.y - a.y * b.x; } /*cross*/
Coordinate operator ^ (const Point &a, const Point &b) { return a.x * b.x + a.y * b.y; } /*dot*/
/*CW*/
inline Poligonal getConvexHull(Poligonal poligonial)
{
sort(poligonial.begin(), poligonial.end(), CompareX());
Poligonal upperConvexHull, lowerConvexHull;
for (const Point &point : poligonial)
{
while (upperConvexHull.size() >= 2 &&
(point - upperConvexHull[upperConvexHull.size()-2]) *
(upperConvexHull[upperConvexHull.size()-1] - upperConvexHull[upperConvexHull.size()-2]) <= EPS)
{
upperConvexHull.pop_back();
}
upperConvexHull.push_back(point);
while (lowerConvexHull.size() >= 2 &&
(point - lowerConvexHull[lowerConvexHull.size()-2]) *
(lowerConvexHull[lowerConvexHull.size()-1] - lowerConvexHull[lowerConvexHull.size()-2]) >= -EPS)
{
lowerConvexHull.pop_back();
}
lowerConvexHull.push_back(point);
}
upperConvexHull.insert(upperConvexHull.end(), lowerConvexHull.rbegin()+1, lowerConvexHull.rend()-1);
return upperConvexHull;
}
vector < pair < Point, Point > > getAntipodalPairs(Poligonal poligonal)
{
poligonal = getConvexHull(poligonal);
vector < pair < Point, Point > > antipodalPairs;
int i = 0, j = 1;
while(
((poligonal[(j+1) % poligonal.size()] - poligonal[j]) * (poligonal[i+1] - poligonal[i])) > EPS &&
((poligonal[(j+1) % poligonal.size()] - poligonal[j]) ^ (poligonal[i+1] - poligonal[i])) > EPS
)
{
j = (j+1) % poligonal.size();
}
antipodalPairs.emplace_back(poligonal[i], poligonal[j]);
int current = i;
while(j + 1 < poligonal.size())
{
Point currentVector = poligonal[(current+1)%poligonal.size()] - poligonal[current];
Point iVector = poligonal[(i+1)%poligonal.size()] - poligonal[i];
Point jVector = poligonal[j+1] - poligonal[j];
if (currentVector * iVector < currentVector * jVector ||
abs(currentVector * jVector - currentVector * iVector) <= EPS)
{
i = (i+1) % poligonal.size();
current = i;
}
else
{
++j;
current = j;
}
antipodalPairs.emplace_back(poligonal[i], poligonal[j]);
currentVector = poligonal[(current+1)%poligonal.size()] - poligonal[current];
iVector = poligonal[(i+1)%poligonal.size()] - poligonal[i];
jVector = poligonal[j+1] - poligonal[j];
if (abs(currentVector * iVector - currentVector * jVector) <= EPS)
{
antipodalPairs.emplace_back(poligonal[(i+1)%poligonal.size()], poligonal[j]);
antipodalPairs.emplace_back(poligonal[(i+1)%poligonal.size()], poligonal[j+1]);
antipodalPairs.emplace_back(poligonal[i], poligonal[j+1]);
if (current == i)
{
++j;
}
else
{
i = (i+1) % poligonal.size();
}
}
}
return antipodalPairs;
}
vector < pair < Point, Point > > getAntipodalPairs2(Poligonal poligonal)
{
poligonal = getConvexHull(poligonal);
vector < pair < Point, Point > > antipodalPairs;
int j = 0;
for (int i = 0; i < (int)poligonal.size(); ++i)
{
while ((poligonal[i] - poligonal[j]).length2() <= (poligonal[i] - poligonal[(j + 1) % (int)poligonal.size()]).length2() && i != (j + 1) % (int)poligonal.size()) {
j = (j + 1) % (int)poligonal.size();
}
antipodalPairs.emplace_back(poligonal[i], poligonal[j]);
}
return antipodalPairs;
}
inline void kattis_roberthood()
{
int c;
while (~scanf("%d", &c))
{
Poligonal shots(c);
for (int i = 0; i < c; ++i)
{
scanf("%Lf%Lf", &shots[i].x, &shots[i].y);
}
auto antipodalPairs = getAntipodalPairs2(shots);
long double answer = 0.0L;
for (const auto &antipodalPair : antipodalPairs)
{
answer = max(answer, (antipodalPair.first - antipodalPair.second).length());
}
printf("%.8Lf\n", answer);
}
}
int main()
{
kattis_roberthood();
return 0;
}