#include<bits/stdc++.h>
#pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#define rep(i, x) for(ll i = 0; i < x; i++)
#define rep2(i, x) for(ll i = 1; i <= x; i++)
#define all(a) (a).begin(),(a).end()
using ll = long long;
using ld = long double;
using namespace std;
const ll INF = 10000000000000000;
const int intINF = 1000000000;
const ll mod = 1000000007;
const ll MOD = 998244353;
const ld pi = 3.141592653589793238;

//printf("%.10f\n", n);
typedef pair <ll, ll> P;
ll dx[4] = { 1, 0, -1, 0 }, dy[4] = { 0, 1, 0, -1 };

ld d[105][105];
signed main() {
	ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
  cout << fixed << setprecision(15);

	ll n; cin >> n;
	vector<ll> x(n + 5), y(n + 5);
	rep(i, n) {
		cin >> x[i] >> y[i];
	}
  if(n==1){
    cout<<max(100-y[0],100+y[0])/2<<endl;
    return 0;
  }
	//行けないか
	vector<vector<ll> > G(123456);
	rep(i, n) {
		rep(j, n) {
			if (i != j) { G[i].push_back(j); }
			d[i][j] = sqrt(pow(abs(x[i] - x[j]), 2) + pow(abs(y[i] - y[j]), 2));
		}
	}
	rep(i, n) {
		G[i].push_back(n);
		d[i][n] = y[i] + 100;
	}
	//cout << 222 << endl;
	ld ans = 200;
	rep(aa, n) {
		queue<ll> que; queue<ld> cnt;
		vector<ld> visit(n + 1, INF); visit[aa] = 100 - y[aa];
		for (int i = 0; i < G[aa].size(); i++) {
        	if (G[aa][i] == n) { ans = min(ans, max(visit[aa], d[aa][G[aa][i]])); } 
			que.push(G[aa][i]); cnt.push(max(visit[aa], d[aa][G[aa][i]]));
			visit[G[aa][i]] = max(visit[aa], d[aa][G[aa][i]]);
		}
		while (que.size()) {
			//cout << visit[que.front()] << endl;
			for (int i = 0; i < G[que.front()].size(); i++) {
				ld uio = 0;
				if (G[que.front()][i] == n) {
					uio = max(cnt.front(), d[que.front()][G[que.front()][i]]);
					ans = min(ans, uio); continue;
				}
				uio = max(cnt.front(), d[que.front()][G[que.front()][i]]);
				if (visit[G[que.front()][i]] > uio) {
					que.push(G[que.front()][i]);
					cnt.push(uio); visit[G[que.front()][i]] = uio;
				}
			}
			que.pop(); cnt.pop();
		}
	}
	ans /= 2;
	cout<<ans<<endl;
	return 0;
}
#include <bits/stdc++.h>

using namespace std;

#ifdef DEBUG
#define LOG(...) cerr << "[" << #__VA_ARGS__ << "]: " << repr(__VA_ARGS__) << endl;
#define MSG(args) cerr << args << "\n";
#define debug(x) x
#else
#define LOG(...)
#define MSG(args)
#define debug(x)
#endif

#define mp make_pair
#define pb push_back
#define sz(x) (int)((x).size())
#define ms(x, v) memset((x), v, sizeof(x))
#define all(x) (x).begin(), (x).end()
#define REP(x, n) for(int x = 0; x < n; x++)
#define REPV(x, v, n) for(int x = v; x < n; x++)
#define REVE(x, n) for(int x = n; x >= 0; x--)

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

class UnionFind
{
    int N, cnt;
    vector<int> parent, size;

public:
    UnionFind() { N = 0; } 
    UnionFind(int N) :N(N) { clear(); }

    void clear() { cnt = N; size.assign(N + 1, 1); parent.assign(N + 1, 0); for(int i = 1; i <= N; i++) parent[i] = i; }
    void reset(int sz) { N = sz; clear(); }
    inline int count() const { assert(N != 0); return cnt; }
    int getSetSize(int i) { assert(N != 0 && i >= 1 && i <= N); return size[findSet(i)]; }
    int findSet(int i) { assert(N != 0 && i >= 1 && i <= N); return (parent[i] == i) ? i : (parent[i] = findSet(parent[i])); }
    bool isSameSet(int i, int j) { assert(N != 0 && i >= 1 && i <= N && j >= 1 && j <= N); return findSet(i) == findSet(j); }

    void unite(int i, int j)
    {
        assert(N != 0 && i >= 1 && i <= N && j >= 1 && j <= N);
        int x = findSet(i), y = findSet(j);
        if(x == y)
            return;
        if(size[x] < size[y])
            swap(x, y);
        parent[y] = x;
        size[x] += size[y];
        cnt--;
    }
};

const ld eps = 1e-7;

int N;
pll nails[111];

bool can(ld R)
{
    UnionFind uf(N + 2);
    int up = N + 1, down = N + 2;
    REPV(i, 1, N + 1)
    {
	if(100 - nails[i].second <= 2 * R) uf.unite(i, up);
	if(100 + nails[i].second <= 2 * R) uf.unite(i, down);
    }
    REPV(i, 1, N + 1)
	REPV(j, i + 1, N + 1)
	    if(pow(nails[i].first - nails[j].first, 2) + pow(nails[i].second - nails[j].second, 2) <= 4 * R * R)
		uf.unite(i, j);
    return !uf.isSameSet(up, down);
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> N;
    REPV(i, 1, N + 1) cin >> nails[i].first >> nails[i].second;
    ld lo = 0.0, hi = 500.0;
    while(hi - lo > eps)
    {
	ld mid = (hi + lo) / 2.0;
	if(can(mid)) lo = mid;
	else hi = mid;
    }
    cout.precision(9);
    cout << fixed << lo << "\n";
    return 0;
}
