#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); }
};
template <typename T = double> T minimum_bounding_radius(const vector<vec2D<T>>& p) {
    auto check = [&](const vec2D<T>& center, T radius) {
        return all_of(p.begin(), p.end(), [&](const vec2D<T>& point) {
            return (point - center).norm() <= radius;
        });
    };
    T ans = lim<T>::infinity();
    for(int i = 0; i < p.size(); i++) {
        for(int j = i + 1; j < p.size(); j++) {
            if(check((p[i] + p[j]) / 2, (p[j] - p[i]).norm() / 2)) {
                ans = min(ans, (p[j] - p[i]).norm() / 2);
            }
            for(int k = j + 1; k < p.size(); k++) {
                line2D<T> IJ = {p[i], p[j]}, JK = {p[j], p[k]};
                if(IJ != JK) {
                    auto center = IJ.perp((p[i] + p[j]) / 2).intersection(JK.perp((p[j] + p[k]) / 2));
                    if(check(center, (center - p[i]).norm())) {
                        ans = min(ans, (center - p[i]).norm());
                    }
                }
            }
        }
    }
    return ans;
}
void solve(long long N, std::vector<long long> x, std::vector<long long> y) {
    vector<vec2D<double>> points(N);
    for(int i = 0; i < N; i++) {
        points[i] = {x[i], y[i]};
    }
    cout << fixed << setprecision(6) << minimum_bounding_radius(points) << 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