#include <bits/stdc++.h>

using namespace std;

#define INF 100000000
#define YJ 1145141919
#define INF_INT_MAX 2147483647
#define INF_LL 9223372036854775
#define INF_LL_MAX 9223372036854775807
#define EPS 1e-10
#define MOD 1000000007
#define MOD9 998244353
#define Pi acos(-1)
#define LL long long
#define ULL unsigned long long
#define LD long double

#define int long long
#define double long double

using II = pair<int, int>;

int gcd(int a, int b) { return b != 0 ? gcd(b, a % b) : a; }
int lcm(int a, int b) { return a * b / gcd(a, b); }
int extgcd(int a, int b, int &x, int &y) { int g = a; x = 1; y = 0; if (b != 0) g = extgcd(b, a % b, y, x), y -= (a / b) * x; return g; }

#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
#define ALL(a)  begin((a)), end((a))
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define MP make_pair
#define SZ(a) int((a).size())

/*********************************************************

幾何ライブラリ

点を表すクラス
・Point
ベクトルを表すクラス
・Vector
線分を表すクラス
・Segment
直線を表すクラス
・Line
円を表すクラス
・Circle
多角形を表すクラス
・Polygon

内積を返す関数
・double dot(Vector a, Vector b)

外積の大きさ
・double cross(Vector a, Vector b)

degをradに変換
・double changeDegToRad(double x)

原点を中心に点pをrad回転させた時の点を返す
・Point rollPointRad(Point p, double rad)

線分ｓに対して、点Pから引いた垂線との交点の座標
・Point project(Line s, Point p)

線分sを対称軸とした点ｐの線対称の点
・Point reflect(Segment s, Point p)

線分po->p1に対してp2はp0を基準にどの方向に回転させたか
・int ccw(Point p0, Point p1, Point p2)

二つの線分の交差判定
・bool intersect(Segment s1, Segment s2)

二点の距離
・double getDistancePP(Point a, Point b)

直線lと点pの距離
・double getDistanceLP(Line l, Point p)

線分sと点pの距離
・double getDistanceSP(Segment s, Point p)

線分と線分の距離
・double getDistanceSS(Segment s1, Segment s2)

線分と線分の交点
・Point getCrossPoint(Segment s1, Segment s2)

円C1とC2の交点を求める(交差しない場合は判定しない)
・pair<Point, Point> getCrossPoints(Circle c1, Circle c2)

円Cと線分lの交点(交点を持たない場合は判定しない)
・pair<Point, Point> getCrossPoints(Circle c, Line l)

多角形gの中に点pが含まれているかどうか(IN, OUT, ON)
・int contains(Polygon g, Point p)

2円の共通接線
・vector<Line> tangentCircleLines(Circle c1, Circle c2)

凸法(直線上にある点もすべて反時計周りに列挙する)
・Polygon andrewScan(Polygon s)

*********************************************************/


const double mEPS = 1e-10;

//点をあらわすクラス
class Point{
public:
  double x, y;

  Point(double x = 0.0, double y = 0.0) : x(x), y(y){}

  Point operator + (Point p){ return Point(x + p.x, y + p.y); }
  Point operator - (Point p){ return Point(x - p.x, y - p.y); }
  Point operator * (double a){ return Point(a*x, a*y); }
  Point operator / (double a){ return Point(x / a, y / a); }

  double abs(){ return sqrt(norm()); } //距離
  double norm(){ return x*x + y*y; }

  bool operator < (const Point &p) const{
    return x != p.x ? x < p.x : y < p.y;
  }

  //EPSは十分小さな値
  bool operator == (const Point &p) const {
    return fabs(x - p.x) < mEPS && fabs(y - p.y) < mEPS;
  }

};

class Segment{
public:
  Point p1, p2;
};

class Circle{
public:
  Point c;
  double r;
};

typedef vector<Point> Polygon;

//点を線として扱う
typedef Point Vector;
//線分を直線として扱う
typedef Segment Line;

//内積
double dot(Vector a, Vector b){
  return a.x*b.x + a.y*b.y;
}

//外積の大きさ
double cross(Vector a, Vector b){
  return a.x*b.y - a.y*b.x;
}

//degをradに変換
double changeDegToRad(double x){
  return x*acos(-1)/180.0;
}

//原点を中心に点pをrad回転させた時の点を返す
Point rollPointRad(Point p, double rad){
  Point ret;
  ret.x = p.x*cos(rad) - p.y*sin(rad);
  ret.y = p.x*sin(rad) + p.y*cos(rad);
  return ret;
}

