Problem: The main land of Japan called Honshu is an island surrounded by the sea. In such an island, it is natural to ask a question: "Where is the most distant point from the sea?" The answer to this question for Honshu was found in 1996. The most distant point is located in former Usuda Town, Nagano Prefecture, whose distance from the sea is 114.86 km.

In this problem, you are asked to write a program which, given a map of an island, finds the most distant point from the sea in the island, and reports its distance from the sea. In order to simplify the problem, we only consider maps representable by convex polygons.



Input

The input consists of multiple datasets. Each dataset represents a map of an island, which is a convex polygon. The format of a dataset is as follows.


n
x1    y1
.
.
.
xn    yn


Every input item in a dataset is a non-negative integer. Two input items in a line are separated by a space.

n in the first line is the number of vertices of the polygon, satisfying 3 ≤ n ≤ 100. Subsequent n lines are the x- and y-coordinates of the n vertices. Line segments (xi, yi) - (xi+1, yi+1) (1 ≤ i ≤ n - 1) and the line segment (xn, yn) - (x1, y1) form the border of the polygon in counterclockwise order. That is, these line segments see the inside of the polygon in the left of their directions. All coordinate values are between 0 and 10000, inclusive.

You can assume that the polygon is simple, that is, its border never crosses or touches itself. As stated above, the given polygon is always a convex one.

The last dataset is followed by a line containing a single zero.

Output

For each dataset in the input, one line containing the distance of the most distant point from the sea should be output. An output line should not contain extra characters such as spaces.

The answer should not have an error greater than 0.00001 (10-5 ). You may output any number of digits after the decimal point, provided that the above accuracy condition is satisfied.

Example

Input

4
0 0
10000 0
10000 10000
0 10000
3
0 0
10000 0
7000 1000
6
0 40
100 20
250 40
250 70
100 90
0 70
3
0 0
10000 10000
5000 5001
0


Output

5000.000000
494.233641
34.542948
0.353553

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using P = pair<int, int>;
using vi = vector<int>;
using vvi = vector<vector<int>>;
using vll = vector<ll>;
using vvll = vector<vector<ll>>;
const ld eps = 1e-9;
const ll MOD = 1000000007;
const int INF = 1000000000;
const ll LINF = 1ll<<50;
template<typename T>
void printv(const vector<T>& s) {
  for(int i=0;i<(int)(s.size());++i) {
    cout << s[i];
    if(i == (int)(s.size())-1) cout << endl;
    else cout << " ";
  }
}
template<typename T1, typename T2>
ostream& operator<<(ostream &os, const pair<T1, T2> p) {
  os << p.first << ":" << p.second;
  return os;
}
using Real = long double;
const Real EPS = 1e-8, PI = acos(-1);
using Point = complex<Real>;
namespace std {
    bool operator<(const Point& a, const Point& b) {
      if (a.real() == b.real()) return a.imag() < b.imag();
      return a.real() < b.real();
    }
}
struct Line {
    Point a, b;
    Line() {}
    Line(const Point& a, const Point& b) : a(a), b(b) {}
    friend ostream& operator<<(ostream& os, Line& l) {
      return os << "[" << l.a << "," << l.b << "]";
    }
};
struct Segment : Line {
    Segment() = default;
    Segment(const Point& a, const Point& b) : Line(a, b) {}
};
inline bool eq(Real a, Real b) { return abs(b - a) < EPS; }
Real radian_to_degree(Real r) {
  return r * 180.0 / PI;
}
Real degree_to_radian(Real d) {
  return d * PI / 180.0;
}
Point rotate(const Point &p, Real theta) {
  return p * polar((Real)1.0, theta);
}
Real cross(const Point& a, const Point& b) {
  return a.real() * b.imag() - a.imag() * b.real();
}
Real dot(const Point& a, const Point& b) {
  return a.real() * b.real() + a.imag() * b.imag();
}
Point projection(const Line& l, const Point& p) {
  Real A = dot(l.b - l.a, p - l.a),
          B = dot(l.a - l.b, p - l.b);
  return (A * l.b + B * l.a) / (A + B);
}
bool parallel(const Line& l1, const Line& l2) {
  return eq(cross(l1.a - l1.b, l2.a - l2.b), 0.0);
}
bool orthogonal(const Line& l1, const Line& l2) {
  return eq(dot(l1.a - l1.b, l2.a - l2.b), 0.0);
}
const int COUNTER_CLOCKWISE = 1,
        CLOCKWISE = -1,
        ONLINE_BACK = 2,
        ONLINE_FRONT = -2,
        ON_SEGMENT = 0;
