#define DEBUG 0
#include <bits/stdc++.h>
#define loop(n) for (lint ngtkana_is_a_genius = 0; ngtkana_is_a_genius < lint(n); ngtkana_is_a_genius++)
#define rep(i, begin, end) for (lint i = lint(begin); (i) < lint(end); i++)
#define all(v) v.begin(), v.end()
#define rand(l, r) std::uniform_int_distribution<>(l, r)(mt)
using lint = long long;
auto mt = std::mt19937_64(std::random_device{}());
auto cmn = [](auto&& a, auto b){ if (a > b) {a = b; return true;} return false; };
auto cmx = [](auto&& a, auto b){ if (a < b) {a = b; return true;} return false; };
void debug_impl() { std::cerr << std::endl; }
template <typename Head, typename... Tail>
void debug_impl(Head head, Tail... tail) { std::cerr << " " << head; debug_impl(tail...); }
#if DEBUG
#define debug(...)\
  do {\
    std::cerr << std::boolalpha << "[" << #__VA_ARGS__ << "]:";\
    debug_impl(__VA_ARGS__);\
    std::cerr << std::noboolalpha;\
  } while (false)
#else
#define debug(...) {}
#endif

template < typename Container, typename Value = typename Container::value_type, std::enable_if_t<!std::is_same< Container, std::string >::value, std::nullptr_t> = nullptr>
std::istream& operator>> (std::istream& is, Container& v)
  { for (auto & x : v) { is >> x; } return is; }

template < typename Container, typename Value = typename Container::value_type, std::enable_if_t<!std::is_same< Container, std::string >::value, std::nullptr_t> = nullptr >
std::ostream& operator<< (std::ostream& os, Container const& v) {
 os << "{";
  for (auto it = v.begin(); it != v.end(); it++)
    {os << (it != v.begin() ? "," : "") << *it;}
  return os << "}";
}

template < template < typename ... > class Tuple,  typename... Args, std::size_t ... Inds, std::size_t = std::tuple_size< Tuple < Args ... > >::value >
std::istream& tuple_input_impl(std::istream& os, Tuple<Args...>& tuple, std::integer_sequence<std::size_t, Inds...>)
  { (void)std::initializer_list<int>{((void)(os >> std::get< Inds >(tuple)), 0)...}; return os; }
template < template < typename ... > class Tuple,  typename... Args, std::size_t = std::tuple_size< Tuple < Args ... > >::value >
std::istream& operator>> (std::istream& os, Tuple<Args...>& tuple)
  { return tuple_input_impl(os, tuple, std::index_sequence_for<Args...>()); }

template < template < typename ... > class Tuple,  typename... Args, std::size_t ... Inds, std::size_t = std::tuple_size< Tuple < Args ... > >::value >
std::ostream& tuple_output_impl(std::ostream& os, const Tuple<Args...>& tuple, std::integer_sequence<std::size_t, Inds...>)
  { os << "("; (void)std::initializer_list<int>{((void)(os << (Inds > 0 ? "," : "") << std::get< Inds >(tuple)), 0)...}; return os << ")"; }
template < template < typename ... > class Tuple,  typename... Args, std::size_t = std::tuple_size< Tuple < Args ... > >::value >
std::ostream& operator<< (std::ostream& os, const Tuple<Args...>& tuple)
 { return tuple_output_impl(os, tuple, std::index_sequence_for<Args...>()); }

int main() {
  std::cin.tie(0); std::cin.sync_with_stdio(false);
  int n; std::cin >> n;
  std::vector<std::pair<int,int>> pts(n); std::cin>>pts;
  debug(pts);

  auto det = [&] (auto&& p, auto&& q) {
    int a,b,c,d; std::tie(a,b) = p; std::tie(c,d) = q;
    return a*d-b*c;
  };

  auto sub = [&] (auto&& p, auto&& q) {
    int a,b,c,d; std::tie(a,b) = p; std::tie(c,d) = q;
    return std::make_pair(a-c,b-d);
  };

  auto sqdist = [&] (auto&& p, auto&& q) {
    double a,b,c,d; std::tie(a,b) = p; std::tie(c,d) = q;
    return std::pow(a-c,2) + std::pow(b-d,2);
  };

  auto orthocenter = [&] (auto&& p, auto&& q, auto&& r) {
    double aa = sqdist(q,r);
    double bb = sqdist(r,p);
    double cc = sqdist(p,q);
    double cosA = (bb+cc-aa) / (2 * std::sqrt(bb*cc));
    double cosB = (cc+aa-bb) / (2 * std::sqrt(cc*aa));
    double cosC = (aa+bb-cc) / (2 * std::sqrt(aa*bb));
    double sin2A = 2 * std::sqrt(1 - cosA*cosA) * cosA;
    double sin2B = 2 * std::sqrt(1 - cosB*cosB) * cosB;
    double sin2C = 2 * std::sqrt(1 - cosC*cosC) * cosC;
    // debug(aa,bb,cc);
    // debug(cosA,cosB,cosC);
    debug(sin2A,sin2B,sin2C);

    double x = 0, y = 0;
    x += sin2A * p.first;
    y += sin2A * p.second;
    x += sin2B * q.first;
    y += sin2B * q.second;
    x += sin2C * r.first;
    y += sin2C * r.second;
    x /= (sin2A+sin2B+sin2C);
    y /= (sin2A+sin2B+sin2C);
    // debug(x,y);
    return std::make_pair(x,y);
  };

  auto cal = [&] (auto&& center) {
    double ans = 0;
    for (auto&& p : pts) {
      cmx(ans, std::sqrt(sqdist(p, center)));
    }
    return ans;
  };

  double inf = std::numeric_limits<double>::infinity();
  double ans = inf;
  rep(i,0,n) rep(j,i+1,n) rep(k,j+1,n) {
    auto&& p = pts.at(i);
    auto&& q = pts.at(j);
    auto&& r = pts.at(k);
    // debug(p,q,r);
    if (det(sub(q,p),sub(r,p))==0) continue;
    auto center = orthocenter(p,q,r);
    double now = cal(center);
    cmn(ans, now);
  }
  rep(i,0,n) rep(j,i+1,n) {
    auto&& p = pts.at(i);
    auto&& q = pts.at(j);
    double a,b,c,d; std::tie(a,b) = p, std::tie(c,d) = q;
    auto mid = std::make_pair((a+c)/2,(b+d)/2);
    double now = cal(mid);
    cmn(ans, now);
  }
  std::cout << std::setprecision(10) << ans << std::endl;
  return 0;
}

/*
答えの円の中心は、どれか 3 点のなす三角形の外心か、2 点の中点です。
外心は、対角の sin2t による加重平均です。
外心を決めたら、全点への距離を計算して最大値を取ります。
これらの最小値が答えです。
*/

Measured memory_bytes: 384