void main()
{
    long n = rdElem;
    Point[] p = n.rdCol!Point;

    double result = 1.0e5;
    foreach (i; 0 .. n-1)
    {
        foreach (j; i+1 .. n)
        {
            Point o = (p[i] + p[j]) / 2.0;
            double len = 0.0;
            foreach (k; 0 .. n)
            {
                Point q = p[k] - o;
                len = max(len, q.norm);
            }
            result = min(result, len);

            if (n >= 3)
            {
                foreach (l; 0 .. n)
                {
                    if (l == i || l == j) continue;
                    o = calcCenter(p[i], p[j], p[l]);
                    len = 0.0;
                    foreach (k; 0 .. n)
                    {
                        Point q = p[k] - o;
                        len = max(len, q.norm);
                    }
                    result = min(result, len);
                }
            }
        }
    }

    writefln("%.15f", result);
}

Point calcCenter(Point p1, Point p2, Point p3)
{
    Point O;
    Point P = 2.0 * (p1 - p2), Q = 2.0 * (p1 - p3);
    double a = P.x, b = P.y, c = Q.x, d = Q.y;
    double e = p1.quadrance - p2.quadrance;
    double f = p1.quadrance - p3.quadrance;
    double det = a * d - b * c;
    if (det.abs <= 1e-6) return Point(1e5, 1e5);
    O.x = (d * e - b * f) / det;
    O.y = (- c * e + a * f) / det;
    return O;
}

alias Point = Vector2D!double;

struct Vector2D(T)
{
    import std.traits;

    T x, y;

    this(T x, T y)
    {
        this.x = x, this.y = y;
    }

    Vector2D!T opBinary(string op, T)(Vector2D!T that)
    if ((op == "+") & isNumeric!T)
    {
        return Vector2D!T(this.x + that.x, this.y + that.y);
    }

    Vector2D!T opBinary(string op, T)(Vector2D!T that)
    if ((op == "-") & isNumeric!T)
    {
        return Vector2D!T(this.x - that.x, this.y - that.y);
    }

    Vector2D!T opBinary(string op, T)(T that)
    if ((op == "*") & isNumeric!T)
    {
        return Vector2D!T(this.x * that, this.y * that);
    }

    Vector2D!T opBinaryRight(string op, T)(T that)
    if ((op == "*") & isNumeric!T)
    {
        return opBinary!(op)(that);
    }

    Vector2D!T opBinary(string op, T)(T that)
    if ((op == "/") & isNumeric!T)
    {
        return Vector2D!T(this.x / that, this.y / that);
    }

    T dot(Vector2D!T that)
    {
        return this.x * that.x + this.y * that.y;
    }

    T cross(Vector2D!T that)
    {
        return this.x * that.y - this.y * that.x;
    }

    T quadrance()
    {
        return dot(this);
    }

    double norm()
    {
        return dot(this).to!double.sqrt;
    }
}

enum long mod = 10^^9 + 7;
enum long inf = 1L << 60;

T rdElem(T = long)()
if (!is(T == struct))
{
    return readln.chomp.to!T;
}

alias rdStr = rdElem!string;
alias rdDchar = rdElem!(dchar[]);

T rdElem(T)()
if (is(T == struct))
{
    T result;
    string[] input = rdRow!string;
    assert(T.tupleof.length == input.length);
    foreach (i, ref x; result.tupleof)
    {
        x = input[i].to!(typeof(x));
    }
    return result;
}

T[] rdRow(T = long)()
{
    return readln.split.to!(T[]);
}

T[] rdCol(T = long)(long col)
{
    return iota(col).map!(x => rdElem!T).array;
}

T[][] rdMat(T = long)(long col)
{
    return iota(col).map!(x => rdRow!T).array;
}

void wrMat(T = long)(T[][] mat)
{
    foreach (row; mat)
    {
        foreach (j, compo; row)
        {
            compo.write;
            if (j == row.length - 1) writeln;
            else " ".write;
        }
    }
}

import std.stdio;
import std.string;
import std.array;
import std.conv;
import std.algorithm;
import std.range;
import std.math;
import std.numeric;
import std.traits;
import std.container;
import std.functional;
import std.typecons;
import std.ascii;
import std.uni;

Measured memory_bytes: 256