#include <bits/stdc++.h>
#define err(args...) {}
#ifdef DEBUG
#include "_debug.cpp"
#endif
using namespace std;
using ll = long long;
using ld = long double;
template <typename T> using lim = numeric_limits<T>;
template <typename T> istream& operator>>(istream& is, vector<T>& a) { for(T& x : a) { is >> x; } return is; }
template <typename X, typename Y> istream& operator>>(istream& is, pair<X, Y>& p) { return is >> p.first >> p.second; }
#ifndef __VEC2D_INCLUDED_
#define __VEC2D_INCLUDED_
template <typename T> struct vec2D {
    T x, y;
    bool operator==(const vec2D& v) const { return x == v.x and y == v.y; }
    bool operator!=(const vec2D& v) const { return not (*this == v); }
    bool operator<(const vec2D& v) const { return x < v.x or (x == v.x and y < v.y); }
    vec2D& operator+=(const vec2D& v) { x += v.x, y += v.y; return *this; }
    vec2D& operator-=(const vec2D& v) { x -= v.x, y -= v.y; return *this; }
    vec2D& operator*=(const T c) { x *= c, y *= c; return *this; }
    vec2D& operator/=(const T c) { x /= c, y /= c; return *this; }
    vec2D operator+(const vec2D& v) const { return vec2D(*this) += v; }
    vec2D operator-(const vec2D& v) const { return vec2D(*this) -= v; }
    vec2D operator*(const T c) const { return vec2D(*this) *= c; }
    vec2D operator/(const T c) const { return vec2D(*this) /= c; }
    vec2D operator-() const { return {-x, -y}; }
    T operator*(const vec2D& v) const { return x * v.y - y * v.x; } // cross product
    T operator|(const vec2D& v) const { return x * v.x + y * v.y; } // dot product
    T squared_norm() const { return *this | *this; }
    double norm() const { return sqrt(squared_norm()); }
    vec2D normalized() const { return *this / norm(); }
    double scalar_project(const vec2D& v) const { return (*this|v) / v.norm(); }
    vec2D vector_project(const vec2D& v) const { return (*this|v) / (v|v) * v; }
    vec2D perp() const { return {-y, x}; }
    vec2D rotate(T t) const { return {cos(t) * x - sin(t) * y, sin(t) * x + cos(t) * y}; }
    friend vec2D operator*(const T c, const vec2D& v) { return v * c; }
    friend ostream& operator<<(ostream& os, const vec2D<T>& v) { return os << "(" << v.x << ", " << v.y << ")"; }
    friend istream& operator>>(istream& is, vec2D<T>& v) { return is >> v.x >> v.y; }
};
#endif
template <typename T> struct line2D {
    vec2D<T> point, dir;
    line2D() {}
    line2D(const vec2D<T>& p1, const vec2D<T>& p2) : point(p1), dir(p2 - p1) {}
    T a() const { return -dir.y; }
    T b() const { return dir.x; }
    T c() const { return dir * point; }
    T turn(const vec2D<T>& p) const { return dir * (p - point); }
    bool contains(const vec2D<T>& p) const { return turn(p) == 0; }
    double distance(const vec2D<T>& p) const { return abs(turn(p)) / dir.norm(); }
    T squared_distance(const vec2D<T>& p) const { return turn(p) * turn(p) / dir.squared_norm(); }
    line2D perp(const vec2D<T>& p) const { return {p, p + dir.perp()}; }
    bool operator==(const line2D& l) const { return dir * l.dir == 0 and contains(l.point); };
    bool operator!=(const line2D& l) const { return not (*this == l); }
    bool intersects(const line2D& l) const { return dir * l.dir != 0 or *this == l; };
    vec2D<T> intersection(const line2D& l) const { return (c() * l.dir - l.c() * dir) / (dir * l.dir); }
};
void solve(long long N, std::vector<long long> x, std::vector<long long> y) {
    if(N == 2) {
        vec2D<double> p0 = {x[0], y[0]}, p1 = {x[1], y[1]};
        cout << fixed << setprecision(6) << (p1 - p0).norm() / 2 << endl;
    } else {
        auto check = [&](const vec2D<double>& center, double radius) {
            bool ans = true;
            for(int i = 0; i < N and ans; i++) {
                ans &= (vec2D<double>{x[i], y[i]} - center).norm() <= radius;
            }
            return ans;
        };
        double ans = 1e6;
        for(int i = 0; i < N; i++) {
            for(int j = i + 1; j < N; j++) {
                for(int k = j + 1; k < N; k++) {
                    vec2D<double> I = {x[i], y[i]}, J = {x[j], y[j]}, K = {x[k], y[k]};
                    line2D<double> IJ = {I, J}, JK = {J, K};
                    if(check((I + J) / 2, (J - I).norm() / 2)) {
                        ans = min(ans, (J - I).norm() / 2);
                    }
                    if(IJ != JK) {
                        auto center = IJ.perp((I + J) / 2).intersection(JK.perp((J + K) / 2));
                        if(check(center, (center - I).norm())) {
                            ans = min(ans, (center - I).norm());
                        }
                    }
                }
            }
        }
        cout << fixed << setprecision(6) << ans << endl;
    }
}
int main() {
    long long N;
    scanf("%lld",&N);
    std::vector<long long> x(N);
    std::vector<long long> y(N);
    for(int i = 0 ; i < N ; i++){
        scanf("%lld",&x[i]);
        scanf("%lld",&y[i]);
    }
    solve(N, std::move(x), std::move(y));
    return 0;
}


Measured memory_bytes: 256