#include <bits/stdc++.h>
 
#define _overload(_1,_2,_3,name,...) name
#define _rep(i,n) _range(i,0,n)
#define _range(i,a,b) for(int i=(int)(a);i<(int)(b);++i)
#define rep(...) _overload(__VA_ARGS__,_range,_rep,)(__VA_ARGS__)
 
#define _rrep(i,n) _rrange(i,n,0)
#define _rrange(i,a,b) for(int i=(int)(a)-1;i>=(int)(b);--i)
#define rrep(...) _overload(__VA_ARGS__,_rrange,_rrep,)(__VA_ARGS__)
 
#define _all(arg) begin(arg),end(arg)
#define uniq(arg) sort(_all(arg)),(arg).erase(unique(_all(arg)),end(arg))
#define bit(n) (1LL<<(n))
 
// #define DEBUG
 
#ifdef DEBUG
    #define dump(...) fprintf(stderr, __VA_ARGS__)
#else
    #define dump(...)
#endif
 
template<class T>bool chmin(T &a, const T &b) {return (b<a)?(a=b,1):0;}
template<class T>bool chmax(T &a, const T &b) { return (a<b)?(a=b,1):0;}
 
using namespace std;
template<class T>void reg(vector<T> &ary,const T &elem){ary.emplace_back(elem);}
using R=long double; // __float128
const R EPS = 1E-11; // [-1000:1000]->EPS=1e-8 [-10000:10000]->EPS=1e-7
const R INF = 1E40;
constexpr R PI = acos(R(-1));
inline int sgn(const R& r){ return (r > EPS) - (r < -EPS);}
inline int sgn(const R& a, const R &b){ return sgn(a-b); }
inline R sq(R x){return sqrt(max<R>(x,0.0));}
 
using P=complex<R>;
using VP=vector<P>;
using L=struct L{P s,t;};
using VL=vector<L>;
using C=struct C{P c;R r;};
using VC=vector<C>;
 
constexpr P O = P(0,0);
istream& operator >> (istream& is,P& p){ R x,y;is >> x >> y; p=P(x,y); return is;}
ostream& operator << (ostream& os,P& p){ os << real(p) << " " << imag(p); return os;}
 
namespace std{
    bool operator <  (const P& a,const P& b){ return sgn(real(a-b))?real(a-b)<0:sgn(imag(a-b))<0;}
    bool operator == (const P& a,const P& b){ return sgn(real(a-b))==0 && sgn(imag(a-b))==0;}
}
 
inline bool cmp_x(const P& p,const P& q){return sgn(real(p-q))?real(p)<real(q):sgn(imag(p-q));}
inline bool cmp_y(const P& a, const P& b){return sgn(imag(a-b)) ? imag(a-b)<0 : sgn(real(a-b))<0;}
inline bool cmp_a(const P& a, const P& b){return sgn(arg(a)-arg(b)) ? arg(a)-arg(b)<0 : sgn(norm(a)-norm(b))<0;}
bool operator <  (const L& a,const L& b){ return a.s==b.s?a.t<b.t:a.s<b.s;}
bool operator == (const L& a,const L& b){ return a.s==b.s&&a.t==b.t;}
 
//内積 dot 外積 det
inline R dot(P o,P a,P b){a-=o,b-=o; return real(conj(a)*b);}
inline R det(P o,P a,P b){a-=o,b-=o; return imag(conj(a)*b);}
inline P vec(L l){return l.t-l.s;}
 
// 射影 verify AOJ CGL_1_A
P proj(P o,P a,P b){ a-=o,b-=o; return a*real(b/a);}
P proj(L l,P p){l.t-=l.s,p-=l.s;return l.s+l.t*real(p/l.t);}
// 反射 verify AOJ CGL_1_B
P refl(L l,P p){ return R(2.0)*proj(l,p)-p;}
// CCW verify AOJ CGL_1_C
enum CCW{ LEFT = 1,RIGHT = 2,BACK = 4,FRONT = 8,ON = 16};
inline int ccw(P o,P a, P b) {//点aと点bが与えられた問いに
    if (sgn(det(o,a,b)) > 0) return LEFT;    // counter clockwise
    if (sgn(det(o,a,b)) < 0) return RIGHT;   // clockwise
    if (sgn(dot(o,a,b)) < 0) return BACK;    // b--base--a on line
    if (sgn(norm(a-o)-norm(b-o)) < 0) return FRONT;   // base--a--b on line
    return ON;// base--b--a on line  aとbの線分判定はこれ
}
 
