#include <map>
#include <set>
#include <list>
#include <cmath>
#include <queue>
#include <stack>
#include <bitset>
#include <vector>
#include <cstdio>
#include <string>
#include <cassert>
#include <climits>
#include <sstream>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define PB push_back
#define MP make_pair
#define SZ(v) ((int)(v).size())
#define abs(x) ((x) > 0 ? (x) : -(x))
#define FOREACH(e,x) for(__typeof(x.begin()) e=x.begin();e!=x.end();++e)
typedef long long LL;

const int maxn = 105;
int n;
int x[maxn], y[maxn];
double d[maxn][maxn];

struct DisJointSet{
	int rank[maxn], parent[maxn];

	void init(int n) {
		for (int i = 0; i < n; i++) {
			rank[i] = 0;
			parent[i] = i;
		}
	}

	int Find(int x) {
		if (parent[x] == x) return x;
		return parent[x] = Find(parent[x]);
	}

	void Union(int x, int y) {
		x = Find(x);
		y = Find(y);

		if (x == y) return;

		if (rank[x] >= rank[y]) {
			parent[y] = x;
			if (rank[x] == rank[y])
				rank[x]++;
		}
		else {
			parent[x] = y;
		}
	}

	int count(int n) {
		int ret = 0;
		for (int i = 0; i < n; i++)
			ret += Find(i) == i;
		return ret;
	}
}uf;

double distance(int x1, int y1, int x2, int y2) {
    return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}

bool check(double r) {
    int s = n, t = n + 1;
    uf.init(n + 2);
    for (int i = 0; i < n; i++) {
        if (100 - y[i] <= 2 * r) {
            uf.Union(s, i);
        }
        if (y[i] - (-100) <= 2 * r) {
            uf.Union(i, t);
        }
    }
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            if (d[i][j] <= 2 * r) {
                uf.Union(i, j);
            }
        }
    }
    return uf.Find(s) == uf.Find(t);
}

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

    double lo = 0, hi = 200, res;
    while (hi - lo > 1e-5) {
        double mid = (lo + hi) / 2;
        if (check(mid)) {
            res = mid;
            hi = mid;
        } else {
            lo = mid;
        }
    }
    printf("%.4f\n", res);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<ll, ll> p_ll;

template<class T>
void debug(T itr1, T itr2) { auto now = itr1; while(now<itr2) { cout << *now << " "; now++; } cout << endl; }
#define repr(i,from,to) for (ll i=(ll)from; i<(ll)to; i++)
#define all(vec) vec.begin(), vec.end()
#define rep(i,N) repr(i,0,N)
#define per(i,N) for (ll i=(ll)N-1; i>=0; i--)

const ll MOD = pow(10,9)+7;
const ll LLINF = pow(2,61)-1;
const ll INF = pow(2,30)-1;

vector<ll> fac;
void c_fac(ll x=pow(10,6)+10) { fac.resize(x,true); rep(i,x) fac[i] = i ? (fac[i-1]*i)%MOD : 1; }
ll inv(ll a, ll m=MOD) { ll b = m, x = 1, y = 0; while (b!=0) { ll d = a/b; a -= b*d; swap(a,b); x -= y*d; swap(x,y); } return (x+m)%m; }
ll nck(ll n, ll k) { return fac[n]*inv(fac[k]*fac[n-k]%MOD)%MOD; }
ll modpow(ll x, ll p) { ll result = 1, now = 1, pm = x; while (now<=p) { if (p&now) { result = result * pm % MOD; } now*=2; pm = pm*pm % MOD; } return result; }
ll gcd(ll a, ll b) { if (a<b) swap(a,b); return b==0 ? a : gcd(b, a%b); }
ll lcm(ll a, ll b) { return a/gcd(a,b)*b; }

struct coord { 
  double x, y; ll i;
  bool operator< (const coord &c) const { return x<c.x||(x==c.x&&y<c.y); };
};

struct dist {
  ll x, y; double d;
  bool operator< (const dist &c) const { return d<c.d; };
};

dist calc_d(coord x, coord y) { 
  double d = sqrt(pow(x.x-y.x,2)+pow(x.y-y.y,2));
  return {x.i, y.i, d};
}

// ----------------------------------------------------------------------
// ----------------------------------------------------------------------

struct UnionFind {
  vector<int> par, s; 
  UnionFind(int N) : par(N), s(N) { rep(i,N) { par[i] = i; s[i] = 1; } }
  int root(int x) { return par[x]==x ? x : par[x] = root(par[x]); }
  int size(int x) { return par[x]==x ? s[x] : s[x] = size(root(x)); }
  void unite(int x, int y) { int rx=root(x), ry=root(y); if (rx!=ry) { s[rx] += s[ry]; par[ry] = rx; } }
  bool same(int x, int y) {  int rx=root(x), ry=root(y); return rx==ry; }
};

// ----------------------------------------------------------------------
// ----------------------------------------------------------------------

int main() {
  ll N; cin >> N;
  coord c[N]; rep(i,N) { cin >> c[i].x >> c[i].y; c[i].i = i+1; }
  vector<dist> d;
  rep(i,N) repr(j,i+1,N) d.push_back(calc_d(c[i], c[j]));
  rep(i,N) { 
    d.push_back({0  ,c[i].i,c[i].y+100.0});
    d.push_back({N+1,c[i].i,100.0-c[i].y});
  }
  sort(all(d));

  // for (auto x: d) cout << x.x << "-" << x.y << ": " << x.d << endl;
  UnionFind uf(N+2);
  double result;
  for (auto x: d) {
    uf.unite(x.x, x.y);
    if (uf.same(0,N+1)) {
      result = x.d/2;
      break;
    }
  }
  cout << setprecision(10) << result << endl;
  return 0;
}