1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
struct Point {
int x, y;
};
inline bool cmpx(Point fir, Point sec) {
if (fir.x == sec.x) {
return fir.y < sec.y;
}
return fir.x < sec.x;
}
inline bool cmpy(Point fir, Point sec) {
if (fir.y == sec.y) {
return fir.x < sec.x;
}
return fir.y < sec.y;
}
inline double distpp(Point a, Point b) {
return sqrt((double)(a.x - b.x) * (a.x - b.x) + (double)(a.y - b.y) * (a.y - b.y));
}

struct Rect {
int x1, x2, y1, y2;
inline Rect operator+(const Rect sec) const {
Rect ans;
ans.x1 = min(x1, sec.x1);
ans.x2 = max(x2, sec.x2);
ans.y1 = min(y1, sec.y1);
ans.y2 = max(y2, sec.y2);
return ans;
}
};
inline double distpr(Point a, Rect b) {
double ans = 0;
if (a.x < b.x1) ans += (double)(a.x - b.x1) * (a.x - b.x1);
if (a.x > b.x2) ans += (double)(a.x - b.x2) * (a.x - b.x2);
if (a.y < b.y1) ans += (double)(a.y - b.y1) * (a.y - b.y1);
if (a.y > b.y2) ans += (double)(a.y - b.y2) * (a.y - b.y2);
return sqrt(ans);
}

int n;
Point a[MAXn + 10];

int root, ls[MAXn + 10], rs[MAXn + 10];
Rect area[MAXn + 10];
inline void pushup(int id) {
area[id].x1 = area[id].x2 = a[id].x;
area[id].y1 = area[id].y2 = a[id].y;
if (ls[id]) area[id] = area[id] + area[ls[id]];
if (rs[id]) area[id] = area[id] + area[rs[id]];
}
int Build(int l, int r) {
if (l > r) return 0;
int mid = (l + r) >> 1;
double avx = 0, avy = 0, vax = 0, vay = 0;
for (int i = l; i <= r; ++i) {
avx += a[i].x;
avy += a[i].y;
}
avx /= r - l + 1;
avy /= r - l + 1;
for (int i = l; i <= r; ++i) {
vax += (a[i].x - avx) * (a[i].x - avx);
vay += (a[i].y - avy) * (a[i].y - avy);
}
if (vax > vay) nth_element(a + l, a + mid, a + 1 + r, cmpx);
else nth_element(a + l, a + mid, a + 1 + r, cmpy);
ls[mid] = Build(l, mid - 1);
rs[mid] = Build(mid + 1, r);
pushup(mid);
return mid;
}
double ans = INF;
void query(int id, int idx) {
if (id == 0) return;
if (id != idx) ans = min(ans, distpp(a[id], a[idx]));
double distls = distpr(a[idx], area[ls[id]]), distrs = distpr(a[idx], area[rs[id]]);
if (distls < ans && distrs < ans) {
if (distls < distrs) {
query(ls[id], idx);
if (distrs < ans) query(rs[id], idx);
} else {
query(rs[id], idx);
if (distls < ans) query(ls[id], idx);
}
} else if (distls < ans) {
query(ls[id], idx);
} else if (distrs < ans) {
query(rs[id], idx);
}
}
void Solve() {
for (int i = 1; i <= n; ++i) {
query(root, i);
}
}

signed main() {
read(n);
for (int i = 1; i <= n; ++i) {
read(a[i].x, a[i].y);
}
root = Build(1, n);
Solve();
printf("%.4lf\n", ans);
return 0;
}