#include <bits/stdc++.h>
using namespace std;
using vi = vector<int>;
using vb = vector<bool>;
using vl = vector<long>;
using vs = vector<string>;
using vvi = vector<vector<int>>;
using vvb = vector<vector<bool>>;
using vvc = vector<vector<char>>;
using vvl = vector<vector<long>>;
using pii = pair<int, int>;
using pil = pair<int, long>;
using pll = pair<long, long>;
#define fix20 cout << fixed << setprecision(20)
#define YES cout << "Yes" << endl
#define NO cout << "No" << endl
#define rep(i,n) for(long i=0; i<(long)(n);i++)
#define REP(i,s,t) for(long i=s; i<t; i++)
#define RNG(i,s,t,u) for(long i=s; i<t; i+=u)
#define MOD 1000000007
#define all(vec) vec.begin(), vec.end()
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return true; } return false; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return true; } return false; }

vector<long> par;

void Initpar(long n){
  par = vector<long>(n); 
  for(long i=0; i<n; i++) par.at(i) = i;
}

long root(long x){
  if(x == par.at(x)) return x;
  else return par.at(x) = root(par.at(x));
}

void unite(long x, long y){
  long rx = root(x);
  long ry = root(y);
  if(rx == ry) return ;
  if(rx < ry) par.at(ry) = rx;
  else par.at(rx) = ry;
}

bool same(long x, long y){
  return root(x) == root(y);
}

void update_par(){
  for(int i=0;i<par.size();i++){
    root(i);
  }
}

struct Edge
{
  double cost;
  long from;
  long to;
  bool operator<(const Edge& o) const {
    return cost < o.cost;
  }
};

// long root(long x, vector<long> &par){
//   if(x == par.at(x)) return x;
//   else par.at(x) = root(par.at(x), par);
// }

// bool unite(long x, long y, vector<long> &par){
//   long rx = root(x, par);
//   long ry = root(y, par);
//   if(rx == ry) return true;
//   else if(rx < ry) par.at(ry) = rx;
//   else par.at(rx) = ry;
//   return false;
// }

// bool same(long x, long y, vector<long> &par){
//   return root(x,par) == root(y,par);
// }


int main(){
  long n;
  cin >> n;
  vector<pair<long,long>> d(n);
  rep(i,n) cin >> d.at(i).first >> d.at(i).second;
  vector<Edge> list;
  rep(i,n){
    double x = (double)d.at(i).first;
    double y = (double)d.at(i).second;
    REP(j,i+1,n){
      double nx = (double)d.at(j).first;
      double ny = (double)d.at(j).second;
      double r = sqrt((nx-x)*(nx-x)+(ny-y)*(ny-y))/2.0;
      list.push_back(Edge{r,i,j});
    }
  }
  rep(i,n){
    double y = (double)d.at(i).second;
    list.push_back(Edge{(100-y)/2.0,i,n});
    list.push_back(Edge{(y+100)/2.0,i,n+1});
  }
  list.push_back(Edge{100, n, n+1});
  sort(list.begin(), list.end());
  Initpar(n+2);
  rep(i,n+2) par.at(i) = i;
  for(Edge ed : list){
    long s = ed.from;
    long t = ed.to;
    double r = ed.cost;
    unite(s,t);
    if(same(n,n+1)){
      cout << r << endl;
      return 0;
    }
  }
}
#include<iostream>
#include<string>
#include<iomanip>
#include<cmath>
#include<vector>
#include<algorithm>
#include<utility>
#include<queue>

using namespace std;

#define int long long
#define endl "\n"

constexpr long long INF = (long long)1e18;
constexpr long long MOD = 1'000'000'007; 
constexpr long double eps = 1e-5;

// struct fast_io {
	// fast_io(){
		// std::cin.tie(nullptr);
		// std::ios::sync_with_stdio(false);
	// };
// } fio;



class union_find
{
	int  _setnum;
	vector<int> par, nume;
public:
	union_find(){
	}
	
	union_find(int x){
		par.resize(x);
		nume.resize(x);
		init();
	}
	
	~union_find(){
		//
		
	}
	
	void clear(){
		_setnum = 0;
		par.clear();
		nume.clear();
	}
	
	void init(){
		_setnum = par.size();
		for(int i = 0; i < par.size(); i++){
			par[i] = i;
			nume[i] = 1;
		}
	}
	
	void resize(int x){
		
		par.resize(x);
		nume.resize(x);
		init();
	}

	int find(int x){
		return par[x] == x ? x : par[x] = find(par[x]);
	}

	void unite(int x, int y){
		x = find(x);
		y = find(y);
	
		if(x == y)return;
		
		_setnum--;
		
		if(nume[x] > nume[y]) std::swap(x,y);
		
		par[x] = y;
		nume[y] += nume[x];
	}
	
	bool same(int x, int y){
		return find(x) == find(y);
	}
	
	int numel(int x){
		return nume[find(x)];
	}
	
	int size(){
		return par.size();
	}
	
	int setnum(){
		return _setnum;
	}
};

#define x first
#define y second

int N;
vector<pair<long double,long double>> p;

long double dis(int i, int j){
    return sqrt((p[i].x - p[j].x)*(p[i].x - p[j].x) + (p[i].y - p[j].y)*(p[i].y - p[j].y));
}

bool cal(long double r){
    union_find uf(N+2);
    
    for(int i = 0; i < N; i++){
        for(int j = 0; j < N; j++){
            if(dis(i,j) <= r * 2) {
                uf.unite(i, j);
            }
        }
        if(100 - p[i].y <= r * 2) uf.unite(i, N);
        if(p[i].y +100 <= r * 2) uf.unite(i, N+1);
    }
    
    return !uf.same(N, N+1);
}

signed main(){
	cout<<fixed<<setprecision(10);
	
	cin>>N;
    
    p.resize(N);
    
    for(int i = 0; i < N; i++){
        cin>>p[i].x>>p[i].y;
    }
   
    long double l = 0, r = 110, m;
    
    for(int i = 0; i < 100; i++){
        m = (l + r) / 2;
        
        if(cal(m)) l = m;
        else r = m;
    }
    
    cout<<l<<endl;
    
	return 0;
}