#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for(int i = 0; i < n; i++)
#define rep2(i, x, n) for(int i = x; i <= n; i++)
#define rep3(i, x, n) for(int i = x; i >= n; i--)
#define elif else if
#define sp(x) fixed << setprecision(x)
#define pb(x) push_back(x)
#define eb(x) emplace_back(x)
#define all(x) x.begin(), x.end()
#define sz(x) (int)x.size()
using ll = long long;
using ld = long double;
using pii = pair<int, int>;
using pil = pair<int, ll>;
using pli = pair<ll, int>;
using pll = pair<ll, ll>;
const ll MOD = 1e9+7;
//const ll MOD = 998244353;
const int inf = 1e9+3;
const ll INF = 1e18+3;
const ld EPS = 1e-10;
template<typename T> bool chmax(T &x, const T &y) {return (x < y)? (x = y, true) : false;};
template<typename T> bool chmin(T &x, const T &y) {return (x > y)? (x = y, true) : false;};

//点(x, y)
struct P {
    ld x, y;
    P() {}
    P(ld x, ld y) : x(x), y(y) {}
    P operator + (P p) {return P(x+p.x, y+p.y);}
    P operator - (P p) {return P(x-p.x, y-p.y);}
    P operator * (ld d) {return P(x*d, y*d);}
    P operator / (ld d) {return P(x/d, y/d);}
    ld norm() {return sqrt(x*x+y*y);}
    ld norm2() {return x*x+y*y;}
};
//直線ax+by+c=0
struct L {ld a, b, c;};
//(x, y)を中心とする半径rの円
struct C {ld x, y, r;};

//点a,bの距離
ld dist(P a, P b) {return (b-a).norm();}

//点a,bの距離の2乗
ld dist2(P a, P b){return (b-a).norm2();}

//内積a・b
ld dot(P a, P b) {return a.x*b.x+a.y*b.y;}

//a,bを横に並べた行列の行列式
ld det(P a, P b) {return a.x*b.y-b.x*a.y;}

//点a,bの中点
P mid(P a, P b) {return (a+b)/2;}

//点a,bをs:tに内分する点
P ind(P a, P b, ld s, ld t) {return (a*t+b*s)/(s+t);}

//点a,bをs:tに外分する点
P exd(P a, P b, ld s, ld t) {return ind(a, b, s, -t);}

//直線l1と直線l2の交点
vector<P> l_l(L l1, L l2){
    vector<P> res;
    if(abs(l1.a*l2.b - l2.a*l1.b) < EPS) return res;
    ld x = (l2.c*l1.b-l1.c*l2.b)/(l1.a*l2.b-l2.a*l1.b);
    ld y = (l2.c*l1.a-l1.c*l2.a)/(l1.b*l2.a-l2.b*l1.a);
    res.pb(P(x, y));
    return res;
}

//直線lと円cの交点
vector<P> l_c(L l, C c){
    vector<P> res;
    if(l.a == 0 && l.b == 0) return res;
    //直線と円の中心の距離
    ld d = abs(l.a*c.x+l.b*c.y+l.c)/sqrt(l.a*l.a+l.b*l.b);
    if(d-c.r > EPS) return res;
    //hx,hy:=円の中心から直線に下ろした垂線の足の座標
    ld hx = -(l.a*l.c+l.b*(l.a*c.y-l.b*c.x))/(l.a*l.a+l.b*l.b);
    ld hy = -(l.b*l.c+l.a*(l.a*c.y-l.b*c.x))/(l.a*l.a+l.b*l.b);
    if(abs(d-c.r) < EPS){
        res.pb(P(hx, hy));
        return res;
    }
    //d2:=垂線の足hと交点の距離
    ld d2 = sqrt(c.r*c.r-d*d);
    //ex,ey:=直線と同じ向きの単位ベクトル
    ld ex = -l.b/sqrt(l.a*l.a+l.b*l.b), ey = l.a/sqrt(l.a*l.a+l.b*l.b);
    res.pb(P(hx+d2*ex, hy+d2*ey)), res.pb(P(hx-d2*ex, hy-d2*ey));
    return res;
}

//円c1と円c2の交点
vector<P> c_c(C c1, C c2){
    //直線ax+by+c=0:=２つの円の交点を通る直線
    ld a = 2*(c1.x-c2.x), b = 2*(c1.y-c2.y);
    ld c = -(c1.x*c1.x+c1.y*c1.y-c1.r*c1.r)+(c2.x*c2.x+c2.y*c2.y-c2.r*c2.r);
    L l = {a, b, c};
    return l_c(l, c1);
}

//点a,bを通る直線
L make_line(P a, P b){
    ld p = a.x, q = a.y, r = b.x, s = b.y;
    ld A = s-q, B = p-r, C = -p*s+q*r;
    L l = {A, B, C};
    return l;
}

//点a,bの垂直二等分線
L make_v_line(P a, P b){
    ld p = a.x, q = a.y, r = b.x, s = b.y;
    ld A = r-p, B = s-q, C = (p*p-r*r+q*q-s*s)/2;
    L l = {A, B, C};
    return l;
}

//点aから直線lに降ろした垂線の足
P v_foot(P a, L l){
    ld A = l.b, B = -l.a, C = l.a*a.y - l.b*a.x;
    L subl = {A, B, C};
    vector<P> p = l_l(l, subl);
    return p[0];
}

//点aがp1とp2を結ぶ線分上にあるかどうか
bool on_line(P a, P p1, P p2){
    P sub1 = p1-a, sub2 = p2-a;
    return (abs(det(sub1, sub2)) < EPS && dot(sub1, sub2) < EPS);
}

//x座標、y座標の小さい順にソート
bool cmp_x(const P &p, const P &q){
    if(p.x != q.x) return p.x < q.x;
    return p.y < q.y;
}

//点の集合psの凸包を求める
vector<P> convex_hull(vector<P> ps){
    sort(all(ps), cmp_x);
    int n = ps.size(), k = 0;
    vector<P> qs(2*n);
    //上側凸包を作成
    rep(i, n){
        while(k > 1 && det(qs[k-2]-qs[k-1], ps[i]-qs[k-1]) < EPS) k--;
        qs[k++] = ps[i];
    }
    int t = k;
    //下側凸包を作成
    rep3(i, n-2, 0){
        while(k > t && det(qs[k-2]-qs[k-1], ps[i]-qs[k-1]) < EPS) k--;
        qs[k++] = ps[i];
    }
    qs.resize(k-1);
    return qs;
}

int main(){
    int N;
    cin >> N;
    vector<P> ps;
    rep(i, N){
        ld x, y; cin >> x >> y;
        ps.pb(P(x, y));
    }
    vector<P> ch = convex_hull(ps);
    int n = sz(ch);
    ld ans = 0;
    rep(i, n){
        rep(j, n){
            if(i == j) continue;
            chmax(ans, dist(ch[i], ch[j])/2);
        }
    }
    rep(i, n){
        rep(j, n){
            rep(k, n){
                if(dot(ch[i]-ch[j], ch[i]-ch[k]) <= 0) continue;
                if(dot(ch[j]-ch[i], ch[j]-ch[k]) <= 0) continue;
                if(dot(ch[k]-ch[i], ch[k]-ch[j]) <= 0) continue;
                L l1 = make_v_line(ch[i], ch[j]);
                L l2 = make_v_line(ch[i], ch[k]);
                vector<P> p = l_l(l1, l2);
                for(auto &e: p){
                    chmax(ans, dist(e, ch[i]));
                }
            }
        }
    }
    cout << sp(10) << ans << endl;
}

Measured memory_bytes: 256