//線分ｓに対して、点Pから引いた垂線との交点の座標
Point project(Line s, Point p){
  Vector base = s.p2 - s.p1;
  double r = dot(p - s.p1, base) / base.norm();
  return s.p1 + base*r;
}

//線分sを対称軸とした点ｐの線対称の点
Point reflect(Segment s, Point p){
  return p + (project(s, p) - p) * 2.0;
}

//線分po->p1に対してp2はp0を基準にどの方向に回転させたか
int ccw(Point p0, Point p1, Point p2){

  //p0->p1をp0始点、p1終点の基準ベクトルとしたとき

  //p0->p2が反時計回りになるとき
  static const int COUNTER_CLOCKWISE = 1;
  //p0->p2が時計回りになるとき
  static const int CLOCKWISE = -1;
  //p2,p0,p1の順で同一直線上にあるとき
  static const int ONLINE_BACK = 2;
  //p0,p1,p2 の順で同一直線上にある場合
  static const int ONLINE_FRONT = -2;
  //p2 が線分 p0p1 上にある場合
  static const int ON_SEGMENT = 0;

  Vector a = p1 - p0;
  Vector b = p2 - p0;

  if (cross(a, b) > mEPS) return COUNTER_CLOCKWISE;
  if (cross(a, b) < -mEPS) return CLOCKWISE;
  if (dot(a, b) < -mEPS) return ONLINE_BACK;
  if (a.norm() < b.norm()) return ONLINE_FRONT;

  return ON_SEGMENT;

}

//二つの線分の交差判定
bool intersect(Segment s1, Segment s2){
  return(ccw(s1.p1, s1.p2, s2.p1) * ccw(s1.p1, s1.p2, s2.p2) <= 0 &&
	 ccw(s2.p1, s2.p2, s1.p1) * ccw(s2.p1, s2.p2, s1.p2) <= 0);
}

//二点の距離
double getDistancePP(Point a, Point b){
  return (a - b).abs();
}

//直線lと点pの距離
double getDistanceLP(Line l, Point p){
  return abs(cross(l.p2 - l.p1, p - l.p1) / (l.p2 - l.p1).abs());
}

//線分sと点pの距離
double getDistanceSP(Segment s, Point p){
  if (dot(s.p2 - s.p1, p - s.p1) < 0.0) return (p - s.p1).abs();
  if (dot(s.p1 - s.p2, p - s.p2) < 0.0) return (p - s.p2).abs();
  return getDistanceLP(s, p);
}

//線分と線分の距離
double getDistanceSS(Segment s1, Segment s2){
  if (intersect(s1, s2)) return 0.0;
  return min(min(getDistanceSP(s1, s2.p1), getDistanceSP(s1, s2.p2)),
	     min(getDistanceSP(s2, s1.p1), getDistanceSP(s2, s1.p2)));
}

//線分と線分の交点
Point getCrossPoint(Segment s1, Segment s2){
  Vector base = s2.p2 - s2.p1;
  double d1 = abs(cross(base, s1.p1 - s2.p1));
  double d2 = abs(cross(base, s1.p2 - s2.p1));
  double t = d1 / (d1 + d2);
  return s1.p1 + (s1.p2 - s1.p1)*t;
}

//円Cと線分lの交点(交点を持たない場合は判定しない)
pair<Point, Point> getCrossPoints(Circle c, Line l){

  Vector pr = project(l, c.c);
  Vector e = (l.p2 - l.p1) / (l.p2 - l.p1).abs();

  double base = sqrt(c.r*c.r - (pr - c.c).norm());
  return make_pair(pr + e * base, pr - e*base);

}

double arg(Vector p){ return atan2(p.y, p.x); }
Vector polar(double a, double r){ return Point(cos(r)*a, sin(r)*a); }

//円C1とC2の交点を求める(交差しない場合は判定しない)
pair<Point, Point> getCrossPoints(Circle c1, Circle c2){
  double d = (c1.c - c2.c).abs();
  double a = acos((c1.r*c1.r + d*d - c2.r*c2.r) / (2 * c1.r*d));
  double t = arg(c2.c - c1.c);
  return make_pair(c1.c + polar(c1.r, t + a), c1.c + polar(c1.r, t - a));
}

