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 <cstdio>
#include <iostream>
#include <vector>
#include <list>
#include <cmath>
#include <fstream>
#include <algorithm>
#include <string>
#include <queue>
#include <set>
#include <map>
#include <complex>
#include <iterator>
#include <cstdlib>
#include <cstring>
#include <sstream>

using namespace std;

#define EPS (1e-10)
#define EQ(a,b) (abs((a) - (b)) < EPS)
#define EQV(a,b) (EQ((a).real(),(b).real()) && EQ((a).imag(),(b).imag()))

typedef complex<double> P;
typedef pair<P,P> Edge;
typedef long long ll;

const double PI=4*atan(1.0);
const int MAX_SIZE = 10000;

// 内積
double dot(P a, P b) {
  return (a.real() * b.real() + a.imag() * b.imag());
}
// 外積
double cross(P a, P b) {
  return (a.real() * b.imag() - a.imag() * b.real());
}
// 点cが直線ab上にあるかないか
int is_point_on_line(P a, P b, P c) {
  return EQ( cross(b-a, c-a), 0.0 );
}
// 2直線の直行判定
int is_orthogonal(P a1, P a2, P b1, P b2) {
  return EQ( dot(a1-a2, b1-b2), 0.0 );
}
// 2直線の平行判定
int is_parallel(P a1, P a2, P b1, P b2) {
  return EQ( cross(a1-a2, b1-b2), 0.0 );
}
// 点a,bを通る直線と点cの間の距離
double distance_l_p(P a, P b, P c) {
  return abs(cross(b-a, c-a)) / abs(b-a);
}
// 点a,bを端点とする線分と点cとの距離
double distance_ls_p(P a, P b, P c) {
  if ( dot(b-a, c-a) < EPS ) return abs(c-a);
  if ( dot(a-b, c-b) < EPS ) return abs(c-b);
  return abs(cross(b-a, c-a)) / abs(b-a);
}
// 点が多角形の中に存在するかどうか
bool isInPolygon(vector<P> &points,P s){
	if(points.size()==1)return false;
	vector<P> v;
	for(int i=0;i<(int)points.size();i++)v.push_back(points[i]-s);
	int sign=0;
	for(int i=1;i<=(int)v.size();i++){
		int prv=(i-1+v.size())%v.size();
		int cur=i%v.size();
		double c=cross(v[prv],v[cur]);
		if(EQ(c,0))continue;
		else if(sign==0){
			if(c>0)sign=1;
			else sign=-1;
		}
		else{
			if(sign==-1&&c>0)return false;
			else if(sign==1&&c<0)return false;
		}
	}
	return true;
}
struct Rec{
	vector<P> p;
};
// a1,a2を端点とする線分とb1,b2を端点とする線分の交差判定
int is_intersected_ls(P a1, P a2, P b1, P b2) {
    // 線分が平行な場合は重なっていないことにする
    if(abs(cross(a2-a1,b2-b1)) < EPS){
        return 0;
    }
    return ( cross(a2-a1, b1-a1) * cross(a2-a1, b2-a1) < EPS ) &&
        ( cross(b2-b1, a1-b1) * cross(b2-b1, a2-b1) < EPS );
}
// aとbの矩形が接しているかどうか(どちらかがどちからを含んでいるものもふくむ
bool isTouchRectangle(Rec &a,Rec &b){
	// aの各頂点がbの中に存在しているかチェック
	for(int i=0;i<4;i++)if(isInPolygon(b.p,a.p[i]))return true;
	// 逆
	for(int i=0;i<4;i++)if(isInPolygon(a.p,b.p[i]))return true;
	// 各辺が他方のどれかの辺と接しているか
	for(int i=0;i<4;i++){
		int curi=i;
		int prvi=(i-1+4)%4;
		for(int j=0;j<4;j++){
			int curj=j;
			int prvj=(j-1+4)%4;
			if(is_intersected_ls(a.p[curi],a.p[prvi],b.p[curj],b.p[prvj]))return true;
		}
	}
	return false;
}
// a1,a2を端点とする線分とb1,b2を端点とする線分の交点計算
P intersection_ls(P a1, P a2, P b1, P b2) {
  P b = b2-b1;
  double d1 = abs(cross(b, a1-b1));
  double d2 = abs(cross(b, a2-b1));
  double t = d1 / (d1 + d2);

  return a1 + (a2-a1) * t;
}
// a1,a2を通る直線とb1,b2を通る直線の交差判定
int is_intersected_l(P a1, P a2, P b1, P b2) {
  return !EQ( cross(a1-a2, b1-b2), 0.0 );
}
// a1,a2を通る直線とb1,b2を通る直線の交点計算
P intersection_l(P a1, P a2, P b1, P b2) {
  P a = a2 - a1; P b = b2 - b1;
  return a1 + a * cross(b, b1-a1) / cross(b, a);
}
// 単位ベクトルを求める
P normalVector(P p){
	return p/abs(p);
}
// 法線ベクトルを求める
P unitVector(P a){
	return P(-a.imag(),a.real());
}
// 単位法線ベクトルを求める
P unitNormalVector(P tmp){
	P e=P(-tmp.imag(),tmp.real());
	e/=abs(e);
	return e;
}
// 座標の回転(座標pにある点を,半時計回りにa(ラジアン)回転)
P roundPoint(P p,double a){
	return P(cos(a)*p.real()-sin(a)*p.imag(),sin(a)*p.real()+cos(a)*p.imag());
}
/*
円周と線分の交差判定
*/
bool isCircleCrossLine(P a,P b,P c,double r){
	double d1 = abs(a-c);
	double d2 = abs(b-c);
    // 線分が中に含まれるとき、ここのコメントアウトをはずせばtrue(交差)となる
	//if(d1<r&&d2<r)
	//	return true;
	double d = distance_ls_p(a,b,c);
	return (EQ(d,r)||d<r);
}
// 三角形の内部に点があるかどうか
// 外積の正負がすべて同じなら内部に点あり
bool isInTriangle(P p1,P p2,P p3,P s){
	P a=p1-s;
	P b=p2-s;
	P c=p3-s;
	return ((cross(a,b)>0&&cross(b,c)>0&&cross(c,a)>0)||(cross(a,b)<0&&cross(b,c)<0&&cross(c,a)<0));
}
// 矩形の中に点が存在するかどうか
bool isInRectangle(P p1,P p2,P p3,P p4,P s){
	P a=p1-s;
	P b=p2-s;
	P c=p3-s;
    P d=p4-s;
	return ((cross(a,b)>0&&cross(b,c)>0&&cross(c,d)>0&&cross(d,a)>0)
        ||(cross(a,b)<0&&cross(b,c)<0&&cross(c,d)<0&&cross(d,a)<0));
}
// 三角形の面積を座標から計算
double calcAreaOfTriangle(P a,P b,P c){
	return abs((b.real()-a.real())*(c.imag()-a.imag()) - (c.real()-a.real())*(b.imag()-a.imag()))/2;
}
// 与えられた円の範囲内に点が存在するかどうか
bool isContainingDot(P c,double r,P a){
	return (((c.real()-a.real())*(c.real()-a.real())
		+(c.imag()-a.imag())*(c.imag()-a.imag())<r*r)
		||EQ((c.real()-a.real())*(c.real()-a.real())
		+(c.imag()-a.imag())*(c.imag()-a.imag()),r*r));
}
// 多角形の面積公式
double calcPolygonArea(vector<P> p){
	double sum=0;
	for(int i = 0; i < p.size(); i++)
		sum+=cross(p[i],p[(i+1)%(p.size())]);
	return abs(sum/2);
}
// 2ベクトル間の角度
// aからbへ左周りで何度か(0->2*PI)
double diffAngle(P a,P b){
    double angle=atan2(cross(a,b),dot(a,b));
    if(angle<0)
        return 2*PI+angle;
    return angle;
}
// 2つのベクトルの重なっている部分の長さを返す
// もし重なっていなければ0を返す
double multipleLength(P a,P b,P c,P d){
    Edge e1=make_pair(a,b);
    Edge e2=make_pair(c,d);
    // 平行であるかどうか
    if(!(is_parallel(e1.first,e2.first,e1.second,e2.second)
        &&is_parallel(e1.first,e1.second,e2.first,e2.second)))
        return 0;
    double dist=0;
    // 両方乗っている
    if(EQ(distance_ls_p(e1.first,e1.second,e2.first),0)&&EQ(distance_ls_p(e1.first,e1.second,e2.second),0))
        dist=abs(e2.first-e2.second);
    else if(EQ(distance_ls_p(e2.first,e2.second,e1.first),0)&&EQ(distance_ls_p(e2.first,e2.second,e1.second),0))
        dist=abs(e1.first-e1.second);
    else if(EQ(distance_ls_p(e1.first,e1.second,e2.first),0)){
        // どちらが線上にあるか
        if(EQ(distance_ls_p(e2.first,e2.second,e1.first),0))
            dist=abs(e1.first-e2.first);
        else
            dist=abs(e1.second-e2.first);
    }
    else if(EQ(distance_ls_p(e1.first,e1.second,e2.second),0)){
        if(EQ(distance_ls_p(e2.first,e2.second,e1.first),0))
            dist=abs(e1.first-e2.second);
        else
            dist=abs(e1.second-e2.second);
    }
    return dist;
}
// 2点を通る半径rの円の中点を求める
pair<P,P> calcCircleCenterPoint(P dot1,P dot2,double r){
    double v=abs(dot1-dot2);
    double x = sqrt(r*r - (v/2)*(v/2));
    // 二組の単位法線ベクトル
    P hose[2];
    double x1=-(dot1.imag()-dot2.imag());
    double y1=(dot1.real() - dot2.real());
    hose[0]=P(x1,y1);
    double y2=-y1;
    double x2=-x1;
    hose[1]=P(x2,y2);
    double dd1=abs(hose[0]);
    double dd2=abs(hose[1]);
    hose[0]/=dd1;hose[0]*=x;
    hose[1]/=dd2;hose[1]*=x;
    P tmp=(dot1+dot2);
    tmp/=2;
    hose[0]+=tmp;
    hose[1]+=tmp;
    return make_pair(hose[0],hose[1]);
}
// 4線分が端点以外でクロスしているかどうかを判定
bool checkCross(const vector<Edge> &vec){
    for(int i=0;i<vec.size();i++){
        for(int j=i+1;j<vec.size();j++){
            // 線分がクロスしているかどうか
            if(is_intersected_ls(vec[i].first,vec[i].second,vec[j].first,vec[j].second)){
                // している場合、端点以外でクロスしているなら、false
                P p=intersection_ls(vec[i].first,vec[i].second,vec[j].first,vec[j].second);
                if(!(EQ(p,vec[i].first)||EQ(p,vec[i].second)))
                    return false;
            }
        }
    }
    return true;
}
// 引き数で与えられた4つの点が矩形を作るどうかを判定
bool checkRec(const vector<P> &squ){
    vector<int> v;
    for(int i=0;i<squ.size();i++)v.push_back(i);
    do{
        vector<Edge> ve;
        for(int i=0;i<4;i++)
            ve.push_back(make_pair(squ[v[i]],squ[v[(i+1)%4]]));
        // ここですべての線分がクロスするかどうかを計算
        if(checkCross(ve)){
            // 線分の長さを確認
            if(EQ(abs(ve[0].first-ve[0].second),abs(ve[2].first-ve[2].second)))
                if(EQ(abs(ve[1].first-ve[1].second),abs(ve[3].first-ve[3].second)))
                    // 直行
                    if(is_orthogonal(ve[0].first,ve[0].second,ve[1].first,ve[1].second))
                        if(is_orthogonal(ve[2].first,ve[2].second,ve[3].first,ve[3].second))
                        return true;
        }
    }while(next_permutation(v.begin(),v.end()));
    return false;
}
// 引き数で与えられた4つの点が正方形を作るかどうかを判定
bool checkSqu(const vector<P> &squ){
    vector<int> v;
    for(int i=0;i<squ.size();i++)v.push_back(i);
    do{
        vector<Edge> ve;
        for(int i=0;i<4;i++)
            ve.push_back(make_pair(squ[v[i]],squ[v[(i+1)%4]]));
        // ここですべての線分がクロスするかどうかを計算
        if(checkCross(ve)){
            // 線分の長さを確認
            double d=abs(ve[0].first-ve[0].second);
            for(int i=1;i<4;i++){
                double d2=abs(ve[i].first-ve[i].second);
                if(!EQ(d,d2))return false;
            }
            // 直行確認
            if(is_orthogonal(ve[0].first,ve[0].second,ve[1].first,ve[1].second))
                if(is_orthogonal(ve[2].first,ve[2].second,ve[3].first,ve[3].second))
                    return true;
        }
    }while(next_permutation(v.begin(),v.end()));
    return false;
}
// 二円の共通接線を構成する4直線を求める(二円はお互い接したりどちらかをふくんだりしない)
vector<pair<P,P> > calcCommonTangentialLine(P p1,double r1,P p2,double r2){
	vector<pair<P,P> > res;
	if(r1>r2){
		swap(r1,r2);
		swap(p1,p2);
	}
	// 共通外接線
	{
		double d=abs(p1-p2);
		double a=abs(r1-r2);
		double b=sqrt(d*d-a*a);
		double sita=acos(b/d);
		P e=normalVector(roundPoint((roundPoint((p2-p1),sita)),PI/2));
		res.push_back(make_pair(e*r1+p1,e*r2+p2));
		P e2=normalVector(roundPoint((roundPoint((p2-p1),-sita)),-PI/2));
		res.push_back(make_pair(e2*r1+p1,e2*r2+p2));
	}
	// 共通内接線
	{
		P cp=(r1*p1+r2*p2)/(r1+r2);
		double u=abs(cp-p1);
		double sita=acos(r1/u);
		P e=normalVector(roundPoint(cp-p1,sita));
		res.push_back(make_pair(e*r1+p1,-e*r2+p2));
		P e2=normalVector(roundPoint(cp-p1,-sita));
		res.push_back(make_pair(e2*r1+p1,-e2*r2+p2));
	}
	return res;
}
/*
  与えられた3点a,b,c,をa->b->cと進むとき
  a->bで時計方向に折れて,b->c
  a->bで半時計方向に折れて,b->c
  a->bで逆を向いてaを通り越してb->c
  a->bでそのままb->c
  a->bで逆を向いてb->c
  のどれであるかを判定
*/
int ccw(P a,P b, P c){
  b-=a;c-=a;
  if(cross(b,c)>0&&!EQ(cross(b,c),0))return 1;// counter clockwise
  if(cross(b,c)<0&&!EQ(cross(b,c),0))return -1;// clockwise
  if(dot(b,c)<0&&!EQ(dot(b,c),0))return 2; // c-a-b on line
  if(!EQ(abs(b),abs(c))&&abs(b)<abs(c))return -2; // a-b-c on line
  return 0;
}
// 凸多角形の切断を行う
// lineのfirst側から見て左の多角形が返る
// 多角形は上が+y,右が+xの座標系で座標を時計周りに格納したvectorで表す
// lineは基本的にmakeDivisorで作成
vector<P> convex_cut(vector<P> polygon,pair<P,P> line){
  vector<P> resPolygon;
  int n=polygon.size();
  for(int i=0;i<n;i++){
    P A=polygon[i];
    P B=polygon[(i+1)%n];
    if(ccw(line.first,line.second,A)!=-1)
      resPolygon.push_back(A);
    if(ccw(line.first,line.second,A)*ccw(line.first,line.second,B)<0)
      resPolygon.push_back(intersection_l(A,B,line.first,line.second));
  }
  return resPolygon;
}
// convex_cutの補助関数
// a側の凸多角形を残すような切断ラインを作成
pair<P,P> makeDivisor(P a, P b){
  P mid=(a+b);mid/=2;
  P base=unitNormalVector(b-a);
  base*=-1000000;
  P p1=base;p1+=mid;
  base*=-1;
  P p2=base;p2+=mid;
  return make_pair(p1,p2);
}

