// g++ -O3 -fmax-errors=1 -fsanitize=undefined -fsanitize=address -sanitize=leak 
#include <bits/stdc++.h>

using namespace std;

using Scalar = long double;
const Scalar EPS = 1e-8;
int sign(Scalar x) { 
  if (x >  EPS) return +1;
  if (x < -EPS) return -1;
  return 0;
}
struct Point {
  Scalar x, y;
  Point(Scalar x = 0, Scalar y = 0) : x(x), y(y) { }
  Point operator+() const    { return {+x, +y}; }
  Point operator-() const    { return {-x, -y}; }
  Point &operator+=(Point p) { x += p.x; y += p.y; return *this; }
  Point &operator-=(Point p) { return *this += -p; }
  Point &operator*=(Scalar a)  { x *= a;   y *= a;   return *this; }
  Point &operator/=(Scalar a)  { return *this *= 1/a; }
};
Point operator+(Point p, Point q) { return p += q; }
Point operator-(Point p, Point q) { return p -= q; }
Point operator*(Scalar a, Point p) { return p *= a; }
Point operator*(Point p, Scalar a) { return p *= a; }
Point operator/(Point p, Scalar a) { return p /= a; }

int compare(Point p, Point q) { 
  int s = sign(p.x - q.x);
  return s ? s : sign(p.y - q.y);
}
bool operator==(Point p, Point q) { return compare(p,q)==0; }
bool operator!=(Point p, Point q) { return compare(p,q)!=0; }
bool operator<=(Point p, Point q) { return compare(p,q)<=0; }
bool operator>=(Point p, Point q) { return compare(p,q)>=0; }
bool operator<(Point p, Point q) { return compare(p,q)<0; }
bool operator>(Point p, Point q) { return compare(p,q)>0; }


Scalar dot(Point p, Point q) { return p.x*q.x+p.y*q.y; }
Scalar cross(Point p, Point q) { return p.x*q.y-p.y*q.x; } // left turn > 0
Scalar norm2(Point p) { return dot(p,p); }
Point orth(Point p) { return {-p.y, p.x}; }
Scalar norm(Point p) { return sqrt(dot(p,p)); }
Scalar arg(Point p) { return atan2(p.y, p.x); }
Scalar arg(Point p, Point q){ return atan2(cross(p,q), dot(p,q)); }

istream &operator>>(istream &is, Point &p) { is>>p.x>>p.y;return is; }
ostream &operator<<(ostream &os, const Point &p) { os<<"("<<p.x<<","<<p.y<<")"; return os; }


struct MinimumEnclosingCircle {
  Point center = {0, 0};
  Scalar radius2 = -1;

  std::list<Point> ps;
  std::list<Point>::iterator supp_end;
  int m = 0; // stack
  Point v[4], c[4];
  Scalar z[4], r[4];
  void push(const Point& p) {
    if (m == 0) {
      c[0] = p; 
      r[0] = 0;
    } else {
      Scalar e = dot(p-c[m-1],p-c[m-1]) - r[m-1];
      Point delta = p - c[0];
      v[m] = delta;
      for (int i = 1; i < m; ++i)
        v[m] -= v[i] * dot(v[i], delta)/z[i];
      z[m] = dot(v[m], v[m]);
      c[m] = c[m-1] + e*v[m]/z[m]/2;
      r[m] = r[m-1] + e*e/z[m]/4;
    }
    center  = c[m];
    radius2 = r[m];
    ++m;
  }
  void rec(list<Point>::iterator end) {
    supp_end = ps.begin();
    if (m == 4) return;
    for (auto k = ps.begin(); k != end; ) {
      auto j = k++;
      if (sign(dot(*j-center,*j-center) - radius2) > 0) {
        push(*j); rec(j); --m;
        if (supp_end == j) ++supp_end;
        ps.splice(ps.begin(), ps, j); // move to front
      }
    }
  }
  template <class Input>
  MinimumEnclosingCircle(Input data) {
    random_shuffle(data.begin(), data.end());
    ps.insert(ps.end(), data.begin(), data.end());
    rec(ps.end());
  }
  vector<Point> support() {
    return vector<Point>(ps.begin(), supp_end);
  }
};

int main() {
  int n;
  cin >> n;
  vector<Point> ps;
  for (int i = 0; i < n; ++i) {
    double x, y;
    cin >> x >> y;
    ps.emplace_back(x, y);
  }
  MinimumEnclosingCircle solver(ps);
  printf("%.12Lf\n", sqrt(solver.radius2));
}


Measured memory_bytes: 256