#include <iostream>
#include <vector>
#include <string>
#include <set>
#include <map>
#include <iomanip>
#include <algorithm>
#include <iterator>
#include <stack>
#include <queue>
#include <unordered_set>
#include <stdio.h>
#include <math.h>
#include <bitset>

using namespace std;
#define pb push_back
#define mp make_pair
#define ifor(a, b) for(int i = a; i < b; ++i)
#define jfor(a, b) for(int j = a; j < b; ++j)
#define kfor(a, b) for(int k = a; k < b; ++k)
#define irof(a, b) for(int i = b - 1; i >= a; --i)
#define jrof(a, b) for(int j = b - 1; j >= a; --j)
#define krof(a, b) for(int k = b - 1; k >= a; --k)
#define all(a) a.begin(), a.end()
#define safe_ind(ind, mass) ((ind) >= 0 ? mass[ind] : 0)

typedef long long ll;
typedef unsigned long long ull;

ll mmod(ll x, ll y) {
	if (x >= 0LL)
		return x % y;
	else
		return (y - (-x) % y) % y;
}

ll ddiv(ll x, ll y) {
	x -= mmod(x, y);
	return x / y;
}


struct edge {
	int u;
	int v;
	double weight;
	edge(int u, int v, double weight) :u(u), v(v), weight(weight) {}
};

double sosize(pair<int, int>& u, pair<int, int>& v) {
	return sqrt((u.first - v.first) * (u.first - v.first) + (u.second - v.second) * (u.second - v.second));
}

vector<int> dsu_par;
vector<int> dsu_size;

void dsu_init(int n) {
	dsu_par.resize(n);
	ifor(0, n) dsu_par[i] = i;
	dsu_size.resize(n, 1);
}

int dsu_root(int u) {
	if (dsu_par[u] == u) return u;
	return dsu_par[u] = dsu_root(dsu_par[u]);
}

void dsu_merge(int u, int v) {
	u = dsu_root(u);
	v = dsu_root(v);
	if (u != v) {
		if (dsu_size[v] > dsu_size[u]) {
			swap(u, v);
		}
		dsu_par[v] = u;
		dsu_size[u] += dsu_size[v];
	}
}

void solve() {
	int n; cin >> n;
	vector<pair<int, int>> dots;
	ifor(0, n) {
		int x, y;
		cin >> x >> y;
		dots.emplace_back(x, y);
	}
	vector<edge> edges;
	ifor(0, n) {
		edges.emplace_back(i, n, 100 - dots[i].second);
		edges.emplace_back(i, n + 1, dots[i].second + 100);
	}
	ifor(0, n - 1) {
		jfor(i + 1, n) {
			edges.emplace_back(i, j, sosize(dots[i], dots[j]));
		}
	}
	sort(all(edges), [](edge& f, edge& s) {
		return f.weight < s.weight;
	});
	dsu_init(n + 2);
	for (auto& it : edges) {
		dsu_merge(it.u, it.v);
		if (dsu_root(n) == dsu_root(n + 1)) {
			cout << fixed;
			cout << setprecision(8) << it.weight / 2 << "\n";
			return;
		}
	}
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);
	int t = 1;
	kfor(0, t)
		solve();
	//system("pause");
	return 0;
}
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define INCANT cin.tie(nullptr), ios::sync_with_stdio(false), cout << fixed << setprecision(12)
const int INF = 1e9 + 7;
const ll LINF = 1e18 + 7;
const int MOD = 1e9 + 7;
const double EPS = 1e-9;
void debug_out();
template <typename Head, typename... Tail> void debug_out(Head H, Tail... T);
#ifdef MY_DEBUG
#define dbg(...) debug_out(__VA_ARGS__)
#define dbgs(x) cout << x << " "
#define dbge cout << endl
#else
#define dbg(...)
#define dbgs(x)
#define dbge
#endif
template <class T> bool chmax(T &, const T &);
template <class T> bool chmin(T &, const T &);
template <class T> T pwr(T, ll);
template <class T> T squ(T);
ll fact(ll);
ll comb(ll, ll);

int main() {
    INCANT;
    
    int n;
    cin >> n;
    vector<pair<int, int>> x(n), y(n);
    vector<pair<int, pair<int, int>>> ls(4);
    for (int i = 0; i < n; i++) {
        cin >> x[i].first >> y[i].first;
        x[i].second = i, y[i].second = i; 
    }
    sort(x.begin(), x.end());
    reverse(x.begin(), x.end());
    sort(y.begin(), y.end());
    reverse(y.begin(), y.end());

    ls[0].first = x[0].first - x[n-1].first;
    ls[1].first = max(x[1].first - x[n-1].first, x[0].first - x[n-2].first);
    ls[2].first = y[0].first - y[n-1].first;
    ls[3].first = max(y[1].first - y[n-1].first, y[0].first - y[n-2].first);
    
    set<int> s1, s2;
    s1.insert(x[0].second), s1.insert(x[n-1].second);
    s2.insert(y[0].second), s2.insert(y[n-1].second);
    if (s1 == s2) {
        cout << max(ls[1].first, ls[3].first) << endl;
    }
    else {
        sort(ls.begin(), ls.end());
        reverse(ls.begin(), ls.end());
        cout << ls[1].first << endl;
    }
}

/*





















-----------------------------------以下関数宣言------------------------------------ */

void debug_out() {
    cout << endl;
}

template <typename Head, typename... Tail> void debug_out(Head H, Tail... T) {
    cout << H << " ";
    debug_out(T...);
}

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

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

template <class T> T pwr(T x, ll n) {
    T ans = 1;
    for (int i = 0; i < n; i++) {
        ans *= x;
    }
    return ans;
}

template <class T> T squ(T x) {
    return x * x;
}

ll fact(ll n) {
    ll res = 1;
    for (ll i = 1; i <= n; i++) res *= i;
    return res;
}

ll comb(ll n, ll r) { // comb(60, 30)までオーバーフローなし
    ll res = 1;
    for (int i = 1; i <= r; i++) {
        res *= n--;
        res /= i;
    }
    return res;
}