int ccw(const Point& a, Point b, Point c) {
  b = b - a, c = c - a;
  if (cross(b, c) > EPS) return COUNTER_CLOCKWISE;
  if (cross(b, c) < -EPS) return CLOCKWISE;
  if (dot(b, c) < 0) return ONLINE_BACK;
  if (norm(b) < norm(c)) return ONLINE_FRONT;
  return ON_SEGMENT;
}
bool intersected(const Line& l, const Point& p) {
  return abs(ccw(l.a, l.b, p)) != 1;
}
bool intersected(const Segment& s, const Point& p) {
  return ccw(s.a, s.b, p) == 0;
}
bool intersected(const Line& l, const Segment& s) {
  return cross(l.b - l.a, s.a - l.a) * cross(l.b - l.a, s.b - l.a) < EPS;
}
bool intersected(const Segment& s1, const Segment& s2) {
  return ccw(s1.a, s1.b, s2.a) * ccw(s1.a, s1.b, s2.b) <= 0 and
         ccw(s2.a, s2.b, s1.a) * ccw(s2.a, s2.b, s1.b) <= 0;
}
Real distance(const Line& l, const Point& p) {
  return abs(p - projection(l, p));
}
Real distance(const Segment& s, const Point& p) {
  Point r = projection(s, p);
  if (intersected(s, r)) return abs(r - p);
  return min(abs(s.a - p), abs(s.b - p));
}
Real distance(const Line &l, const Segment &s) {
  if (intersected(l, s)) return 0;
  return min(distance(l, s.a), distance(l, s.b));
}
Real distance(const Segment& s1, const Segment& s2) {
  if (intersected(s1, s2)) return 0.0;
  return min({ distance(s1, s2.a), distance(s1, s2.b),
               distance(s2, s1.a), distance(s2, s1.b) });
}
Point crosspoint(const Line& l1, const Line& l2) {
  Real A = cross(l2.a - l1.a, l2.b - l1.a),
          B = cross(l2.b - l1.b, l2.a - l1.b);
  return (A * l1.b + B * l1.a) / (A + B);
}
using Polygon = vector<Point>;
Real area(const Polygon& U) {
  Real area = 0;
  for (int i = 0; i < U.size(); ++i) {
    area += cross(U[i], U[(i + 1) % U.size()]);
  }
  return area / 2.0;
}
bool is_convex(const Polygon &U) {
  int n = U.size();
  for (int i = 0; i < n; ++i) {
    if (ccw(U[i], U[(i + 1) % n], U[(i + 2) % n]) == -1) return false;
  }
  return true;
}
const int OUT = 0,
        ON = 1,
        IN = 2;
int contains(const Polygon &U, const Point &p) {
  int in = 0;
  for (int i = 0; i < U.size(); ++i) {
    Point a = U[i] - p, b = U[(i + 1) % U.size()] - p;
    if (cross(a, b) == 0 and dot(a, b) <= 0) return ON;
    if (a.imag() > b.imag()) swap(a, b);
    if (a.imag() <= 0 and 0 < b.imag() and cross(a, b) < 0) in ^= 1;
  }
  return in ? IN : OUT;
}
vector<Point> convex_hull(vector<Point>& p, bool includeOnLine = false) {
  int n = p.size(), k = 0;
  if (n <= 2) return p;
  sort(p.begin(), p.end());
  vector<Point> ch(n * 2);
  const Real BOUND = includeOnLine ? -EPS : EPS;
  for (int i = 0; i < n; ch[k++] = p[i++]) {
    while (k >= 2 and cross(ch[k-1] - ch[k-2], p[i] - ch[k-1]) < BOUND) --k;
  }
  for (int i = n-2, t = k+1; i >= 0; ch[k++] = p[i--]) {
    while (k >= t and cross(ch[k-1] - ch[k-2], p[i] - ch[k-1]) < BOUND) --k;
  }
  ch.resize(k-1);
  return ch;
}
Real convex_diameter(const Polygon &U) {
  int n = U.size();
  int is = 0, js = 0;
  for (int i = 1; i < n; ++i) {
    if (U[i].imag() > U[is].imag()) is = i;
    if (U[i].imag() < U[js].imag()) js = i;
  }
  Real maxnorm = norm(U[is] - U[js]);
  int i = is, j = js;
  do {
    if (cross(U[(i+1) % n] - U[i], U[(j+1) % n] - U[j]) >= 0) {
      j = (j+1) % n;
    } else {
      i = (i+1) % n;
    }
    if (norm(U[i] - U[j]) > maxnorm) {
      maxnorm = norm(U[i] - U[j]);
    }
  } while (i != is or j != js);
  return sqrt(maxnorm);
}
Polygon convex_cut(const Polygon& U, const Line& l) {
  Polygon ret;
  for (int i = 0; i < U.size(); ++i) {
    Point now = U[i], nxt = U[(i + 1) % U.size()];
    if (ccw(l.a, l.b, now) != -1) ret.push_back(now);
    if (ccw(l.a, l.b, now) * ccw(l.a, l.b, nxt) == -1) {
      ret.push_back(crosspoint(Line{ now, nxt }, l));
    }
  }
  return ret;
}
Polygon voronoi_cell(const Point& c, const vector<Point>& ps, Polygon outer) {
  for (const Point& p : ps) {
    Point m = (p + c) / complex<ld>(2.0, 0);
    outer = convex_cut(outer,
                       Line{ m, m + rotate(p - c, M_PI / 2) });
  }
  return outer;
}
int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(10);
  while(1) {
  int n; cin >> n;
  if(n == 0) break;
  Polygon poly;
  for(int i=0;i<n;++i) {
    int x, y; cin >> x >> y;
    poly.emplace_back(Point(x, y));
  }
  vector<Line> lines;
  for(int i=0;i<n;++i) {
    lines.emplace_back(Line(poly[i], poly[(i+1)%n]));
  }
  vector<Point> norm;
  for(int i=0;i<n;++i) {
    Point tmp = (lines[i].b - lines[i].a);
    norm.emplace_back(Point(-tmp.imag() / abs(tmp), tmp.real() / abs(tmp)));
  }
  Real l = 0, r = 100000000;
  while(r - l > eps) {
    Real mid = (l + r) / 2.0;
    vector<Line> newlines;
    for(int i=0;i<n;++i) {
      newlines.emplace_back(Line(lines[i].a + norm[i] * mid, lines[i].b + norm[i] * mid));
    }
    Polygon tmp = poly;
    for(int i=0;i<n;++i) {
      tmp = convex_cut(tmp, newlines[i]);
    }
    if((int)(tmp.size()) > 0) {
      l = mid;
    } else {
      r = mid;
    }
  }
  cout << l << endl;
  }
}