#include "bits/stdc++.h"
using namespace std;
using ll = long long;
using Pii = pair<int, int>;
using Pll = pair<ll, ll>;
#define rep(i, begin, n) for (int i = begin; i < n; i++)
#define repe(i, begin, n) for (int i = begin; i <= n; i++)
#define repr(i, begin, n) for (int i = begin; i > begin - n; i--)
#define repre(i, begin, end) for (int i = begin; i >= end; i--)

template <class T>
inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}

template <class T>
inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}

const int inf = 1000000007;
const int MOD = 1000000007;
const long long INF = 1000000000000000007;

// -------------------------------------------------------

using ld = long double;

using FloatType = long double;
using P = complex<FloatType>;

#define EPS (1e-10)
#define EQ(a, b) (abs((a) - (b)) < EPS)
#define EQV(a, b) (EQ((a).real(), (b).real()) && EQ((a).imag(), (b).imag()))

FloatType dot(P a, P b) { return a.real() * b.real() + a.imag() * b.imag(); }

FloatType cross(P a, P b) { return a.real() * b.imag() - a.imag() * b.real(); }

// 2直線の直行判定
bool is_orthogonal(P a1, P a2, P b1, P b2) {
  return EQ(dot(a1 - a2, b1 - b2), 0.0);
}

// 2直線の平行判定
bool is_parallel(P a1, P a2, P b1, P b2) {
  return EQ(cross(a1 - a2, b1 - b2), 0.0);
}

// 点cが直線a-b上にあるか
bool is_point_on_line(P a, P b, P c) { return EQ(cross(b - a, c - a), 0.0); }

// 点cが線分a-b上にあるか
bool is_point_on_line_segment(P a, P b, P c) {
  return (abs(c - a) + abs(c - b) < abs(b - a) + EPS);
}

// 点a,bを通る直線と点cとの距離
FloatType distance_l_p(P a, P b, P c) {
  return abs(cross(b - a, c - a)) / abs(b - a);
}

// 点a,bを通る線分と点cとの距離
FloatType distance_ls_p(P a, P b, P c) {
  if (dot(b - a, c - a) < EPS) return abs(c - a);
  if (dot(a - b, c - b) < EPS) return abs(c - b);
  return distance_l_p(a, b, c);
}

// a1,a2を端点とする線分とb1,b2を端点とする線分の交差判定
FloatType is_intersected_ls(P a1, P a2, P b1, P b2) {
  return (cross(a2 - a1, b1 - a1) * cross(a2 - a1, b2 - a1) < EPS) &&
         (cross(b2 - b1, a1 - b1) * cross(b2 - b1, a2 - b1) < EPS);
}

// a1,a2を端点とする線分とb1,b2を端点とする線分の交点計算
P intersection_ls(P a1, P a2, P b1, P b2) {
  P b = b2 - b1;
  FloatType d1 = abs(cross(b, a1 - b1));
  FloatType d2 = abs(cross(b, a2 - b1));
  FloatType t = d1 / (d1 + d2);

  return a1 + (a2 - a1) * t;
}

// a1,a2を通る直線とb1,b2を通る直線の交差判定
bool is_intersected_l(P a1, P a2, P b1, P b2) {
  return !EQ(cross(a1 - a2, b1 - b2), 0.0);
}

// a1,a2を通る直線とb1,b2を通る直線の交点計算
P intersection_l(P a1, P a2, P b1, P b2) {
  P a = a2 - a1;
  P b = b2 - b1;
  return a1 + a * cross(b, b1 - a1) / cross(b, a);
}

ll N;
vector<P> Points;

ld max_dist(P p) {
  ld res = 0;
  for (P cp : Points) {
    chmax(res, abs(cp - p));
  }
  return res;
}

ld g(ld x) {
  ld ub = 1000.0L;
  ld lb = 0.0L;

  rep(loopcnt, 0, 50) {
    ld lbm = (2 * lb + ub) / 3.0L;
    ld ubm = (2 * ub + lb) / 3.0L;

    ld resub = max_dist(P(x, ub));
    ld resubm = max_dist(P(x, ubm));
    ld reslbm = max_dist(P(x, lbm));
    ld reslb = max_dist(P(x, lb));

    if (reslbm > resubm) {
      lb = lbm;
    } else {
      ub = ubm;
    }
  }

  return ub;
}

int main() {
  cin >> N;
  Points.resize(N);
  rep(i, 0, N) {
    ll x, y;
    cin >> x >> y;
    Points[i] = P(x, y);
  }

  ld ub = 1000.0L;
  ld lb = 0.0L;
  rep(loopcnt, 0, 50) {
    ld lbm = (2 * lb + ub) / 3.0L;
    ld ubm = (2 * ub + lb) / 3.0L;

    ld resubm = max_dist(P(ubm, g(ubm)));
    ld reslbm = max_dist(P(lbm, g(lbm)));

    if (reslbm > resubm) {
      lb = lbm;
    } else {
      ub = ubm;
    }
  }

  cout << setprecision(20) << fixed << max_dist(P(ub, g(ub))) << endl;
}


Measured memory_bytes: 3880