#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<sstream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<cmath>
#include<string>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<numeric>
#include<functional>
#include<algorithm>
#include<bitset>
#include<tuple>
#include<unordered_set>
#include<unordered_map>
#include<random>
#include<array>
#include<cassert>
using namespace std;
#define INF (1<<29)
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define all(v) v.begin(),v.end()
#define uniq(v) v.erase(unique(all(v)),v.end())



#define INF 1e+10
#define EPS 1e-10
#define EQ(a,b) (abs(a-b)<EPS)

//誤差を考慮して足し算
double add(double a, double b) {
	if (abs(a + b) < EPS * (abs(a) + abs(b)))return 0;
	return a + b;
}
struct P {//2次元ベクトル
	double x, y;
	P() {}
	P(double x, double y) :x(x), y(y) {}
	P operator + (P p) {
		return P(add(x, p.x), add(y, p.y));
	}
	P operator - (P p) {
		return P(add(x, -p.x), add(y, -p.y));
	}
	P operator * (double d) {
		return P(x * d, y * d);
	}
	P operator / (double d) {
		return P(x / d, y / d);
	}
	double dot(P p) {//内積
		return add(x * p.x, y * p.y);
	}
	double det(P p) {//外積
		return add(x * p.y, -y * p.x);
	}
	bool equal(P p) {
		return (x - p.x) * (x - p.x) + (y - p.y) * (y - p.y) < EPS * EPS;
	}
	double norm()const {
		return sqrt(x * x + y * y);
	}
};
//typedef pair<P,P> Line;

//線分p1-p2上に点qがあるか判定
bool on_seg(P p1, P p2, P q) {
	return (p1 - q).det(p2 - q) == 0 && (p1 - q).dot(p2 - q) <= 0;
}
//直線p1-p2と直線q1-q2の交点
P intersection(P p1, P p2, P q1, P q2) {
	return p1 + (p2 - p1) * ((q2 - q1).det(q1 - p1) / (q2 - q1).det(p2 - p1));
}
//直線p1-p2でqに線対称な点
P line_symmetry(P p1, P p2, P q) {
	double dx, dy;
	dx = p2.x - p1.x;
	dy = p2.y - p1.y;
	P inter = intersection(p1, p2, q, q + P(dy, -dx));
	return q + (inter - q) * 2;
}

//線分p1-p2と線分q1-q2が交差するか
bool is_intersect(P p1, P p2, P q1, P q2) {
	if (on_seg(p1, p2, q1) || on_seg(p1, p2, q2) || on_seg(q1, q2, p1) || on_seg(q1, q2, p2))return true;
	if ((p1 - p2).det(q1 - q2) == 0)return false;//平行
	P a = intersection(p1, p2, q1, q2);
	return on_seg(p1, p2, a) && on_seg(q1, q2, a);
}
//原点中心回転
P rotate(P p, double rad) {
	double s = sin(rad), c = cos(rad);
	return P(c * p.x - s * p.y, s * p.x + c * p.y);
}
//originを中心に回転
P rotate(P p, double rad, P origin) {
	return origin + rotate(p - origin, rad);
}
//二点間の距離
double dist(P p, P q) {
	p = p - q;
	return sqrt(p.x * p.x + p.y * p.y);
}
//単位ベクトルに変換
P to_unit(P p) {
	double d = sqrt(p.x * p.x + p.y * p.y);
	return p / d;
}

//2点を通る半径rの円の中心座標
vector<P> circle_on_2P(P p, P q, double r) {
	vector<P> res;
	if (2 * r + EPS < dist(p, q))return res;//解なし
	if (q.x < p.x)swap(p, q);
	q = q - p;
	double rad = atan2(q.y, q.x);
	P tmp = rotate(q, -rad);
	double x = tmp.x / 2;
	double y = sqrt(4 * r * r - tmp.x * tmp.x) / 2;
	P a = p + rotate(P(x, y), rad), b = p + rotate(P(x, -y), rad);
	res.push_back(a);
	if (!a.equal(b))res.push_back(b);
	return res;
}


int n;
P p[50];

bool f(double r) {
	rep(j, n) {
		rep(i, j) {
			if (dist(p[i], p[j]) > 2 * r + EPS)continue;
			vector<P> cir = circle_on_2P(p[i], p[j], r);
			for (const P &c : cir) {
				bool ok = true;
				rep(k, n) {
					if (dist(c, p[k]) > r + EPS) {
						ok = false;
						break;
					}
				}
				if (ok)return true;
			}
		}
	}
	return false;
}

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

	cin >> n;
	rep(i,n) {
		cin >> p[i].x;
		cin >> p[i].y;
	}

	double lb = 0, ub = 2000;
	rep(i, 50) {
		double mid = (lb + ub) / 2;

		if (f(mid))ub = mid;
		else lb = mid;
	}

	printf("%.6f\n", ub);


	return 0;
}

Measured memory_bytes: 512