#include <bits/stdc++.h>
using namespace std;
template <typename T, typename U>
std::istream &operator>>(std::istream &i, pair<T, U> &p) {
  i >> p.first >> p.second;
  return i;
}
template <typename T>
std::istream &operator>>(std::istream &i, vector<T> &t) {
  for (auto &v : t) {
    i >> v;
  }
  return i;
}
template <typename T, typename U>
std::ostream &operator<<(std::ostream &o, const pair<T, U> &p) {
  o << p.first << ' ' << p.second;
  return o;
}
template <typename T>
std::ostream &operator<<(std::ostream &o, const vector<T> &t) {
  if (t.empty()) o << '\n';
  for (size_t i = 0; i < t.size(); ++i) {
    o << t[i] << " \n"[i == t.size() - 1];
  }
  return o;
}
template <typename T>
using minheap = priority_queue<T, vector<T>, greater<T>>;
template <typename T>
using maxheap = priority_queue<T, vector<T>, less<T>>;
template <typename T>
bool in(T a, T b, T c) {
  return a <= b && b < c;
}
unsigned int logceil(long long first) {
  return first ? 8 * sizeof(long long) - __builtin_clzll(first) : 0;
}
namespace std {
template <typename T, typename U>
struct hash<pair<T, U>> {
  hash<T> t;
  hash<U> u;
  size_t operator()(const pair<T, U> &p) const {
    return t(p.first) ^ (u(p.second) << 7);
  }
};
}  // namespace std
template <typename T, typename F>
T bsh(T l, T h, const F &f) {
  T r = -1, m;
  while (l <= h) {
    m = (l + h) / 2;
    if (f(m)) {
      l = m + 1;
      r = m;
    } else {
      h = m - 1;
    }
  }
  return r;
}
template <typename F>
double bshd(double l, double h, const F &f, double p = 1e-9) {
  unsigned int r = 3 + (unsigned int)log2((h - l) / p);
  while (r--) {
    double m = (l + h) / 2;
    if (f(m)) {
      l = m;
    } else {
      h = m;
    }
  }
  return (l + h) / 2;
}
template <typename T, typename F>
T bsl(T l, T h, const F &f) {
  T r = -1, m;
  while (l <= h) {
    m = (l + h) / 2;
    if (f(m)) {
      h = m - 1;
      r = m;
    } else {
      l = m + 1;
    }
  }
  return r;
}
template <typename F>
double bsld(double l, double h, const F &f, double p = 1e-9) {
  unsigned int r = 3 + (unsigned int)log2((h - l) / p);
  while (r--) {
    double m = (l + h) / 2;
    if (f(m)) {
      h = m;
    } else {
      l = m;
    }
  }
  return (l + h) / 2;
}
template <typename T>
T gcd(T a, T b) {
  if (a < b) swap(a, b);
  return b ? gcd(b, a % b) : a;
}
template <typename T>
class vector2 : public vector<vector<T>> {
 public:
  vector2() {}
  vector2(size_t a, size_t b, T t = T())
      : vector<vector<T>>(a, vector<T>(b, t)) {}
};
template <typename T>
class vector3 : public vector<vector2<T>> {
 public:
  vector3() {}
  vector3(size_t a, size_t b, size_t c, T t = T())
      : vector<vector2<T>>(a, vector2<T>(b, c, t)) {}
};
template <typename T>
class vector4 : public vector<vector3<T>> {
 public:
  vector4() {}
  vector4(size_t a, size_t b, size_t c, size_t d, T t = T())
      : vector<vector3<T>>(a, vector3<T>(b, c, d, t)) {}
};
template <typename T>
class vector5 : public vector<vector4<T>> {
 public:
  vector5() {}
  vector5(size_t a, size_t b, size_t c, size_t d, size_t e, T t = T())
      : vector<vector4<T>>(a, vector4<T>(b, c, d, e, t)) {}
};
auto seed = chrono::high_resolution_clock::now().time_since_epoch().count();
std::mt19937 rng(seed);
using random_int = std::uniform_int_distribution<int>;
using random_ll = std::uniform_int_distribution<long long>;
struct TimeLimit {
  TimeLimit(double seconds) : s(seconds - 0.2), last(clock()), mx(0) {}
  operator bool() const {
    clock_t cur = clock();
    mx = max(mx, cur - last);
    last = cur;
    return clock() < s * CLOCKS_PER_SEC - 1.5 * mx;
  }
  double s;
  mutable clock_t last, mx;
};
unsigned long long mulull(unsigned long long a, unsigned long long z,
                          unsigned long long mod) {
  __int128 result = ((__int128)a * (__int128)z) % (__int128)mod;
  return (unsigned long long)result;
}
pair<unsigned long long, unsigned long long> mulull(unsigned long long a,
                                                    unsigned long long b) {
  __int128 result = (__int128)a * (__int128)b;
  return {(unsigned long long)(result >> 64), (unsigned long long)result};
}
bool fractionGreaterOrEqual(long long a, long long b, long long c,
                            long long d) {
  if (b < 0) {
    b = -b;
    a = -a;
  }
  if (d < 0) {
    d = -d;
    c = -c;
  }
  return a < 0 && c < 0 ? mulull(-a, d) <= mulull(-c, b)
                        : (a >= 0) && (c < 0 || mulull(a, d) >= mulull(c, b));
}
bool fractionGreaterOrEqual(pair<long long, long long> a,
                            pair<long long, long long> b) {
  return fractionGreaterOrEqual(a.first, a.second, b.first, b.second);
}
bool fractionGreaterOrEqual(double a, double b, double c, double d) {
  return a / b >= c / d;
}
constexpr double PI = 3.14159265358979323846;
template <typename T>
struct Segment;
template <typename T>
struct Point : public pair<T, T> {
  using pair<T, T>::first;
  using pair<T, T>::second;
  Point(T a = 0, T b = 0) : pair<T, T>(a, b) {}
  Point(const pair<T, T> &p) : pair<T, T>(p.first, p.second) {}
  Point(const Point<T> &p) = default;
  Point<T> &operator=(const Point<T> &p) = default;
  Point<T> &operator-=(const Point<T> &p) {
    first -= p.first;
    second -= p.second;
    return *this;
  }
  Point<T> &operator+=(const Point<T> &p) {
    first += p.first;
    second += p.second;
    return *this;
  }
  Point<T> &operator*=(T f) {
    first *= f;
    second *= f;
    return *this;
  }
  Point<T> operator-(const Point<T> &p) const {
    Point<T> t(*this);
    t -= p;
    return t;
  }
  Point<T> operator+(const Point<T> &p) const {
    Point<T> t(*this);
    t += p;
    return t;
  }
  Point<T> operator*(T f) const {
    Point<T> t(*this);
    t *= f;
    return t;
  }
  T squaredDistance(const Point<T> &o) const {
    return Segment<T>{*this, o}.squaredLength();
  }
  long double distance(const Point<T> &o) const {
    return Segment<T>{*this, o}.length();
  }
};
template <typename T>
ostream &operator<<(ostream &o, const Point<T> &p) {
  o << p.first << ' ' << p.second;
  return o;
}
template <typename T>
T ccw(const Point<T> &a, const Point<T> &b, const Point<T> &c) {
  return (b.first - a.first) * (c.second - a.second) -
         (b.second - a.second) * (c.first - a.first);
}
template <typename T>
T area(const Point<T> &a, const Point<T> &b, const Point<T> &c) {
  return abs(ccw(a, b, c));
}
template <typename T>
double cosangle(const Point<T> &a, const Point<T> &b, const Point<T> &c) {
  return ((b.first - a.first) * (c.first - a.first) +
          (b.second - a.second) * (c.second - a.second)) /
         a.distance(b) / a.distance(c);
}
template <typename T>
bool acuteAngle(const Point<T> &a, const Point<T> &b, const Point<T> &c) {
  return ((b.first - a.first) * (c.first - a.first) +
          (b.second - a.second) * (c.second - a.second)) > 0;
}
template <typename T>
bool obtuseAngle(const Point<T> &a, const Point<T> &b, const Point<T> &c) {
  return ((b.first - a.first) * (c.first - a.first) +
          (b.second - a.second) * (c.second - a.second)) < 0;
}
template <typename T>
bool rightAngle(const Point<T> &a, const Point<T> &b, const Point<T> &c) {
  return ((b.first - a.first) * (c.first - a.first) +
          (b.second - a.second) * (c.second - a.second)) == 0;
}
template <typename T>
double angle(const Point<T> &a, const Point<T> &b, const Point<T> &c) {
  return acos(cosangle(a, b, c));
}
template <typename T>
int orientation(const Point<T> &a, const Point<T> &b, const Point<T> &c) {
  auto o = ccw(a, b, c);
  return (o > 1e-6) - (o < -1e-6);
}
template <typename T>
bool collinear(const Point<T> &a, const Point<T> &b, const Point<T> &c) {
  return orientation(a, b, c) == 0;
}
template <typename T>
struct Segment : public pair<Point<T>, Point<T>> {
  using pair<Point<T>, Point<T>>::first;
  using pair<Point<T>, Point<T>>::second;
  explicit Segment(Point<T> a = {0, 0}, Point<T> b = {0, 0})
      : pair<Point<T>, Point<T>>(a, b) {}
  Segment(const Segment<T> &) = default;
  Segment<T> &operator=(const Segment<T> &) = default;
  inline T dx() const { return first.first - second.first; }
  inline T dy() const { return first.second - second.second; }
  T squaredLength() const { return dx() * dx() + dy() * dy(); }
  long double length() const { return sqrtl(squaredLength()); }
  bool contains(const Point<T> &q) const {
    return collinear(first, q, second) &&
           ((q.first <= max(first.first, second.first) &&
             q.first >= min(first.first, second.first)) &&
            (q.second <= max(first.second, second.second) &&
             q.second >= min(first.second, second.second)));
  }
  double distance(const Point<T> &p) const {
    double u =
        ((p.first - second.first) * dx() + (p.second - second.second) * dy()) /
        double(dx() * dx() + dy() * dy());
    if (u > 1) u = 1;
    if (u < 0) u = 0;
    return Point<double>(p.first, p.second)
        .distance({second.first + u * dx(), second.second + u * dy()});
  }
  bool intersect(const Segment<T> &s) const {
    return (orientation(first, second, s.first) !=
                orientation(first, second, s.second) &&
            orientation(s.first, s.second, first) !=
                orientation(s.first, s.second, second)) ||
           contains(s.first) || contains(s.second) || s.contains(first) ||
           s.contains(second);
  }
};
template <typename T>
struct Line : public pair<Point<T>, Point<T>> {
  using pair<Point<T>, Point<T>>::first;
  using pair<Point<T>, Point<T>>::second;
  Line(Point<T> a = {0, 0}, Point<T> b = {0, 0})
      : pair<Point<T>, Point<T>>(a, b) {}
  explicit Line(const Segment<T> &s)
      : pair<Point<T>, Point<T>>(s.first, s.second) {}
  Line(const Line<T> &p) = default;
  Line<T> &operator=(const Line<T> &p) = default;
  inline T dx() const { return first.first - second.first; }
  inline T dy() const { return first.second - second.second; }
  inline T c() const {
    return first.second * second.first - first.first * second.second;
  }
  double distance(const Point<T> &p) const {
    long long px = dx(), py = dy(), dL = px * px + py * py;
    return abs(py * p.first - px * p.second + second.first * first.second -
               second.second * first.first) /
           sqrt(dL);
  }
  Point<double> project(const Point<T> &p) const {
    double u =
        ((p.first - second.first) * dx() + (p.second - second.second) * dy()) /
        double(dx() * dx() + dy() * dy());
    return {second.first + u * dx(), second.second + u * dy()};
  }
  bool parallel(const Line<T> &l) const {
    return abs(l.dx() * dy() - l.dy() * dx()) < 1e-6;
  }
  Point<double> intersection(const Line<T> &l) {
    double det = l.dx() * dy() - l.dy() * dx();
    if (abs(det) < 1e-6)
      return {1e300, 1e300};
    else {
      double c1 = c(), c2 = l.c();
      double first = -(c2 * dx() - l.dx() * c1) / det;
      double second = -(-l.dy() * c1 + c2 * dy()) / det;
      return {first, second};
    }
  };
};
template <typename T>
T cramer(const std::array<T, 9> &X) {
  return X[0] * X[4] * X[8] + X[1] * X[5] * X[6] + X[2] * X[3] * X[7] -
         X[0] * X[5] * X[7] - X[1] * X[3] * X[8] - X[2] * X[4] * X[6];
}
template <typename T>
struct Circle {
  Point<T> center;
  T sqRadius;
  bool contains(const Point<T> &p) const {
    return p.squaredDistance(center) <= sqRadius;
  }
  pair<Point<T>, Point<T>> intersections(Circle c) {
    Point<T> P0 = center;
    Point<T> P1 = c.center;
    T d = P0.distance(P1);
    T a = (sqRadius - c.sqRadius + d * d) / (2 * d);
    T h = sqrt(sqRadius - a * a);
    Point<T> P2 = (P1 - P0) * (a / d) + P0;
    T x3 = P2.first + h * (P1.second - P0.second) / d;
    T y3 = P2.second - h * (P1.first - P0.first) / d;
    T x4 = P2.first - h * (P1.second - P0.second) / d;
    T y4 = P2.second + h * (P1.first - P0.first) / d;
    return {{x3, y3}, {x4, y4}};
  }
  Point<T> invert(const Point<T> &t) const {
    return center + (t - center) * (sqRadius / t.squaredDistance(center));
  }
  Circle(const Point<T> &c, T r) : center(c), sqRadius(r) {}
  explicit Circle(const Point<T> &p) : center(p), sqRadius(0) {}
  explicit Circle(const Point<T> &a, const Point<T> &b)
      : center((a.first + b.first) / 2, (a.second + b.second) / 2),
        sqRadius(a.squaredDistance(b) / 4) {}
  explicit Circle(const Point<T> &a, const Point<T> &b, const Point<T> &c) {
    T la = a.squaredDistance({0, 0}), lb = b.squaredDistance({0, 0}),
      lc = c.squaredDistance({0, 0});
    T first =
        cramer<T>({la, a.second, 1, lb, b.second, 1, lc, c.second, 1}) / 2;
    T second = cramer<T>({a.first, la, 1, b.first, lb, 1, c.first, lc, 1}) / 2;
    T s = cramer<T>(
        {a.first, a.second, 1, b.first, b.second, 1, c.first, c.second, 1});
    center.first = first / s;
    center.second = second / s;
    sqRadius = center.squaredDistance(a);
  }
  static Circle minimumEnclosing(vector<Point<T>> p, bool randomize = true) {
    if (randomize) shuffle(p.begin(), p.end(), rng);
    vector<Point<T>> V;
    return welzl(p.begin(), p.end(), V);
  }

