#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef long double ld;
typedef vector<ll> vl;
typedef vector<bool> vb;
typedef vector<string> vs;
typedef vector<char> vc;
typedef queue<ll> ql;
typedef deque<ll> dql;
typedef priority_queue<ll> pql;
typedef set<ll> sl;
typedef pair<ll, ll> pl;
typedef vector<vl> vvl;
typedef vector<pl> vpl;
#define rep(i, n) for(ll i = 0; i < ll(n); i++)
#define rep2(i, k, n) for(ll i = ll(k); i <= ll(n); i++)
#define rep3(i, n, k) for(ll i = ll(n); i >= ll(k); i--)
#define all(v) (v).begin(), (v).end()
ll mod(ll a, ll b) {if(b == 0) return 0; return (a % b + b) % b;}
bool chmin(ll &a, ll b) {if(b < a) {a = b; return 1;} return 0;}
bool chmax(ll &a, ll b) {if(b > a) {a = b; return 1;} return 0;}
const ll INF = 1LL << 60;
const ll MOD = 1e9 + 7;
//const ll MOD = 998244353;
const ll MAX = 1e3;
const ld eps = 1e-9;
const char newl = '\n';

vl parent(MAX), depth(MAX);
 
ll find(ll x) {if(parent[x]==x) return x; return parent[x] = find(parent[x]);}
 
void unite(ll x, ll y) {
  x = find(x);
  y = find(y);
  if (x==y) return;
  
  if(depth[x] < depth[y]) {
    parent[x] = y;
  }else {
    parent[y] = x;
    if(depth[x] == depth[y]) depth[x]++;
  }
}

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

  cout << fixed << setprecision(15);

  ll n;
  cin >> n;
  vl x(n), y(n);
  rep(i, n) cin >> x[i] >> y[i];

  ll ok=0, ng=40001;
  while(ng-ok>1) {
    ll RR = (ok+ng)/2;

    rep(i, n) {parent[i] = i; depth[i] = 0;}
    rep2(i, 200-99, 200+99) {parent[i] = 200; depth[i] = 0;}
    rep2(i, 400-99, 400+99) {parent[i] = 400; depth[i] = 0;}

    rep(i, n) {
      if((100+y[i])*(100+y[i]) < RR) unite(i, x[i]+200);
      if((100-y[i])*(100-y[i]) < RR) unite(i, x[i]+400);
    }

    rep(i, n-1) rep2(j, i+1, n-1) {
      ll dx = x[j]-x[i], dy = y[j]-y[i];
      if(dx*dx+dy*dy < RR) unite(i, j);
    }

    if(find(200)==find(400)) ng = (ok+ng)/2;
    else ok = (ok+ng)/2;
  }
  cout << sqrt(ok)/2 << newl;
  return 0;
}
#include<bits/stdc++.h>
using namespace std;

#define _GLIBCXX_DEBUG
#define all(v) (v).begin(),(v).end()

using ll=long long;
using ld=long double;
using pii=pair<int, int>;
using vi=vector<int>;
using vii=vector<vector<int>>;

const ll LINF=1LL<<60;
const int INF=1<<29;
const ll MOD=1e9+7;

template<typename T> bool chmax(T &a,const T b){if(a < b){a=b; return true;} return false;}
template<typename T> bool chmin(T &a,const T b){if(a > b){a=b; return true;} return false;}

struct Union_Find{
    vector<int> par, depth;
    Union_Find(int n){init(n);}
    void init(int n){
        par.resize(n); depth.resize(n);
        for(int i=0; i<n; i++){
            par[i]=i;
            depth[i]=0;
        }
    }

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

    void unite(int x, int y){
        x=find(x), y=find(y);
        if(x == y) return;

        if(depth[x] < depth[y]) par[x]=y;
        else{
            par[y]=x;
            if(depth[x] == depth[y]) depth[x]++;
        }
    }

    bool same(int x, int y){
        return find(x) == find(y); 
    }
};

int main(){
    int n; cin >> n;
    vi x(n), y(n);
    for(int i=0; i<n; i++){
        cin >> x[i] >> y[i];
    }

    vector<vector<double>> dist(n+2, vector<double>(n+2));
    vector<double> d;
    for(int i=0; i<n; i++){
        for(int j=i+1; j<n; j++){
            int dx=x[i]-x[j], dy=y[i]-y[j];
            double val=sqrt(dx*dx+dy*dy);
            dist[i][j]=val;
            d.push_back(val);
        }
    }
    for(int i=0; i<n; i++){
        dist[i][n]=100-y[i];
        dist[i][n+1]=y[i]+100;
        d.push_back(100-y[i]);
        d.push_back(y[i]+100);
    }
    sort(all(d));

    for(auto ans : d){
        Union_Find uf(n+2);
        for(int i=0; i<n; i++){
            for(int j=i+1; j<n+2; j++){
                if(dist[i][j] <= ans) uf.unite(i, j);
            }
        }
        if(uf.same(n, n+1)){
            cout << fixed << setprecision(5);
            cout << ans/2 << endl;
            break;
        }
    }
    return 0;
}