#include <bits/stdc++.h>
using namespace std;
using lint = long long int;
using pint = pair<int, int>;
using plint = pair<lint, lint>;
struct fast_ios { fast_ios(){ cin.tie(0); ios::sync_with_stdio(false); cout << fixed << setprecision(20); }; } fast_ios_;
#define ALL(x) (x).begin(), (x).end()
#define SZ(x) ((lint)(x).size())
#define POW2(n) (1LL << (n))
#define FOR(i, begin, end) for(int i=(begin),i##_end_=(end);i<i##_end_;i++)
#define IFOR(i, begin, end) for(int i=(end)-1,i##_begin_=(begin);i>=i##_begin_;i--)
#define REP(i, n) FOR(i,0,n)
#define IREP(i, n) IFOR(i,0,n)
template<typename T> void ndarray(vector<T> &vec, int len) { vec.resize(len); }
template<typename T, typename... Args> void ndarray(vector<T> &vec, int len, Args... args) { vec.resize(len); for (auto &v : vec) ndarray(v, args...); }
template<typename T> bool mmax(T &m, const T q) { if (m < q) {m = q; return true;} else return false; }
template<typename T> bool mmin(T &m, const T q) { if (m > q) {m = q; return true;} else return false; }
template<typename T1, typename T2> pair<T1, T2> operator+(const pair<T1, T2> &l, const pair<T1, T2> &r) { return make_pair(l.first + r.first, l.second + r.second); }
template<typename T1, typename T2> pair<T1, T2> operator-(const pair<T1, T2> &l, const pair<T1, T2> &r) { return make_pair(l.first - r.first, l.second - r.second); }
template<typename T> istream &operator>>(istream &is, vector<T> &vec){ for (auto &v : vec) is >> v; return is; }
///// This part below is only for debug, not used /////
template<typename T> ostream &operator<<(ostream &os, const vector<T> &vec){ os << "["; for (auto v : vec) os << v << ","; os << "]"; return os; }
template<typename T> ostream &operator<<(ostream &os, const deque<T> &vec){ os << "deq["; for (auto v : vec) os << v << ","; os << "]"; return os; }
template<typename T> ostream &operator<<(ostream &os, const set<T> &vec){ os << "{"; for (auto v : vec) os << v << ","; os << "}"; return os; }
template<typename T> ostream &operator<<(ostream &os, const unordered_set<T> &vec){ os << "{"; for (auto v : vec) os << v << ","; os << "}"; return os; }
template<typename T> ostream &operator<<(ostream &os, const multiset<T> &vec){ os << "{"; for (auto v : vec) os << v << ","; os << "}"; return os; }
template<typename T> ostream &operator<<(ostream &os, const unordered_multiset<T> &vec){ os << "{"; for (auto v : vec) os << v << ","; os << "}"; return os; }
template<typename T1, typename T2> ostream &operator<<(ostream &os, const pair<T1, T2> &pa){ os << "(" << pa.first << "," << pa.second << ")"; return os; }
template<typename TK, typename TV> ostream &operator<<(ostream &os, const map<TK, TV> &mp){ os << "{"; for (auto v : mp) os << v.first << "=>" << v.second << ","; os << "}"; return os; }
template<typename TK, typename TV> ostream &operator<<(ostream &os, const unordered_map<TK, TV> &mp){ os << "{"; for (auto v : mp) os << v.first << "=>" << v.second << ","; os << "}"; return os; }
#define dbg(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << ") " << __FILE__ << endl;
///// END /////

using T_P = double;
constexpr T_P EPS = 1E-12;