int n;
P ps[101];
int main(){

  while(cin>>n&&n){
    vector<P> pol;
    for(int i=0;i<n;i++){
      double x,y;
      cin>>x>>y;
      ps[i]=P(x,y);
      pol.push_back(ps[i]);
    }
    reverse(pol.begin(),pol.end());
    reverse(ps,ps+n);
    vector<P> initPol=pol;
    double ub=1000000000;
    double lb=0;
    const int lim=200;
    for(int p=0;p<lim;p++){
      double mid=(ub+lb)/2;
      //cout<<mid<<endl;
      // convexcutを線分ごとに繰り返して,点が残るかチェック
      for(int i=0;i<n;i++){
	P tmp=(ps[(i+1)%n]-ps[i]);tmp/=abs(tmp);
	tmp=-P(-tmp.imag(),tmp.real());tmp*=mid;
	P p1=tmp;p1+=ps[i];
	P p2=tmp;p2+=ps[(i+1)%n];
	//cout<<p1<<" "<<p2<<endl;
	P tmp2=(p2-p1);tmp2/=abs(tmp2);tmp2*=100000;
	p2+=tmp2;
	tmp2*=-1;
	p1+=tmp2;
	pol=convex_cut(pol,make_pair(p2,p1));
	// cout<<i<<" "<<pol.size()<<endl;
	// cout<<p1<<" "<<p2<<endl;
      }
      if(pol.size()>0)lb=mid;
      else ub=mid;
      pol=initPol;
    }
    printf("%.10f\n",ub);
  }

  return 0;
}