// g++ -std=c++14

/*

Today might be the chance to grasp the chance to let your talent bloom.
May be tomorrow, the day after, or next year...
May be even when you are 30. I'm not sure if physique has anything to do with it
but if you think that it will never come, it probably never will.

- Tooru Oikawa.

*/

#include <bits/stdc++.h>

typedef long long ll;
typedef long double lld;
using namespace std;

#define endl "\n"
#define fi first
#define se second
#define pb(x) push_back(x)
#define mp(x, y) make_pair(x, y)
#define MEMS(a, b) memset(a, b, sizeof(a))
#define _                             \
    ios_base::sync_with_stdio(false); \
    cin.tie(NULL);                    \
    cout.tie(NULL);
#define __                            \
    freopen("input.txt", "r", stdin); \
    freopen("output.txt", "w", stdout);
#define all(c) c.begin(), c.end()
#define inf 1000000000000000001
#define pii pair<int, int>
#define tr(...)                                       \
    cout << __FUNCTION__ << ' ' << __LINE__ << " = "; \
    trace(#__VA_ARGS__, __VA_ARGS__)

template <typename S, typename T>
ostream &operator<<(ostream &out, pair<S, T> const &p)
{
    out << '(' << p.fi << ", " << p.se << ')';
    return out;
}

template <typename T>
ostream &operator<<(ostream &out, vector<T> const &v)
{
    ll l = v.size();
    for (ll i = 0; i < l - 1; i++)
        out << v[i] << ' ';
    if (l > 0)
        out << v[l - 1];
    return out;
}

template <typename T>
ostream &operator<<(ostream &out, set<T> const &v)
{
    for (auto i = v.begin(); i != v.end(); i++)
        out << (*i) << ' ';
    return out;
}
template <typename T, typename V>
ostream &operator<<(ostream &out, map<T, V> const &v)
{
    for (auto i = v.begin(); i != v.end(); i++)
        out << "\n"
            << (i->first) << ":" << (i->second);
    return out;
}

template <typename T>
void trace(const char *name, T &&arg1) { cout << name << " : " << arg1 << endl; }

template <typename T, typename... Args>
void trace(const char *names, T &&arg1, Args &&... args)
{
    const char *comma = strchr(names + 1, ',');
    cout.write(names, comma - names) << " : " << arg1 << " | ";
    trace(comma + 1, args...);
}

#define int ll

#define MAX_SIZE 1000
const double PI = 2.0 * acos(0.0);
const double EPS = 1e-9; //too
struct PT
{
    double x, y;
    double length() { return sqrt(x * x + y * y); }
    int normalize()
    {
        double l = length();
        if (fabs(l) < EPS)
            return -1;
        x /= l;
        y /= l;
        return 0;
    }
    PT operator-(PT a)
    {
        PT r;
        r.x = x - a.x;
        r.y = y - a.y;
        return r;
    }
    PT operator+(PT a)
    {
        PT r;
        r.x = x + a.x;
        r.y = y + a.y;
        return r;
    }
    PT operator*(double sc)
    {
        PT r;
        r.x = x * sc;
        r.y = y * sc;
        return r;
    }
};
bool operator<(const PT &a, const PT &b)
{
    if (fabs(a.x - b.x) < EPS)
        return a.y < b.y;
    return a.x < b.x;
}
double dist(PT &a, PT &b)
// the distance between two points
{
    return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
double dot(PT &a, PT &b)
// the inner product of two vectors
{
    return (a.x * b.x + a.y * b.y);
}


double trap(PT a, PT b)
{
    return (0.5 * (b.x - a.x) * (b.y + a.y));
}
double area(vector<PT> &vin)
    // Area of a simple polygon, not
    // neccessary convex
{
    int n = vin.size();
    double ret = 0.0;
    for (int i = 0; i < n; i++)
        ret += trap(vin[i], vin[(i + 1) % n]);
    return fabs(ret);
}
double peri(vector<PT> &vin)
    // Perimeter of a simple polygon, not
    // neccessary convex
{
    int n = vin.size();
    double ret = 0.0;
    for (int i = 0; i < n; i++)
        ret += dist(vin[i], vin[(i + 1) % n]);
    return ret;
}
double triarea(PT a, PT b, PT c)
{
    return fabs(trap(a, b) + trap(b, c) +
                trap(c, a));
}
double height(PT a, PT b, PT c)
// height from a to the line bc
{
    double s3 = dist(c, b);
    double ar = triarea(a, b, c);
    return (2.0 * ar / s3);
}


int intersection(PT p1, PT p2, PT p3, PT p4, PT &r)
    // two lines given by p1->p2, p3->p4 r is
    // the intersection point
    // return -1 if two lines are parallel
{
    double d = (p4.y - p3.y) * (p2.x - p1.x) - (p4.x - p3.x) * (p2.y - p1.y);
    if (fabs(d) < EPS)
        return -1;
    // might need to do something
    //special !!!
    double ua, ub;
    ua = (p4.x - p3.x) * (p1.y - p3.y) - (p4.y - p3.y) * (p1.x - p3.x);
    ua /= d;
    // ub = (p2.x - p1.x)*(p1.y-p3.y) -
    (p2.y - p1.y) * (p1.x - p3.x);
    //ub /= d;
    r = p1 + (p2 - p1) * ua;
    return 0;
}
void closestpt(PT p1, PT p2, PT p3, PT &r)
    // the closest point on the line p1->p2 to
    // p3
{
    if (fabs(triarea(p1, p2, p3)) < EPS)

    {
        r = p3;
        return;
    }
    PT v = p2 - p1;
    v.normalize();
    double pr; // inner product
    pr = (p3.y - p1.y) * v.y + (p3.x - p1.x) * v.x;
    r = p1 + v * pr;
}
int hcenter(PT p1, PT p2, PT p3, PT &r)
{
    // point generated by altitudes
    if (triarea(p1, p2, p3) < EPS)
        return -1;
    PT a1, a2;
    closestpt(p2, p3, p1, a1);
    closestpt(p1, p3, p2, a2);
    intersection(p1, a1, p2, a2, r);
    return 0;
}
int center(PT p1, PT p2, PT p3, PT &r)
{
    // point generated by circumscribed
    // circle 
    if (triarea(p1, p2, p3) < EPS) return -1;
    PT a1, a2, b1, b2;
    a1 = (p2 + p3) * 0.5;
    a2 = (p1 + p3) * 0.5;
    b1.x = a1.x - (p3.y - p2.y);
    b1.y = a1.y + (p3.x - p2.x);
    b2.x = a2.x - (p3.y - p1.y);
    b2.y = a2.y + (p3.x - p1.x);
    intersection(a1, b1, a2, b2, r);
    return 0;
}

const int N = 60;

PT arr[N];
int n;
int32_t main()
{
    _
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> arr[i].x >> arr[i].y;
    }
    lld ans = inf;
    for (int i = 1; i <= n; i++) {
        for (int j = i + 1; j <= n; j++) {
            for (int k = j + 1; k <= n; k++) {
                PT r;
                int tmp = center(arr[i], arr[j], arr[k], r);
                if (tmp == -1) {
                    continue;
                }
                lld rad = dist(r, arr[i]);
                int done = 0;
                for (int p = 1; p <= n; p++) {
                    if (dist(r, arr[p]) > rad + EPS) {
                        done = 1;
                        break;
                    }
                }
                if (!done) {
                    ans = min(ans, rad);
                }
            }
        }
    }
    for (int i = 1; i <= n; i++) {
        for (int j = i + 1; j <= n; j++) {
            PT r;
            r.x = (arr[i].x + arr[j].x) / 2.0;
            r.y = (arr[i].y + arr[j].y) / 2.0;
            lld rad = dist(r, arr[i]);
            int done = 0;
            for (int p = 1; p <= n; p++) {
                if (dist(r, arr[p]) > rad + EPS) {
                    done = 1;
                    break;
                }
            }
            if (!done) {
                ans = min(ans, rad);
            }
        }
    }
    cout << fixed << setprecision(12) << ans << endl;
}

Measured memory_bytes: 256