struct P
{
    T_P x, y;
    P(T_P x = 0, T_P y = 0) : x(x), y(y) {}
    P(pair<T_P, T_P> p) : x(p.first), y(p.second) {}
    static T_P add_w_error(T_P a, T_P b) { return (abs(a + b) < EPS * (abs(a) + abs(b))) ? 0 : a + b; }
    P operator+(const P &p) const { return P(add_w_error(x, p.x), add_w_error(y, p.y)); }
    P operator-(const P &p) const { return P(add_w_error(x, -p.x), add_w_error(y, -p.y)); }
    P operator*(const P &p) const { return P(add_w_error(x * p.x,  -y * p.y), add_w_error(x * p.y, y * p.x)); }
    P inv() const { return conj() * (1.0L / norm2()); }
    P operator/(const P &p) const { return (*this) * p.inv(); }
    P operator*(T_P d) { return P(x * d, y * d); }
    bool operator<(const P &r) const{ return x != r.x ? x < r.x : y < r.y; }
    bool operator==(const P &r) const{ return add_w_error(x, -r.x) == 0 and add_w_error(y, -r.y) == 0; }
    T_P dot(P p) const { return add_w_error(x * p.x, y * p.y); }
    T_P det(P p) const { return add_w_error(x * p.y, -y * p.x); }
    T_P norm() const { return sqrt(x * x + y * y); }
    static T_P norm(P p) { return p.norm(); }
    T_P norm2() const { return x * x + y * y; }
    // rotate point/vector by rad
    P rotate(T_P rad) { return P(add_w_error(x * cos(rad), -y * sin(rad)), add_w_error(x * sin(rad), y * cos(rad))); }
    P conj() const { return P(x, -y); }
    friend istream &operator>>(istream &is, P &p) { T_P x, y; is >> x >> y; p = P(x, y); return is; }
    friend ostream &operator<<(ostream &os, const P &p) { os << '(' << p.x << ',' << p.y << ')'; return os; }
};

int ccw(P a, P b, P c) // a->b->cの曲がり方
{
    P v1 = b - a;
    P v2 = c - a;
    if (v1.det(v2) > EPS) return 1; // 左折
    if (v1.det(v2) < -EPS) return -1; // 右折
    if (v1.dot(v2) < -EPS) return 2; // c-a-b
    if (v1.norm() < v2.norm()) return -2; // a-b-c
    return 0; // a-c-b
}


// // Convex hull （凸包）
// // return: IDs of vertices used for convex hull, counterclockwise
// // include_boundary: If true, interior angle pi is allowed
// vector<int> convex_hull(const vector<P> &ps, bool include_boundary=false)
// {
//     int n = ps.size();
//     if (n <= 1) return vector<int>(n, 0);
//     vector<pair<P, int>> points(n);
//     for (size_t i = 0; i < ps.size(); i++) points[i] = make_pair(ps[i], i);
//     sort(points.begin(), points.end());
//     int k = 0;
//     vector<pair<P, int> > qs(2 * n);
//     auto ccw_check = [&](int c) {
//         if (include_boundary) return c == -1;
//         else return c <= 0;
//     };
//     for (int i = 0; i < n; i++)
//     {
//         while (k > 1 and ccw_check(ccw(qs[k - 2].first, qs[k - 1].first, points[i].first))) k--;
//         qs[k++] = points[i]; 
//     }
//     for (int i = n - 2, t = k; i >= 0; i--) {
//         while (k > t and ccw_check(ccw(qs[k - 2].first, qs[k - 1].first, points[i].first))) k--;
//         qs[k++] = points[i];
//     }
//     vector<int> ret(k - 1);
//     for (int i = 0; i < k - 1; i++) ret[i] = qs[i].second;
//     return ret;
// }

// Circumcenter （三角形の外心）
P circumcenter(P z1, P z2, P z3) {
    P a = z2 - z1, b = z3 - z1;
    return z1 + a * b * (a - b).conj() / (b * a.conj() - a * b.conj());
}


int main()
{
    int N;
    cin >> N;
    vector<P> x(N);
    cin >> x;
    double ret = 2000;
    REP(i, N) REP(j, i) {
        P p = (x[i] + x[j]) * 0.5;
        double r = 0;
        REP(k, N) mmax(r, (p - x[k]).norm());
        mmin(ret, r);
    }
    REP(i, N) REP(j, i) REP(k, j) if (abs(ccw(x[i], x[j], x[k])) % 2) {
        P c = circumcenter(x[i], x[j], x[k]);
        double r = 0;
        REP(l, N) mmax(r, (c - x[l]).norm());
        mmin(ret, r);
    }
    cout << ret << endl;
}


Measured memory_bytes: 256