//2円の共通接線
vector<Line> tangentCircleLines(Circle c1, Circle c2){

  vector<Line> ret;

  double d = getDistancePP(c1.c, c2.c);

  for(int i = 0; i < 2; i++){
    double sin = (c1.r - (1 - i*2)*c2.r)/d;
    if(!(sin*sin < 1 + mEPS))
      break;
    double cos = sqrt(max((double)1-sin*sin, (double)0.0));
    for(int j = 0; j < 2; j++){
      Point a = c2.c - c1.c;
      Point b(sin, (1-j*2)*cos);
      Point n;
      n.x = (a.x*b.x - a.y*b.y)/d; n.y = (a.x*b.y + a.y*b.x)/d;
      Line tmp;
      tmp.p1 = c1.c + n*c1.r;
      tmp.p2 = c2.c + n*(1-i*2)*c2.r;
      ret.push_back(tmp);
      if(cos < mEPS)
	      break; //重複する接線を無視
    }
  }

  return ret;

}

//多角形gの中に点pが含まれているかどうか
int contains(Polygon g, Point p){

  const int IN = 2;
  const int ON = 1;
  const int OUT = 0;

  int n = g.size();

  bool x = false;

  for (int i = 0; i < n; i++){
    Point a = g[i] - p, b = g[(i + 1) % n] - p;
    if (abs(cross(a, b)) < mEPS && dot(a, b) < mEPS) return ON;
    if (a.y > b.y) swap(a, b);
    if (a.y < mEPS && mEPS < b.y && cross(a, b) > mEPS) x = !x;
  }

  return (x ? IN : OUT);

}

//凸法(直線上にある点もすべて反時計周りに列挙する)
Polygon andrewScan(Polygon s){

  Polygon u, l;

  if (s.size() < 3) return s;

  sort(s.begin(), s.end()); //x,yを基準にソート

  u.push_back(s[0]);
  u.push_back(s[1]);

  l.push_back(s[s.size() - 1]);
  l.push_back(s[s.size() - 2]);

  //凸方の上部を生成
  for (int i = 2; i < s.size(); i++){
    for (int n = u.size(); n >= 2 && ccw(u[n - 2], u[n - 1], s[i]) == 1; n--){
      u.pop_back();
    }
    u.push_back(s[i]);
  }

  //凸法の下部を生成
  for (int i = s.size() - 3; i >= 0; i--){
    for (int n = l.size(); n >= 2 && ccw(l[n - 2], l[n - 1], s[i]) == 1; n--){
      l.pop_back();
    }
    l.push_back(s[i]);
  }

  //反時計回りになるように凸包の点の列
  reverse(l.begin(), l.end());
  for (int i = u.size() - 2; i >= 1; i--)
    l.push_back(u[i]);

  return l;

}

const int MAX_N = 51;
int N;
Point P[MAX_N];

signed main()
{
  cin >> N;
  REP(n,N) {
    cin >> P[n].x >> P[n].y;
  }

  if(N <= 2) {
    printf("%.15Lf\n", (P[0] - P[1]).abs() / 2);
    return 0;
  }

  double ans = INF;
  REP(i1, N) {
    FOR(i2,i1+1,N) {
      FOR(i3,i2+1,N) {
        Point p1 = P[i1], p2 = P[i2], p3 = P[i3];

        int ccwv = ccw(p1, p2, p3);
        if(ccwv == 0 || ccwv == 2 || ccwv == -2) {
          continue;
        }

        Vector vec1, vec2;
        vec1 = p1 - p2; vec2 = p2 - p3;
        Vector mid1 = vec1 / 2, mid2 = vec2 / 2;
        Vector h1 = rollPointRad(mid1, changeDegToRad(90));
        Vector rh1 = rollPointRad(mid1, changeDegToRad(270));
        Vector h2 = rollPointRad(mid2, changeDegToRad(90));
        Vector rh2 = rollPointRad(mid2, changeDegToRad(270));
        
        Line l1, l2;
        l1.p1 = p2 + mid1 + (h1 * 1000000); l1.p2 = p2 + mid1 + (rh1 * 1000000);
        l2.p1 = p3 + mid2 + (h2 * 1000000); l2.p2 = p3 + mid2 + (rh2 * 1000000);

        Point centerP = getCrossPoint(l1, l2);
        double r = (centerP - p1).abs() + 0.0000001;
        bool check = true;
        REP(n,N) {
          if((centerP - P[n]).abs() > r) {
            check = false;
          }
        }
        if(check) {
          ans = min(ans, r);
        }
      }
    }
  }

  REP(i1, N) {
    FOR(i2,i1+1,N) {
      Point centerP = P[i2] + (P[i1] - P[i2])/2;
      double r = (centerP - P[i1]).abs() + 0.0000001;
      bool check = true;
      REP(n,N) {
        if((centerP - P[n]).abs() > r) {
          check = false;
        }
      }
      if(check) {
        ans = min(ans, r);
      }
    }
  }

  printf("%.15Lf\n", ans);

  return 0;
}


Measured memory_bytes: 384