// 垂直 平行 verify AOJ CGL_2_A
bool vertical(L a, L b) {return sgn(dot(O,vec(a),vec(b)))==0;}
bool parallel(L a, L b) {return sgn(det(O,vec(a),vec(b)))==0;}
 
// 同じ直線判定 
bool eql(L a,L b){ return (parallel(a,b) && sgn(det(a.s,a.t,b.s))==0);}
 
// 交差判定　verify AOJ CGL_2_B 端点を含まない場合は1,含む場合は0
bool ill(L a,L b){ return parallel(a,b)==false;}
bool ils(L l,L s,int end=0){ return sgn(det(l.s,l.t,s.s)*det(l.s,l.t,s.t))<=-end;}
bool iss(L a,L b,int end=0){
    int s1=ccw(a.s,a.t,b.s)|ccw(a.s,a.t,b.t);
    int s2=ccw(b.s,b.t,a.s)|ccw(b.s,b.t,a.t);
    if(end) return (s1&s2)==(LEFT|RIGHT);
    return (s1|s2)&ON || (s1&s2)==(LEFT|RIGHT);
}
 
// 交点 verify AOJ CGL_2_C
P cross(L a,L b){
    R s1=det(a.s,b.s,b.t);
    R s2=s1+det(a.t,b.t,b.s);
    return a.s+s1/s2*(a.t-a.s);
}
     
// 距離 verify AOJ CGL_2_D
R dlp(L l,P p){return abs(det(l.s,l.t,p))/abs(vec(l));}
R dsp(L s,P p){
    if(sgn(dot(s.s,s.t,p))<=0) return abs(p-s.s);
    if(sgn(dot(s.t,s.s,p))<=0) return abs(p-s.t);
    return abs(det(s.s,s.t,p))/abs(s.t-s.s);
}
R dll(L a,L b){return ill(a,b)?0:dlp(a,b.s);}
R dls(L l,L s){return ils(l,s)?0:min(dlp(l,s.s),dlp(l,s.t));}
R dss(L a,L b){return iss(a,b)?0:min({dsp(a,b.s),dsp(a,b.t),dsp(b,a.s),dsp(b,a.t)});}
 
// 多角形
// 面積 Verify AOJ 1100 CGL_3_A
R area(const VP& pol){
    int n=pol.size();
    R sum=0;
    rep(i,n) sum+=det(O,pol[i],pol[(i+1)%n]);
    return abs(sum/2.0);
}
 
// 凸多角形の判定 verify CGL_3_B
bool is_convex(const VP& pol){
    int n=pol.size();
    rep(i,n)if(ccw(pol[(i+n-1)%n],pol[i],pol[(i+1)%n])==RIGHT) return false;
    return true;
}
 
// 多角形の内外判定 含む 2 線上 1 含まない 0　(凹多角形も可) verify AOJ CGL_3-C
int in_polygon(const VP& pol, const P& p){
    int n=pol.size(),res=0;
    rep(i,n){
        if(ccw(pol[i],pol[(i+1)%n],p)==ON) return 1;
        bool f=sgn(imag(p-pol[i]))>=0;
        bool s=sgn(imag(p-pol[(i+1)%n]))<0;
        int sign=sgn(imag(pol[(i+1)%n]-pol[i]));
        bool can=sgn(sign*det(pol[i],pol[(i+1)%n],p))>0; // (a*d-b*c)*b
        if(can&&f==s) res+=(2*f-1);
    }
    return res?2:0;
}
 
// 多角形の内外判定　(凹多角形も可) Verify AOJ 2514
bool in_polygon(const VP& pol, const L& l){
    VP check{l.s,l.t};
    int n=pol.size();
    rep(i,n){
        L edge={pol[i],pol[(i+1)%n]};
        if(iss(l,edge)) reg(check,cross(l,edge));
    }
    sort(_all(check));
    n=check.size();
    rep(i,n-1){
        P m=(check[i]+check[i+1])/R(2.0);
        if(in_polygon(pol,m)==false) return false;
    }
    return true;
}
 
