#include <bits/stdc++.h>
using namespace std;
#define rep(i,n) REP(i,0,n)
#define REP(i,s,e) for(int i=(s); i<(int)(e); i++)
#define repr(i, n) REPR(i, n, 0)
#define REPR(i, s, e) for(int i=(int)(s-1); i>=(int)(e); i--)
#define pb push_back
#define all(r) r.begin(),r.end()
#define rall(r) r.rbegin(),r.rend()
#define fi first
#define se second

// #define DEBUG_MODE
#ifdef DEBUG_MODE
#define dump(x) cout << #x << " : " << x << " "
#define dumpL(x) cout << #x << " : " << x << '\n'
#define LINE cout << "line : " << __LINE__ << " "
#define LINEL cout << "line : " << __LINE__ << '\n'
#define dumpV(v) cout << #v << " : ["; for(auto& t : v) cout << t << ", "; cout<<"]" << " "
#define dumpVL(v) cout << #v << " : ["; for(auto& t : v) cout << t << ", "; cout<<"]" << endl
#define STOP assert(false)
#else
#define dump(x) 
#define dumpL(x) 
#define LINE 
#define LINEL 
#define dumpV(v) 
#define dumpVL(v) 
#define STOP assert(false)
#endif
#define mp make_pair
 
namespace std {
template<class S, class T>
ostream &operator <<(ostream& out, const pair<S, T>& a) {
    out << '(' << a.fi << ", " << a.se << ')';
    return out;
}
}



template<typename T> T chmax(T& a, const T& b){return a = (a > b ? a : b);}
template<typename T> T chmin(T& a, const T& b){return a = (a < b ? a : b);}

#define X real()
#define Y imag()
#define x(p) real(p)
#define y(p) imag(p)
#define curr(P, i) P[i]
#define next(P, i) P[(i+1)%P.size()]
#define prev(P, i) P[(i+P.size()-1)%P.size()]

using D = double;

const D EPS = 1e-8;
const D INF = 1e12;
const D PI = acos(-1);
typedef complex<D> P;
typedef complex<D> point;
namespace std {
    bool operator < (const P& a, const P& b) {
        return x(a) != x(b) ? x(a) < x(b) : y(a) < y(b);
    }
}
D cross(const P& a, const P& b) {
    return y(conj(a)*b);
}
D dot(const P& a, const P& b) {
    return x(conj(a)*b);
}

struct L : public vector<P> {
    L(const P &a, const P &b) {
        push_back(a); push_back(b);
    }
};

typedef vector<P> G;
typedef vector<P> polygon;

struct C {
    P p; D r;
    C(const P &p, D r) : p(p), r(r) { }
};
//点の進行方向
int ccw(P a, P b, P c) {
    b -= a; c -= a;
    if (cross(b, c) > 0)   return +1;       // counter clockwise
    if (cross(b, c) < 0)   return -1;       // clockwise
    if (dot(b, c) < 0)     return +2;       // c--a--b on line
    if (norm(b) < norm(c)) return -2;       // a--b--c on line
    return 0;
}
//------------------------------------------------------------------------------------------
//---------交差判定・距離等-------------------------------------------------------------------
bool intersectLL(const L &l, const L &m) {
    return abs(cross(l[1]-l[0], m[1]-m[0])) > EPS || // non-parallel
            abs(cross(l[1]-l[0], m[0]-l[0])) < EPS;   // same line
}
bool intersectLS(const L &l, const L &s) {
    return cross(l[1]-l[0], s[0]-l[0])*       // s[0] is left of l
            cross(l[1]-l[0], s[1]-l[0]) < EPS; // s[1] is right of l
}
bool intersectLP(const L &l, const P &p) {
    return abs(cross(l[1]-p, l[0]-p)) < EPS;
}
bool intersectSS(const L &s, const L &t) {
  return ccw(s[0],s[1],t[0])*ccw(s[0],s[1],t[1]) <= 0 &&
         ccw(t[0],t[1],s[0])*ccw(t[0],t[1],s[1]) <= 0;
}
bool intersectSP(const L &s, const P &p) {
    return abs(s[0]-p)+abs(s[1]-p)-abs(s[1]-s[0]) < EPS; // triangle inequality
}
P projection(const L &l, const P &p) {
    D t = dot(p-l[0], l[0]-l[1]) / norm(l[0]-l[1]);
    return l[0] + t*(l[0]-l[1]);
}
P reflection(const L &l, const P &p) {
    return p + 2.0 * (projection(l, p) - p);
}
D distanceLP(const L &l, const P &p) {
    return abs(p - projection(l, p));
}
D distanceLL(const L &l, const L &m) {
    return intersectLL(l, m) ? 0 : distanceLP(l, m[0]);
}
D distanceLS(const L &l, const L &s) {
    if (intersectLS(l, s)) return 0;
    return min(distanceLP(l, s[0]), distanceLP(l, s[1]));
}
D distanceSP(const L &s, const P &p) {
    const P r = projection(s, p);
    if (intersectSP(s, r)) return abs(r - p);
    return min(abs(s[0] - p), abs(s[1] - p));
}
D distanceSS(const L &s, const L &t) {
    if (intersectSS(s, t)) return 0;
    return min(min(distanceSP(s, t[0]), distanceSP(s, t[1])),
            min(distanceSP(t, s[0]), distanceSP(t, s[1])));
}
P crosspoint(const L &l, const L &m) {
    D A = cross(l[1] - l[0], m[1] - m[0]);
    D B = cross(l[1] - l[0], l[1] - m[0]);
    if (abs(A) < EPS && abs(B) < EPS) return m[0]; // same line
    if (abs(A) < EPS) assert(false); // !!!PRECONDITION NOT SATISFIED!!!
    return m[0] + B / A * (m[1] - m[0]);
}

//点が円の中にあるか判定
bool contains(const P& p, const C& c) {
    return abs(p-c.p) < c.r+EPS;
}

int main(){
    int n;
    cin >> n;
    vector<P> ps(n);
    rep(i, n) {
        D a, b;
        cin >> a >> b;
        ps[i] = P(a, b);
    }
    D l = EPS, r = 3000;
    auto check2 = [&](C c) {
        rep(i, n) {
            if(!contains(ps[i], c)) return false;
        }
        return true;
    };
    auto calc = [&](P a, P b, D r) {
        vector<P> ret(2);
        if(a.X > b.X) swap(a, b);
        dump(a); dumpL(b);
        P d = b-a;
        dumpL(d);
        D d2 = abs(d)/2;
        D h = sqrt(r*r - d2*d2);
        ret[0] = P(d2, h);
        ret[1] = P(d2, -h);
        dumpV(ret);
        rep(i, 2) ret[i] *= d/abs(d);
        rep(i, 2) ret[i] += a;

        return ret;
    };
    auto check = [&](D r) {
        // dumpL(r);
        rep(i, n) rep(j, i) {
            auto a = calc(ps[i], ps[j], r);
            if(check2(C(a[0], r)) || check2(C(a[1], r))) return true;
        }
        return false;
    };
    rep(_, 256) {
        D m = (l + r) / 2;
        if(check(m)) r = m;
        else l =m;
    }
    cout << fixed << setprecision(15) << r << endl;
    // auto a = calc(ps[0], ps[1], 0.5);
    // dump(a[0]); dumpL(a[1]);
    return 0;
}

Measured memory_bytes: 256