 private:
  static Circle welzl(typename vector<Point<T>>::const_iterator it,
                      typename vector<Point<T>>::const_iterator itend,
                      vector<Point<T>> &p) {
    if (it == itend || p.size() == 3) {
      if (p.size() == 1)
        return Circle{p[0]};
      else if (p.size() == 2)
        return Circle{p[0], p[1]};
      else if (p.size() == 3)
        return Circle(p[0], p[1], p[2]);
      else
        return {Point<T>{0, 0}, 0};
    } else {
      Circle d = welzl(next(it), itend, p);
      if (d.contains(*it))
        return d;
      else {
        p.push_back(*it);
        d = welzl(next(it), itend, p);
        p.pop_back();
        return d;
      }
    }
  }
};
template <typename T>
struct Polygon : public vector<Point<T>> {
  using vector<Point<T>>::vector;
  using vector<Point<T>>::at;
  using vector<Point<T>>::front;
  using vector<Point<T>>::back;
  T doubleSignedArea() const {
    if (this->empty()) return T(0);
    T area = back().first * front().second - back().second * front().first;
    for (int i = 0; i < this->size() - 1; ++i)
      area += (at(i).first * at(i + 1).second - at(i + 1).first * at(i).second);
    return area;
  }
  double circumference() const {
    if (this->empty()) return T(0);
    T res = back().distance(front());
    for (int i = 0; i < this->size() - 1; ++i) res += at(i).distance(at(i + 1));
    return res;
  }
};
template <typename T>
Polygon<T> convexhull(const vector<Point<T>> &v) {
  unsigned int N = (unsigned int)v.size();
  vector<Point<T>> w(N + 1);
  int lo = 0;
  for (int i = 0; i < N; ++i)
    if (v[i].second < v[lo].second ||
        (v[i].second == v[lo].second && v[i].first < v[lo].first))
      lo = i;
  Point<T> o = v[lo];
  for (int i = 0; i < N; ++i)
    w[i + 1] = {v[i].first - o.first, v[i].second - o.second};
  swap(w[1], w[lo + 1]);
  sort(w.begin() + 2, w.end(), [](Point<T> &a, Point<T> &b) {
    if (a.second == 0) return b.second != 0 || a.first < b.first;
    if (b.second == 0) return false;
    auto disc = (a.first * b.second - a.second * b.first);
    return disc > 0 || (disc == 0 && a.second < b.second);
  });
  w[0] = w[N];
  unsigned int M = 1;
  for (int i = 2; i <= N; ++i) {
    while (ccw(w[M - 1], w[M], w[i]) <= 0)
      if (M > 1)
        --M;
      else if (i == N)
        break;
      else
        ++i;
    ++M;
    swap(w[M], w[i]);
  }
  Polygon<T> res(M);
  for (int i = 0; i < M; ++i)
    res[i] = {w[i + 1].first + o.first, w[i + 1].second + o.second};
  return res;
}
class CTheLastHole {
 public:
  void solve(istream &cin, ostream &cout) {
    int N;
    cin >> N;
    vector<Point<long long>> P(N);
    cin >> P;
    vector<Point<double>> R(N);
    for (int i = 0; i < N; ++i) {
      R[i] = {(double)P[i].first, (double)P[i].second};
    }
    auto right_angle = [&](int i, int j, int k) {
      long long a = P[i].squaredDistance(P[j]);
      long long b = P[i].squaredDistance(P[k]);
      long long c = P[k].squaredDistance(P[j]);
      long long d = max(a, max(b, c));
      return 2 * d == a + b + c;
    };
    double ans = 0;
    for (int i = 0; i < N; ++i) {
      for (int j = i + 1; j < N; ++j) {
        for (int k = j + 1; k < N; ++k) {
          if (right_angle(i, j, k)) {
            for (int l = k + 1; l < N; ++l) {
              if (right_angle(i, j, l) && right_angle(i, k, l) &&
                  right_angle(j, k, l)) {
                Circle<double> C(R[i], R[j], R[k]);
                bool del = true;
                for (int m = 0; m < N; ++m) {
                  del &= C.center.squaredDistance(R[m]) >= C.sqRadius - 1e-6;
                }
                if (del) ans = max(ans, C.sqRadius);
              }
            }
          } else {
            long long a = P[i].squaredDistance(P[j]);
            long long b = P[i].squaredDistance(P[k]);
            long long c = P[k].squaredDistance(P[j]);
            long long d = max(a, max(b, c));
            if (2 * d < a + b + c) {
              Circle<double> C(R[i], R[j], R[k]);
              bool del = true;
              for (int l = 0; l < N; ++l) {
                del &= C.center.squaredDistance(R[l]) >= C.sqRadius - 1e-6;
              }
              if (del) ans = max(ans, C.sqRadius);
            }
          }
        }
      }
    }
    if (ans < 1e-6)
      cout << -1 << endl;
    else
      cout << fixed << setprecision(8) << sqrt(ans) << endl;
  }
};
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  CTheLastHole solver;
  std::istream &in(std::cin);
  std::ostream &out(std::cout);
  solver.solve(in, out);
  return 0;
}