// convex_hull Verify AOJ CGL_4_A 線分上の頂点を含む場合は1,含まない場合は0
VP convex_hull(VP pol,int edge=0){
    int n=pol.size(),k=0;
    sort(_all(pol));
    VP res(2*n);
 
    //以下のwhile判定式について 凸包の線分上の頂点を除去 >=0 しない　>=1
    // down
    rep(i,n){
        while(k>1&&sgn(det(O,res[k-1]-res[k-2],pol[i]-res[k-1]))>=edge) k--;
        res[k++]=pol[i];
    }
    // up
    int t=k;
    rrep(i,n-1){
        while(k>t&&sgn(det(O,res[k-1]-res[k-2],pol[i]-res[k-1]))>=edge) k--;
        res[k++]=pol[i];
    }
    res.resize(k-1);
    return res;
}
// farthest point pair Verify AOJ CGL_4_B
R fpp(VP pol){
    if(!is_convex(pol)) pol=convex_hull(pol);
    int n=pol.size(),i=0,j=0;
    R res=0.0;
    if(n<=2) return abs(pol[0]-pol[1]);
 
    rep(k,n){
        if(!cmp_x(pol[i],pol[k]))i=k;
        if(cmp_x(pol[j],pol[k]))j=k;
    }
 
    int si=i,sj=j;
    while(i!=sj||j!=si){
        chmax(res,abs(pol[i]-pol[j]));
        if(sgn(det(O,pol[(i+1)%n]-pol[i],pol[(j+1)%n]-pol[j]))<0)
            i=(i+1)%n;
        else
            j=(j+1)%n;
    }
    return res;
}
 
// 凸カット verify AOJ CGL_4_C
VP convex_cut(const VP& pol,const L& l) {
    VP res;
    int n=pol.size();
    rep(i,n){
        P a = pol[i],b=pol[(i+1)%n];
        if(ccw(l.s,l.t,a)!=RIGHT) reg(res,a);
        if((ccw(l.s,l.t,a)|ccw(l.s,l.t,b))==(LEFT|RIGHT)) reg(res,cross({a,b},l));
    }
    return res;
}
 
// closest point pair Verify AOJ CGL_5_A
R cpp(VP a,int flag=1){
    if(flag) sort(_all(a));
    int n=a.size(),m=n/2;
    if(n<=1) return INF;
    VP b(begin(a),begin(a)+m),c(begin(a)+m,end(a)),e;
    R x=real(a[m]),d=min(cpp(b,0),cpp(c,0));
    sort(_all(a),cmp_y);
    rep(i,n){
        if(abs(real(a[i])-x)>=d) continue;   
        rep(j,e.size()){
            if(imag(a[i]-e[e.size()-1-j])>=d) break;
            chmin(d,abs(a[i]-e[e.size()-1-j]));
        }
        reg(e,a[i]);
    }
    return d;
}
 
// 円
// Verify AOJ 1183
using VC=vector<C>;
bool operator <  (const C& a,const C& b){ return a.c==b.c?sgn(a.r-b.r)<0:a.c<b.c;}
bool operator == (const C& a,const C& b){ return a.c==b.c&&sgn(a.r-b.r)==0;}
 
enum RCC{IN=1,ON_IN=2,ISC=4,ON_OUT=8,OUT=16,ONS=10};
int rcc(C a,C b){
    R d=abs(a.c-b.c);
    if(sgn(a.r+b.r-d)<0) return OUT;
    if(sgn(a.r+b.r-d)==0) return ON_OUT;
    if(sgn(abs(a.r-b.r)-d)<0) return ISC;
    if(sgn(abs(a.r-b.r)-d)==0) return ON_IN;
    return IN;
}
 
