#include <bits/stdc++.h>
using namespace std;
int cross(const complex<int>& a, const complex<int>& b) {
  return a.real() * b.imag() - a.imag() * b.real();
}
int hypot2(const complex<int>& a) {
  return a.real() * a.real() + a.imag() * a.imag();
}
int N;
vector<complex<int> > pt;
vector<complex<int> > hull(const vector<complex<int> >& p) {
  int n = p.size(), k = 0;
  if (n < 3) return p;
  vector<complex<int> > h(2 * n);
  for (int i = 0; i < n; ++i) {
    while (k >= 2 && cross(h[k - 1] - h[k - 2], p[i] - h[k - 2]) <= 0) --k;
    h[k++] = p[i];
  }
  for (int i = n - 2, e = k + 1; i >= 0; --i) {
    while (k >= e && cross(h[k - 1] - h[k - 2], p[i] - h[k - 2]) <= 0) --k;
    h[k++] = p[i];
  }
  h.resize(k);
  h.pop_back();
  return h;
}
bool with_one(const complex<int>& o, int m) {
  vector<complex<int> > p;
  copy_if(pt.begin(), pt.end(), back_inserter(p),
          [&](const complex<int>& a) { return hypot2(a - o) >= m; });
  auto h = hull(p);
  switch (h.size()) {
    case 0:
    case 1:
      return false;
    case 2:
      return hypot2(h[1] - h[0]) >= m;
  }
  int n = h.size();
  auto nx = [&](int i) { return i + 1 == n ? 0 : i + 1; };
  auto cal = [&](int i) { return h[nx(i)] - h[i]; };
  for (int i = 0, j = 0; i < n; ++i) {
    while (cross(cal(i), cal(j)) >= 0) {
      j = nx(j);
      if (hypot2(h[j] - h[i]) >= m) return true;
    }
  }
  return false;
}
bool ok(int m) {
  for (const complex<int>& p : pt) {
    if (with_one(p, m)) return true;
  }
  return false;
}
int main() {
  cout.precision(20);
  cout << fixed;
  cin >> N;
  for (int i = 0, x, y; i < N; ++i) {
    cin >> x >> y;
    pt.push_back({x, y});
  }
  sort(pt.begin(), pt.end(), [](const complex<int>& a, const complex<int>& b) {
    return a.real() < b.real() || a.real() == b.real() && a.imag() < b.imag();
  });
  int l = 0, h = 1e9;
  while (l + 1 < h) {
    int m = (l + h) / 2;
    if (ok(m))
      l = m;
    else
      h = m;
  }
  cout << sqrt(l) / 2 << "\n";
  return 0;
}
