#include<iostream>
#include<iomanip>
#include<vector>
#include<string>
#include<cmath>
#define rep(i, start, end) for (int i = (int)start; i < (int)end; ++i)
#define rrep(i, start, end) for (int i = (int)start - 1; i >= end; --i)
#define iter(i, c) for (auto i = (c).begin(); i != (c).end(); ++i)
#define riter(i, c) for (auto i = (c).rbegin(); i != (c).rend(); ++i)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
using namespace std;
using ll = long long;
template<typename T> inline bool chmax(T& a, T b) {if (a < b) {a = b; return true;} return 0;}
template<typename T> inline bool chmin(T& a, T b) {if (a > b) {a = b; return true;} return 0;}

const double EPS = 1e-10;
const double PI = acos(-1.0);

double deg2rad(double degree) {
    return degree * PI / 180.0;
}

double rad2deg(double radian) {
    return radian * 180.0 / PI;
}

template<typename T>
class Polygon2D {
    private:
        T x_, y_;
        int idx_;
    public:
        Polygon2D() {}
        Polygon2D(T x, T y):x_(x), y_(y) {}
        Polygon2D(T x, T y, int idx):x_(x), y_(y), idx_(idx) {}  // for convex-full
        static T dot(const Polygon2D& p1, const Polygon2D& p2) {return p1.x_ * p2.x_ + p1.y_ * p2.y_;}
        static T cross(const Polygon2D& p1, const Polygon2D& p2) {return p1.x_ * p2.y_ - p1.y_ * p2.x_;}
        T norm() const {return dot(*this, *this);}
        T abs() const {return sqrt(this->norm());}
        Polygon2D rot(T radian) const {return Polygon2D(cos(radian) * x_ - sin(radian) * y_, sin(radian) * x_ + cos(radian) * y_, idx_);}
        Polygon2D rot90() const {return Polygon2D(-y_, x_, idx_);}
        static int ccw(const Polygon2D& p1, const Polygon2D& p2, const Polygon2D& p3) {
            if (cross(p2 - p1, p3 - p1) > EPS) return 1;    // p3 is left side
            if (cross(p2 - p1, p3 - p1) < -EPS) return -1;  // p3 is right side
            return 0;                                       // p3 is on the line
        }
        Polygon2D operator+(const Polygon2D& p) const {Polygon2D<T> res = *this; res.x_ += p.x_; res.y_ += p.y_; return res;}
        Polygon2D operator-(const Polygon2D& p) const {Polygon2D<T> res = *this; res.x_ -= p.x_; res.y_ -= p.y_; return res;}
        Polygon2D operator*(const T val) const {Polygon2D<T> res = *this; res.x_ *= val; res.y_ *= val; return res;}
        friend const Polygon2D operator*(const T& val, const Polygon2D& p) {Polygon2D res = p; res.x_ *= val; res.y_ *= val; return res;}
        const Polygon2D operator/(const T val) const {Polygon2D res = *this; res.x_ /= val; res.y_ /= val; return res;}
        T getX() const {return x_;}
        T getY() const {return y_;}
        int getIdx() const {return idx_;}
        friend ostream& operator<<(ostream& stream, const Polygon2D& p) {stream << '(' << p.x_ << ',' << p.y_ << ')'; return stream;}
};

template<typename T>
class Line {
    private:
        Polygon2D<T> a_, b_;
    public:
        Line() {}
        Line(Polygon2D<T> a, Polygon2D<T> b):a_(a), b_(b) {}
        Polygon2D<T> getFirst() const {return a_;}
        Polygon2D<T> getSecond() const {return b_;}
};

template<typename T>
vector<Polygon2D<T>> crosspoints(const Line<T>& l1, const Line<T>& l2) {
    vector<Polygon2D<T>> res;
    T d = Polygon2D<T>::cross(l2.getSecond() - l2.getFirst(), l1.getSecond() - l1.getFirst());
    if (abs(d) < EPS) {
        return vector<Polygon2D<T>>();
    }
    res.push_back(l1.getFirst() + (l1.getSecond() - l1.getFirst()) * Polygon2D<T>::cross(l2.getSecond() - l2.getFirst(), l2.getSecond() - l1.getFirst()) / d);
    return res;
}

template<typename T>
Polygon2D<T> getCircumCenter(const Polygon2D<T>& p1, const Polygon2D<T>& p2, const Polygon2D<T>& p3) {
    Line<T> p12((p1 + p2) / 2, (p1 + p2) / 2 + (p1 - p2).rot90());
    Line<T> p23((p2 + p3) / 2, (p2 + p3) / 2 + (p2 - p3).rot90());
    return crosspoints(p12, p23)[0];
}

const double INF = 1LL << 60;

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int N;
    cin >> N;
    vector<Polygon2D<double>> points;
    double x, y;
    rep(i, 0, N) {
        cin >> x >> y;
        points.emplace_back(x, y);
    }
    vector<Polygon2D<double>> centers;
    rep(i, 0, N) rep(j, i + 1, N) {
        centers.push_back((points[i] + points[j]) / 2);
        rep(k, j + 1, N) {
            if (Polygon2D<double>::ccw(points[i], points[j], points[k]) == 0) {
                continue;
            }
            centers.push_back(getCircumCenter(points[i], points[j], points[k]));
        }
    }
    double ans = INF;
    for (auto now_center : centers) {
        double max_r = 0.0;
        for (auto now_point : points) {
            chmax(max_r, (now_center - now_point).abs());
        }
        chmin(ans, max_r);
    }
    cout << fixed << setprecision(10) << ans << endl;
    return 0;
}

Measured memory_bytes: 1152