// 円関連の交差判定
bool icp(C c,P p,int end=0){return sgn(norm(p-c.c)-norm(c.r))<=-end;}
bool ics(C c,L s,int end=0){return sgn(dsp(s,c.c)-c.r)<=-end;}
bool icsc(C c,L l,int end=0){return ics(c,l) && sgn(max(norm(l.s-c.c),norm(l.t-c.c))-norm(c.r))<=0;}
 
// 円と円の共通部分の面積を求める．
R area(C c1,C c2){
    R d=abs(c2.c-c1.c);
    int r=rcc(c1,c2);
    if(r>=ON_OUT) return 0.0;  
    if(r==IN) return min(norm(c1.r),norm(c2.r))*PI;
    R rc=(norm(d)+ norm(c1.r) - norm(c2.r))/(2.0*d),theta=acos(rc/c1.r),phi=acos((d-rc)/c2.r);
    return norm(c1.r)*theta+norm(c2.r)*phi-d*c1.r*sin(theta);
}
 
//円と直線の交点 Verify AOJ CGL_7_D
P cir(C c,R t){return c.c+polar(c.r,t);}
VP pcl(C c, L l){P h=proj(l,c.c),e=(l.t-l.s)/abs(l.t-l.s)*sq(norm(c.r)-norm(h-c.c));return VP{h-e,h+e};}
 
//2つの円の交点 Verify AOJ CGL_7_E
VP pcc(C a,C b){P d=b.c-a.c,w=(norm(d)+norm(a.r)-norm(b.r))/(2.0*norm(d))*d,h=a.c+w,e=w*P(0,1);return pcl(a,{h-e,h+e});}
 
// 円の接線 Verify AOJ 2001
L tan(C c,R t){P p=cir(c,t),d=polar(c.r,t)*P(0,1);return L{p-d,p+d};}
 
VL tan(C c,P p){
    VL res;R t=arg(p-c.c),d=acos(c.r/abs(p-c.c));
    reg(res,tan(c,t+d));
    if(sgn(d)) reg(res,tan(c,t-d));         
    return res;
}
 
VL tan(C a,C b){
    VL res;R t=arg(b.c-a.c),d=abs(b.c-a.c),i=acos((a.r+b.r)/d),o=acos((a.r-b.r)/d); int r=rcc(a,b);
    if(r>=OUT) reg(res,tan(a,t+i)),reg(res,tan(a,t-i));
    if(r>=ISC) reg(res,tan(a,t+o)),reg(res,tan(a,t-o));
    if(r&ONS) reg(res,tan(a,t));
    return res;
}
 
const int vmax=5010;
using node = struct node{int to;R cost;};
vector<node> graph[vmax];
 
// 点 not verify
R toRagian(R degree){ return degree*PI/180.0;}
R ang (P p){return arg(p);}
R ang (P base,P a,P b) {R res=arg((b-base)/(a-base));return res<0?res+2*PI:res;} // base 中心
P rot (P base,P a,R theta){P tar=a-base;return base+polar(abs(tar), arg(tar)+theta );}
 
inline void add_edge(int f,int t,R c){reg(graph[f],{t,c}),reg(graph[t],{f,c});}
 
void circle_arrangement(const VC &circle,VP &point){
    VP candiate;    
    auto can=[&](P p){for(auto &c:circle) if(icp(c,p,1)) return; reg(candiate,p);};
    auto check1=[&](P p){for(auto &c:circle) if(icp(c,p,1)) return false; return true;};
    auto check2=[&](L s){for(auto &c:circle) if(ics(c,s,1)) return false; return true;};
 
    for(auto &c1:circle){
        rep(j,4) can(cir(c1,j*PI/2.0));
        for(auto &p:point) for(auto &l:tan(c1,p)) can(proj(l,c1.c));
        for(auto &c2:circle){
            if(rcc(c1,c2)==ISC) for(auto &p:pcc(c1,c2)) can(p);
            for(auto &l:tan(c1,c2)) can(proj(l,c1.c)),can(proj(l,c2.c));
        }
    }   
    uniq(candiate),move(_all(candiate),back_inserter(point));
    for(auto &c:circle){
        vector<pair<R,int>> idx;
        rep(i,point.size()) if(sgn(norm(c.c-point[i])-norm(c.r))==0) reg(idx,{arg(point[i]-c.c),i});
        sort(_all(idx)),reg(idx,{idx[0].first+2*PI,idx[0].second});
        rep(i,1,idx.size()){
            R a1=idx[i-1].first,a2=idx[i].first;
            P mid=cir(c,(a1+a2)/2.0);
            if(check1(mid)) add_edge(idx[i-1].second,idx[i].second,c.r*(a2-a1));
        }
    }
    rep(i,point.size())rep(j,i){
        L l={point[i],point[j]};
        if(check2(l)) add_edge(i,j,abs(l.t-l.s));
    }
}
 
