#include #include #include #include #include #include #define repeat(i,n) for (int i = 0; (i) < int(n); ++(i)) #define whole(f,x,...) ([&](decltype((x)) whole) { return (f)(begin(whole), end(whole), ## __VA_ARGS__); })(x) using namespace std; template void setmax(T & a, T const & b) { if (a < b) a = b; } template auto vectors(X x, T a) { return vector(x, a); } template auto vectors(X x, Y y, Z z, Zs... zs) { auto cont = vectors(y, z, zs...); return vector(x, cont); } bool is_on_field(int y, int x, int h, int w) { return 0 <= y and y < h and 0 <= x and x < w; } int main() { int n; cin >> n; vector x(n), y(n); repeat (i,n) { cin >> x[i] >> y[i]; x[i] += 10000; y[i] += 10000; assert (0 <= y[i] and y[i] <= 20000); assert (0 <= x[i] and x[i] <= 20000); } function dist = [&](int i, int j) { return hypot(x[i] - x[j], y[i] - y[j]); }; function const &)> farthest = [&](int i, vector const & acc) { return *whole(max_element, acc, [&](int j, int k) { return dist(i, j) < dist(i, k); }); }; const int Q = 20; const int K = 20000 / Q + 1; assert (20000 / Q < K); auto bucket = vectors(K, K, vector()); repeat (i,n) bucket[y[i] / Q][x[i] / Q].push_back(i); double ans = 1; vector used(n); repeat (i,n) if (not used[i]) { vector acc; { int it = 0; acc.push_back(i); used[i] = true; while (it < acc.size()) { int j = acc[it]; ++ it; for (int dy : { -1, 0, 1 }) { for (int dx : { -1, 0, 1 }) { int ny = y[j] / Q + dy; int nx = x[j] / Q + dx; if (is_on_field(ny, nx, K, K)) { for (int k : bucket[ny][nx]) if (not used[k] and dist(j, k) <= 10) { acc.push_back(k); used[k] = true; } } } } } } if (acc.size() < 300) { repeat (j, acc.size()) { repeat (i, j) { setmax(ans, dist(acc[i], acc[j]) + 2); } } } else { whole(random_shuffle, acc); repeat (i, min(300, acc.size())) { int j = farthest(i, acc); int k = farthest(j, acc); setmax(ans, dist(j, k) + 2); } } } printf("%.9lf\n", ans); return 0; }