Problem: Mr. KM, the mayor of KM city, decided to build a new elementary school. The site for the school has an awkward polygonal shape, which caused several problems. The most serious problem was that there was not enough space for a short distance racetrack. Your task is to help Mr. KM to calculate the maximum possible length for the racetrack that can be built in the site. The track can be considered as a straight line segment whose width can be ignored. The boundary of the site has a simple polygonal shape without self-intersection, and the track can touch the boundary. Note that the boundary might not be convex.



Input

The input consists of multiple test cases, followed by a line containing "0". Each test case has the following format. The first line contains an integer N (3 \leq N \leq 100). Each of the following N lines contains two integers x_i and y_i (-1,000 \leq x_i, y_i \leq 1,000), which describe the coordinates of a vertex of the polygonal border of the site, in counterclockwise order.

Output

For each test case, print its case number and the maximum possible length of the track in a line. The answer should be given as a floating point number with an absolute error of at most 10^{-6}.

Example

Input

4
0 0
10 0
10 10
0 10
3
0 0
1 0
0 1
0


Output

Case 1: 14.142135624
Case 2: 1.41421356

Solution (in CPP):

Solution:
#include<cmath>
#include<cstdio>
#include<vector>
#include<algorithm>

#define rep(i,n) for(int i=0;i<(n);i++)

using namespace std;

const double EPS=1e-7;

template<class T>
struct point{
	T x,y;
	point operator+(const point &a)const{ return (point){x+a.x,y+a.y}; }
	point operator-(const point &a)const{ return (point){x-a.x,y-a.y}; }
};

template<class T>
point<T> operator*(T c,const point<T> &a){ return (point<T>){c*a.x,c*a.y}; }

template<class T>
point<double> operator/(const point<T> &a,double c){
	return (point<double>){a.x/c,a.y/c};
}

bool operator==(const point<double> &a,const point<double> &b){
	return abs(a.x-b.x)<EPS && abs(a.y-b.y)<EPS;
}

bool operator!=(const point<double> &a,const point<double> &b){
	return abs(a.x-b.x)>EPS || abs(a.y-b.y)>EPS;
}

bool operator<(const point<double> &a,const point<double> &b){
	return abs(a.x-b.x)>EPS ? a.x<b.x : a.y<b.y;
}

template<class T>
struct line{
	point<T> a,b;
};

template<class T>
struct segment{
	point<T> a,b;
	operator line<T>(){ return (line<T>){a,b}; }
};

template<class T>
struct polygon:vector< point<T> >{
	polygon(){}
	polygon(int n):vector< point<T> >(n){}
};

template<class T>
T dot(const point<T> &a,const point<T> &b){ return a.x*b.x+a.y*b.y; }

template<class T>
T cross(const point<T> &a,const point<T> &b){ return a.x*b.y-a.y*b.x; }

enum {CCW=1,CW=-1,ON=0};
int ccw(const point<double> &a,const point<double> &b,const point<double> &c){
	double rdir=cross(b-a,c-a);
	if(rdir> EPS) return CCW;
	if(rdir<-EPS) return CW;
	return ON;
}

template<class T>
point<double> get_intersect(const line<T> &L1,const line<T> &L2){
	double a1=cross(L1.b-L1.a,L2.b-L2.a);
	double a2=cross(L1.b-L1.a,L1.b-L2.a);
	if(abs(a1)<EPS) return L1.a; // L1 == L2
	return L2.a+a2/a1*(L2.b-L2.a);
}

bool intersect(const line<double> &L,const segment<double> &S){
	return cross(L.b-L.a,S.a-L.a)*cross(L.b-L.a,S.b-L.a)<EPS;
}

template<class T>
double dist(const point<T> &a,const point<T> &b){
	return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}

template<class T>
bool cover(const polygon<T> &G,const point<T> &p){
	int n=G.size();
	bool res=false;
	rep(i,n){
		point<T> v1=G[i]-p,v2=G[(i+1)%n]-p;
		if(v1.y>v2.y) swap(v1,v2);
		if(v1.y<EPS && EPS<v2.y && cross(v1,v2)>EPS) res=!res;
		if(abs(cross(v1,v2))<EPS && dot(v1,v2)<EPS) return true;
	}
	return res;
}

int n;
polygon<double> G;

// 直線 L と G の辺 S が点 G[k] で交わっているとき、G[k] を候補点として採用するかどうかを判定する
bool is_candidate(const line<double> &L,const segment<double> &S,int k){
	point<double> prev=G[(k-1+n)%n],next=G[(k+1)%n];
	int c1=ccw(L.a,L.b,prev);
	int c2=ccw(L.a,L.b,next);
	if(c1==CCW && c2==CW || c1==CW && c2==CCW) return true;
	return ccw(prev,G[k],next)==CCW;
}

double solve(){
	double ans=0;
	rep(j,n) rep(i,j) {
		vector< point<double> > P;
		line<double> L={G[i],G[j]};
		rep(k,n){
			segment<double> S={G[k],G[(k+1)%n]};
			if(intersect(L,S)){
				point<double> p=get_intersect((line<double>)S,L);
				if(p!=S.a && p!=S.b
				|| p==S.a && is_candidate(L,S,k)
				|| p==S.b && is_candidate(L,S,(k+1)%n)) P.push_back(p);
			}
		}

		sort(P.begin(),P.end());

		rep(k,(int)P.size()-1){
			point<double> p=P[k],q=P[k+1],r=(p+q)/2;
			if(cover(G,r)) ans=max(ans,dist(p,q));
		}
	}

	return ans;
}

int main(){
	for(int T=1;scanf("%d",&n),n;T++){
		G.resize(n);
		rep(i,n) scanf("%lf%lf",&G[i].x,&G[i].y);
		printf("Case %d: %.9f\n",T,solve());
	}

	return 0;
}