// segments arrangement AOJ 1050
 
void segment_arrangement(const vector<L> &seg, vector<P> &point){
    rep(i,vmax) graph[i].clear();
    int n=seg.size();
    rep(i,n){
        reg(point,seg[i].s),reg(point,seg[i].t);
        rep(j,i) if(iss(seg[i],seg[j],1)) reg(point,cross(seg[i],seg[j]));
    }
    uniq(point);
    rep(i,n){
        vector<pair<R,int>> idx;
        rep(j,point.size()) if(ccw(seg[i].s,seg[i].t,point[j])==ON) reg(idx,{norm(point[j]-seg[i].s),j});
        sort(_all(idx));
        rep(j,1,int(idx.size())){
            int a=idx[j-1].second,b=idx[j].second;
            add_edge(a,b,abs(point[a]-point[b]));
        }
    }
}
 
// 線分をマージする
VL merge(VL l) {
    int n=l.size();
    rep(i,n) if(l[i].t<l[i].s) swap(l[i].s,l[i].t);
    sort(_all(l));
    rep(i,n)rep(j,i){
        if(iss(l[i],l[j],0)&&!iss(l[i],l[j],1)){
            if(abs(l[i].t-l[j].s)>abs(l[j].t-l[j].s)) l[j].t=l[i].t;
            l.erase(begin(l)+i--);
            break;
        }
    }
    return l;
}
 
// 凸法を代用すれば?
// 多角形の端点の除去を目的にする．
VP normalize_polygon(VP pol){ int n=pol.size(); rep(i,pol.size()) if(ccw(pol[(i+n-1)%n],pol[i],pol[(i+1)%n])==ON) pol.erase(begin(pol)+i--);return pol;}
L bisector(P a, P b){P mid=(a+b)/P(2,0);return L{mid, mid+(b-a)*P(0,1)};}
VP voronoi_cell(VP pol,VP v,int s){rep(i,v.size())if(i!=s)pol=convex_cut(pol,bisector(v[s],v[i]));return pol;}
 
// 三角形の内心
// verify : aoj 1301
P incenter(P p1, P p2, P p3){
    R a=abs(p2-p3),b=abs(p3-p1),c=abs(p1-p2);
    return (a*p1+b*p2+c*p3)/(a+b+c);
}

P outcenter(P p1, P p2, P p3){
    R a = sin(2 * ang(p1, p2, p3));
    R b = sin(2 * ang(p2, p3, p1));
    R c = sin(2 * ang(p3, p1, p2));
    return (a * p1 + b * p2 + c * p3) / (a + b + c);
}

int main(void){
    cin.tie(0);
    ios::sync_with_stdio(false);

    int n; cin >> n;
    VP p(n); for(auto& e : p) cin >> e;

    R res = INF;

    auto check = [&](C c){
        rep(i, n){
            if(not icp(c, p[i])){
                return false;
            }
        }
        return true;
    };

    // 2 points
    rep(i, n){
        rep(j, i + 1, n){
            P c = (p[i] + p[j]); c /= 2.0;
            R r = abs(c - p[i]);
            C circle = {c, r};

            if(check(circle)){
                chmin(res, r);
            }
        }
    }

    // 3 points
    rep(i, n){
        rep(j, i + 1, n){
            rep(k, j + 1, n){
                P c = outcenter(p[i], p[j], p[k]);
                R r = abs(c - p[i]);
                C circle = {c, r};

                if(check(circle)){
                    chmin(res, r);
                }
            }
        }
    }

    cout.precision(18);
    cout << fixed << res << endl;

    return 0;
}


Measured memory_bytes: 640