#include<iostream>
#include<math.h>
#include<algorithm>
#include<stdint.h>
#include<vector>
#include<deque>
#include<stack>
#include<functional>
#include<string>
#include<cstring>
#include<time.h>
#include<array>
#include<iomanip>
#include<list>
#include<set>
#include<map>
#include<random>
#include<unordered_map>
#include<unordered_set>
#include<bitset>
#include <queue>


using namespace std;
using ll = long long;
using ull = unsigned long long;
using uint = unsigned int;
using ldb = long double;


//BDD,ZDD,kdtree, bdtree,bicalc, bolonoy, doloney, tree, chinesemod,segmenttree,daikusutora, saidairyuu, 2bugurahu, heirokenshutu, topologicalsort, kyourenketuseibun

#define REP(i,a,b) for(ll i = a; i < b; ++i)
#define PRI(s) cout << s << endl
#define PRIF(v, n) printf("%."#n"f\n", v)
#define PRIY PRI("Yes")
#define PRIN PRI("No")
#define MINS(a,b) a = min(a,(decltype(a))(b))
#define MAXS(a,b) a = max(a,(decltype(a))(b))


using vec2d = pair<double,double>;
using line = pair<vec2d, vec2d>;
vec2d operator+(const vec2d & a, const vec2d & b) { return { a.first + b.first,a.second + b.second }; }
vec2d operator-(const vec2d & a, const vec2d & b) { return { a.first - b.first,a.second - b.second }; }
vec2d operator*(const vec2d & a, const vec2d & b) { return { a.first * b.first,a.second * b.second }; }
vec2d operator*(double c, const vec2d& b) { return { c * b.first,c * b.second }; }
vec2d operator*(const vec2d& b, double c) { return { c * b.first,c * b.second }; }
vec2d operator/(const vec2d& b, double c) { return { b.first / c,b.second/c }; }

double norm(vec2d v) {
	return sqrt(v.first * v.first + v.second * v.second);
}
double dist(vec2d a, vec2d b) {
	return norm(a - b);
}
line lineparam(vec2d from, vec2d to) {
	return { to - from, from };
}
bool parallel(vec2d a, vec2d b, double eps = 1e-6) {
	double det = a.first * b.second - a.second * b.first;
	return -eps < det && det < eps;
}
bool orthogonal(vec2d a, vec2d b, double eps = 1e-6) {
	double dot = a.first * b.first + a.second * b.second;
	return -eps < dot&& dot < eps;
}
vec2d crosspoint(line l1, line l2) {
	vec2d B = l2.second - l1.second;
	double t = (-l2.first.second * B.first + l2.first.first * B.second) / (-l1.first.first * l2.first.second + l2.first.first * l1.first.second);
	return l1.first * t + l1.second;
}
line verticalbisector(vec2d a, vec2d b) {
	vec2d center = (a + b) / 2.0;
	vec2d d = a - b;
	return lineparam(center, center + vec2d{ -d.second, d.first });
}

int main() {
	ll N;
	cin >> N;
	vector<vec2d> v(N);
	REP(i, 0, N) {
		cin >> v[i].first >> v[i].second;
	}
	double ans = 1e18;
	REP(i, 0, N) {
		REP(j, i + 1, N) {
			vec2d center = (v[i] + v[j]) / 2.0;
			bool ok = true;
			REP(l, 0, N) {
				if (dist(v[l], center) - dist(v[i], center) > 1e-6) {
					ok = false;
					break;
				}
			}
			if (ok) MINS(ans, dist(v[i], center));
		}
	}
	REP(i, 0, N) {
		REP(j, i+1, N) {
			REP(k, j + 1, N) {
				line l1 = verticalbisector(v[i], v[j]);
				line l2 = verticalbisector(v[j], v[k]);
				if (parallel(l1.first, l2.first)) continue;
				vec2d center = crosspoint(l1, l2);
				bool ok = true;
				REP(l, 0, N) {
					if (dist(v[l], center) - dist(v[i], center) > 1e-6) {
						ok = false;
						break;
					}
				}
				if (ok) MINS(ans, dist(v[i], center));
			}
		}
	}
	PRIF(ans, 11);
	return 0;
}




Measured memory_bytes: 3800