Problem:
Longest Lane
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}
.
Sample Input
4
0 0
10 0
10 10
0 10
3
0 0
1 0
0 1
0
Output for the Sample Input
Case 1: 14.142135624
Case 2: 1.41421356

Submitted solutions:

code_snippet: #include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<cassert>
#define N 110
#define eps 1e-5
using namespace std;

int dlcmp(double x) {return x<-eps?-1:x>eps;}
double sqr(double x) {return x*x;}

struct Point
{
	double x,y;

	Point (){}
	Point (double a,double b):x(a),y(b){}

	void input() {scanf("%lf%lf",&x,&y);}

	Point operator + (const Point &p) const {return Point(x+p.x,y+p.y);}
	Point operator - (const Point &p) const {return Point(x-p.x,y-p.y);}

	double len() {return sqrt(sqr(x)+sqr(y));}
	Point trunc(double d) {d/=len(); return Point(x*d,y*d);}
};

double cross(Point a,Point b) {return a.x*b.y-b.x*a.y;}
double dot(Point a,Point b) {return a.x*b.x+a.y*b.y;}
double dis(Point a,Point b) {return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y));}

Point pt[N];
vector<double>vec;
int n;

/*
// 0 in-in; 1 in-out; 2 out-in; 3 out-out
int check(Point s,Point e,Point a,Point o,Point b)
{
	Point v=e-s;

	if (dlcmp(vec,a-o)<=0&&dlcmp(vec,b-o)<=0)
		return 0;
	else if (dlcmp(vec,a-o)>0&&dlcmp(vec,b-o)>0)
		return 3;
	else if
*/

int segment_intersect(Point s1,Point e1,Point s2,Point e2)
{
	if (dlcmp(cross(e1-s1,s2-s1))*dlcmp(cross(e1-s1,e2-s1))<0&&
		dlcmp(cross(e2-s2,s1-s2))*dlcmp(cross(e2-s2,e1-s2))<0)
		return 1;
	else
		return 0;
}

Point interpoint_lines(Point s1,Point e1,Point s2,Point e2)
{
	Point v1,v2,res;

	v1=s1-e1; v2=s2-e2;

	double r=((s1.x-s2.x)*v2.y-(s1.y-s2.y)*v2.x)/(v1.x*v2.y-v2.x*v1.y);
	res.x=-r*v1.x+s1.x;
	res.y=-r*v1.y+s1.y;
	return res;
}
bool isChange(Point s,Point e,Point a,Point o,Point b)
{
	Point vec=e-s;

	if (dlcmp(cross(vec,a-o))*dlcmp(cross(vec,b-o))<0)
		return true;
	else
		return false;
}

void init()
{
	int i,cnt=0;

	cnt=2;
	for (i=2;i<n;i++)
	{
		while (cnt>1&&dlcmp(cross(pt[cnt-1]-pt[cnt-2],pt[i]-pt[cnt-1]))==0)
			cnt--;
		pt[cnt++]=pt[i];
	}
	n=cnt;
}

void solve(Point s,Point e,Point a,Point b,Point p,Point q)
{
	int dp,dq;

	dp=dlcmp(cross(e-s,p-a));
	dq=dlcmp(cross(e-s,q-b));
	if (dlcmp(dot(e-s,b-a))<0)
	{
		dp=-dp; dq=-dq;
	}


	if(dp>0&&dq>0)
	{
		vec.push_back(dis(s,a));
		vec.push_back(dis(s,b));
		//printf("put3 %.3f %.3f\n",a.x,a.y);
		//printf("put3 %.3f %.3f\n",b.x,b.y);
	}
	else if (dp>0&&dq<0)
	{
		vec.push_back(dis(s,a));
		//printf("put3 %.3f %.3f\n",a.x,a.y);
	}
	else if (dp<0&&dq>0)
	{
		vec.push_back(dis(s,b));
		//printf("put3 %.3f %.3f\n",b.x,b.y);
	}
}


int main()
{
	int i,j,k,m;
	double ans,tmp;
	Point s,e,a,b,o,aa,bb;

	int ys=0;

	while(scanf("%d",&n),n)
	{
		for (i=0;i<n;i++)
			pt[i].input();

		init();
		//printf("n %d\n",n);
		//for (i=0;i<n;i++)
			//printf("%.2f %.2f\n",pt[i].x,pt[i].y);

		ans=0;
		for (i=0;i<n;i++)
			for (j=0;j<n;j++)
			{
				if (i==j) continue;
				//printf("i%d j%d\n",i,j);
				s=pt[i]+(pt[i]-pt[j]).trunc(5000); e=pt[j]+(pt[j]-pt[i]).trunc(5000);

				vec.clear();
				for (k=0;k<n;k++)
				{
					a=pt[k]; b=pt[(k+1)%n];

					if (segment_intersect(s,e,a,b))
					{
						Point p=interpoint_lines(s,e,a,b);
						//printf("put1 %.3f %.3f\n",p.x,p.y);
						vec.push_back(dis(s,p));
					}
				}

				for (k=0;k<n;k++)
				{
					o=pt[k]; a=pt[(k-1+n)%n]; b=pt[(k+1)%n];

					if (dlcmp(cross(e-s,o-s))==0&&isChange(s,e,a,o,b))
					{
						//printf("put2 %.3f %.3f %.3f\n",o.x,o.y,dis(s,o));
						vec.push_back(dis(s,o));
					}
				}

				for (k=0;k<n;k++)
				{
					a=pt[k]; b=pt[(k+1)%n],aa=pt[(k-1+n)%n]; bb=pt[(k+2)%n];

					if (dlcmp(cross(e-s,a-s))==0&&dlcmp(cross(e-s,b-s))==0)
					{
						Point f1=e-s, f2=b-a;
						//printf("true k %d %.3f %.3f %.3f %.3f\n",k,f1.x,f1.y,f2.x,f2.y);
						solve(s,e,a,b,aa,bb);
					}
				}

				sort(vec.begin(),vec.end());
				m=vec.size(); assert(m%2==0);
				tmp=0;
				for (k=0;k<m;k+=2)
					tmp=max(tmp,vec[k+1]-vec[k]);

				ans=max(ans,tmp);
			}

		printf("Case %d: %.8f\n",++ys,ans);
	}

	return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 2936
final_rank: 4

code_snippet: // AOJ 2394 Longest Lane
// 2025.5.18

#include <bits/stdc++.h>
using namespace std;
using ld = long double;
const ld EPS = 1e-9;

struct P { ld x, y; };

inline P operator-(const P &a, const P &b) { return {a.x - b.x, a.y - b.y}; }
inline ld dot(const P &a, const P &b)    { return a.x*b.x + a.y*b.y; }
inline ld crs(const P &a, const P &b)    { return a.x*b.y - a.y*b.x; }
inline ld crs(const P &a, const P &b, const P &c) {
    return crs({b.x - a.x, b.y - a.y}, {c.x - a.x, c.y - a.y});
}

int sgn(ld v){ return v < -EPS ? -1 : (v > EPS ? 1 : 0); }
int ccw(const P &a, const P &b, const P &c){ return sgn(crs(a,b,c)); }

vector<ld> cplt(const vector<P> &ps, const P &a, const P &b){
    int n = ps.size();
    P dir = b - a;
    vector<ld> pos;
    for(int i = 0; i < n; i++){
        P p = ps[i];
        P q = ps[(i+1)%n];
        P r = ps[(i-1+n)%n];
        int sa = ccw(a,b,p), sb = ccw(a,b,q);
        if (sa * sb == -1) {
            ld denom = crs(dir, q - p);
            if (sgn(denom) != 0) pos.push_back(crs(p,q,a) / denom);
        }
        if (sa == 0) {
            int sc = ccw(a,b,r);
            if (sb != sc && (sb*sc < 0 || ccw(p,q,r) > 0))
                pos.push_back(dot(p - a, dir) / dot(dir, dir));
        }
    }
    sort(pos.begin(), pos.end());
    return pos;
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);

    int N, tc = 1;
    while ( (cin >> N) && N ){
        vector<P> poly(N);
        for(int i = 0; i < N; i++) cin >> poly[i].x >> poly[i].y;

        ld ans = 0;
        for(int i = 0; i < N; i++){
            for(int j = 0; j < i; j++){
                P a = poly[i], b = poly[j];
                auto pos = cplt(poly, a, b);
                if (pos.size() < 2) continue;
                ld L = sqrtl(dot(b - a, b - a));
                for(int k = 0; k+1 < (int)pos.size(); k += 2){
                    ld len = (pos[k+1] - pos[k]) * L;
                    ans = max(ans, len);
                }
            }
        }
        cout << "Case " << tc++ << ": "
             << fixed << setprecision(10)
             << (double)ans << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3424
final_rank: 8

code_snippet: #include<bits/stdc++.h>
using namespace std;

using ll=long long;
#define rng(i,a,b) for(int i=(int)a;i<(int)b;i++)
#define rep(i,b) rng(i,0,b)
#define repn(i,b) rng(i,1,b+1)
#define pb push_back
#define eb emplace_back
#define all(x) x.begin(),x.end()
#define si(x) (int)(x.size())
#define mp make_pair

#define tct template<class t>
tct using vc=vector<t>;
using vi=vc<int>;
#define tctu template<class t,class u>
tctu bool chmax(t&a,u b){if(a<b){a=b;return true;}else return false;}
tctu bool chmin(t&a,u b){if(a>b){a=b;return true;}else return false;}

using P=pair<int,int>;
#define a first
#define b second
using ld = long double;
const ld PI = acos((ld)-1);
const ld eps = 1e-9;

int sgn(ld a){ return a<-eps?-1:(a>eps?1:0); }
int sgn(ld a, ld b){ return sgn(a-b); }

using pt = complex<ld>;
#define x real()
#define y imag()

using ln=pair<pt,pt>;
pt dir(ln a){ return a.b-a.a; }
ld dot(const pt&a,const pt&b){ return a.x*b.x+a.y*b.y; }
ld crs(const pt&a,const pt&b){ return a.x*b.y-a.y*b.x; }
ld crs(const pt&a,const pt&b,const pt&c){ return crs(b-a,c-a); }
int ccw(const pt&a,const pt&b){ return sgn(crs(a,b)); }
int ccw(const pt&a,const pt&b,const pt&c){ return ccw(b-a,c-a); }
int ccw(const ln&a, const pt&b){ return ccw(a.a, a.b, b); }
ld cllt(ln a, ln b){
	return crs(b.a,b.b,a.a)/crs(dir(a),dir(b));
}
vc<ld>cplt(const vc<pt>&ps, ln z){
	int n=si(ps);
	vc<ld>pos;
	rep(i,n){
		pt p=ps[i],q=ps[(i+1)%n],r=ps[(i+n-1)%n];
		int a=ccw(z,p),b=ccw(z,q);
		if(a*b==-1) pos.pb(cllt(z,ln(p,q)));
		if(a==0){
			int c=ccw(z,r);
			if(b!=c&&(b*c<0||ccw(p,q,r)>0)) pos.pb(dot(ps[i]-z.a,dir(z))/norm(dir(z)));
		}
	}
	sort(all(pos));
	return pos;
}
int n;
void solve(){
	vc<pt>vec(n);
	rep(i,n){
		ld p,q;cin>>p>>q;
		vec[i] = pt(p,q);
	}
	ld ans = 0;
	rep(i,n) rep(j,i){
		ln z = mp(vec[i], vec[j]);
		auto info = cplt(vec, z);
		for(int a=0;a<si(info);a+=2){
			chmax(ans, (info[a+1]-info[a]) * abs(vec[i]-vec[j]));
		}
	}
	cout << ans << '\n';
}
signed main(){
	cin.tie(0);
	ios::sync_with_stdio(0);
	cout<<fixed<<setprecision(20);
	int t; 
	rng(i,1,1000000){
		cin>>n; if(!n) return 0;
		cout << "Case "<<i<<": "; solve();
	}
}
accuracy: 1
time_ms: 20
memory_kb: 3572
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;
const double eps = 0.000001;
const double INF = 100000000;
int sign(double x){
  if (x > eps){
    return 1;
  } else if (x < -eps){
    return -1;
  } else {
    return 0;
  }
};
struct point{
  double x, y;
  point(){
  }
  point(double x, double y): x(x), y(y){
  }
  point operator +(point P){
    return point(x + P.x, y + P.y);
  }
  point operator -(point P){
    return point(x - P.x, y - P.y);
  }
};
double abs(point P){
  return sqrt(P.x * P.x + P.y * P.y);
}
double dist(point P, point Q){
  return abs(Q - P);
}
double dot(point P, point Q){
  return P.x * Q.x + P.y * Q.y;
}
double cross(point P, point Q){
  return P.x * Q.y - P.y * Q.x;
}
bool point_in_angle(point A, point B, point C, point P){
  B = B - A;
  C = C - A;
  P = P - A;
  if (abs(cross(B, P)) < eps && dot(B, P) > 0){
    return true;
  }
  if (abs(cross(C, P)) < eps && dot(C, P) > 0){
    return true;
  }
  if (abs(cross(B, C)) < eps){
    if (dot(B, C) > 0){
      return false;
    } else {
      return cross(B, P) > 0;
    }
  }
  if (cross(B, C) > 0){
    return cross(B, P) > 0 && cross(P, C) > 0;
  } else {
    return cross(B, P) > 0 || cross(P, C) > 0;
  }
}
struct line{
  point A, B;
  line(point A, point B): A(A), B(B){
  }
};
point vec(line L){
  return L.B - L.A;
}
bool segment_line_intersect(line L1, line L2){
  return sign(cross(L2.A - L1.A, vec(L1))) * sign(cross(L2.B - L1.A, vec(L1))) < 0;
}
bool segment_intersect(line L1, line L2){
  return segment_line_intersect(L1, L2) && segment_line_intersect(L2, L1);
}
int main(){
  cout << fixed << setprecision(10);
  int T = 0;
  while (true){
    int N;
    cin >> N;
    if (N == 0){
      break;
    }
    vector<point> P(N * 2);
    for (int i = 0; i < N; i++){
      cin >> P[i].x >> P[i].y;
    }
    for (int i = 0; i < N; i++){
      P[N + i] = P[i];
    }
    double ans = 0;
    for (int i = 1; i <= N; i++){
      for (int j = i + 1; j < i + N - 1; j++){
        double mn = -INF, mx = INF;
        bool ok = true;
        if (!point_in_angle(P[i], P[i + 1], P[i - 1], P[j])){
          ok = false;
        }
        if (!point_in_angle(P[i], P[i + 1], P[i - 1], P[i] + (P[i] - P[j]))){
          mn = 0;
        }
        if (!point_in_angle(P[j], P[j + 1], P[j - 1], P[i])){
          ok = false;
        }
        if (!point_in_angle(P[j], P[j + 1], P[j - 1], P[j] + (P[j] - P[i]))){
          mx = 1;
        }
        for (int k = 0; k < N; k++){
          if (k != i - 1 && k != i % N && k != (j - 1) % N && k != j % N){
            if (segment_line_intersect(line(P[i], P[j]), line(P[k], P[k + 1]))){
              double r = cross(P[k] - P[i], P[k + 1] - P[k]) / cross(P[j] - P[i], P[k + 1] - P[k]);
              if (r < eps){
                mn = max(mn, r);
              } else if (r > 1 - eps){
                mx = min(mx, r);
              } else {
                ok = false;
              }
            }
          }
        }
        for (int k = 0; k < N; k++){
          if (k != i % N && k != j % N){
            if (abs(cross(P[k] - P[i], P[j] - P[i])) < eps){
              if (!point_in_angle(P[k], P[k + 1], P[k + N - 1], P[k] + P[i] - P[j]) || !point_in_angle(P[k], P[k + 1], P[k + N - 1], P[k] + P[j] - P[i])){
                if (dot(P[k] - P[i], P[j] - P[i]) < 0){
                  mn = max(mn, -abs(P[k] - P[i]) / abs(P[j] - P[i]));
                } else if (dot(P[k] - P[j], P[j] - P[i]) > 0){
                  mx = min(mx, abs(P[k] - P[i]) / abs(P[j] - P[i]));
                } else {
                  ok = false;
                }
              }
            }
          }
        }
        if (ok){
          ans = max(ans, (mx - mn) * dist(P[i], P[j]));
        }
      }
    }
    cout << "Case " << T + 1 << ": " << ans << endl;
    T++;
  }
}
accuracy: 1
time_ms: 40
memory_kb: 3468
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;
const double eps = 0.000001;
const double INF = 100000000;
int sign(double x){
  if (x > eps){
    return 1;
  } else if (x < -eps){
    return -1;
  } else {
    return 0;
  }
};
struct point{
  double x, y;
  point(){
  }
  point(double x, double y): x(x), y(y){
  }
  point operator +(point P){
    return point(x + P.x, y + P.y);
  }
  point operator -(point P){
    return point(x - P.x, y - P.y);
  }
};
double abs(point P){
  return sqrt(P.x * P.x + P.y * P.y);
}
double dist(point P, point Q){
  return abs(Q - P);
}
double dot(point P, point Q){
  return P.x * Q.x + P.y * Q.y;
}
double cross(point P, point Q){
  return P.x * Q.y - P.y * Q.x;
}
bool point_in_angle(point A, point B, point C, point P){
  B = B - A;
  C = C - A;
  P = P - A;
  if (abs(cross(B, P)) < eps && dot(B, P) > 0){
    return true;
  }
  if (abs(cross(C, P)) < eps && dot(C, P) > 0){
    return true;
  }
  if (abs(cross(B, C)) < eps){
    if (dot(B, C) > 0){
      return false;
    } else {
      return cross(B, P) > 0;
    }
  }
  if (cross(B, C) > 0){
    return cross(B, P) > 0 && cross(P, C) > 0;
  } else {
    return cross(B, P) > 0 || cross(P, C) > 0;
  }
}
struct line{
  point A, B;
  line(point A, point B): A(A), B(B){
  }
};
point vec(line L){
  return L.B - L.A;
}
bool segment_line_intersect(line L1, line L2){
  return sign(cross(L2.A - L1.A, vec(L1))) * sign(cross(L2.B - L1.A, vec(L1))) < 0;
}
bool segment_intersect(line L1, line L2){
  return segment_line_intersect(L1, L2) && segment_line_intersect(L2, L1);
}
int main(){
  cout << fixed << setprecision(10);
  int T = 0;
  while (true){
    int n;
    cin >> n;
    if (n == 0){
      break;
    }
    vector<point> P(n * 2);
    for (int i = 0; i < n; i++){
      cin >> P[i].x >> P[i].y;
    }
    for (int i = 0; i < n; i++){
      P[n + i] = P[i];
    }
    double ans = 0;
    for (int i = 1; i <= n; i++){
      for (int j = i + 1; j < i + n - 1; j++){
        double mn = -INF, mx = INF;
        bool ok = true;
        if (!point_in_angle(P[i], P[i + 1], P[i - 1], P[j])){
          ok = false;
        }
        if (!point_in_angle(P[i], P[i + 1], P[i - 1], P[i] + (P[i] - P[j]))){
          mn = 0;
        }
        if (!point_in_angle(P[j], P[j + 1], P[j - 1], P[i])){
          ok = false;
        }
        if (!point_in_angle(P[j], P[j + 1], P[j - 1], P[j] + (P[j] - P[i]))){
          mx = 1;
        }
        for (int k = 0; k < n; k++){
          if (k != i - 1 && k != i % n && k != (j - 1) % n && k != j % n){
            if (segment_line_intersect(line(P[i], P[j]), line(P[k], P[k + 1]))){
              double r = cross(P[k] - P[i], P[k + 1] - P[k]) / cross(P[j] - P[i], P[k + 1] - P[k]);
              if (r < eps){
                mn = max(mn, r);
              } else if (r > 1 - eps){
                mx = min(mx, r);
              } else {
                ok = false;
              }
            }
          }
        }
        for (int k = 0; k < n; k++){
          if (k != i % n && k != j % n){
            if (abs(cross(P[k] - P[i], P[j] - P[i])) < eps){
              if (!point_in_angle(P[k], P[k + 1], P[k + n - 1], P[k] + P[i] - P[j]) || !point_in_angle(P[k], P[k + 1], P[k + n - 1], P[k] + P[j] - P[i])){
                if (dot(P[k] - P[i], P[j] - P[i]) < 0){
                  mn = max(mn, -abs(P[k] - P[i]) / abs(P[j] - P[i]));
                } else if (dot(P[k] - P[j], P[j] - P[i]) > 0){
                  mx = min(mx, abs(P[k] - P[i]) / abs(P[j] - P[i]));
                } else {
                  ok = false;
                }
              }
            }
          }
        }
        if (ok){
          ans = max(ans, (mx - mn) * dist(P[i], P[j]));
        }
      }
    }
    cout << "Case " << T + 1 << ": " << ans << endl;
    T++;
  }
}
accuracy: 1
time_ms: 40
memory_kb: 3576
final_rank: 13

code_snippet: #pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<unordered_set>
#include<utility>
#include<cassert>
#include<complex>
#include<numeric>
#include<array>
#include<chrono>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
constexpr ll mod = 1000000007;
const ll INF = mod * mod;
typedef pair<int, int>P;

#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;

template<typename T>
void chmin(T& a, T b) {
	a = min(a, b);
}
template<typename T>
void chmax(T& a, T b) {
	a = max(a, b);
}
template<typename T>
void cinarray(vector<T>& v) {
	rep(i, v.size())cin >> v[i];
}
template<typename T>
void coutarray(vector<T>& v) {
	rep(i, v.size()) {
		if (i > 0)cout << " "; cout << v[i];
	}
	cout << "\n";
}
ll mod_pow(ll x, ll n, ll m = mod) {
	if (n < 0) {
		ll res = mod_pow(x, -n, m);
		return mod_pow(res, m - 2, m);
	}
	if (abs(x) >= m)x %= m;
	if (x < 0)x += m;
	if (x == 0)return 0;
	ll res = 1;
	while (n) {
		if (n & 1)res = res * x % m;
		x = x * x % m; n >>= 1;
	}
	return res;
}
struct modint {
	int n;
	modint() :n(0) { ; }
	modint(ll m) {
		if (m < 0 || mod <= m) {
			m %= mod; if (m < 0)m += mod;
		}
		n = m;
	}
	operator int() { return n; }
};
bool operator==(modint a, modint b) { return a.n == b.n; }
modint operator+=(modint& a, modint b) { a.n += b.n; if (a.n >= mod)a.n -= mod; return a; }
modint operator-=(modint& a, modint b) { a.n -= b.n; if (a.n < 0)a.n += mod; return a; }
modint operator*=(modint& a, modint b) { a.n = ((ll)a.n * b.n) % mod; return a; }
modint operator+(modint a, modint b) { return a += b; }
modint operator-(modint a, modint b) { return a -= b; }
modint operator*(modint a, modint b) { return a *= b; }
modint operator^(modint a, ll n) {
	if (n == 0)return modint(1);
	modint res = (a * a) ^ (n / 2);
	if (n % 2)res = res * a;
	return res;
}

ll inv(ll a, ll p) {
	return (a == 1 ? 1 : (1 - p * inv(p % a, a)) / a + p);
}
modint operator/(modint a, modint b) { return a * modint(inv(b, mod)); }
modint operator/=(modint& a, modint b) { a = a / b; return a; }
const int max_n = 1 << 10;
modint fact[max_n], factinv[max_n];
void init_f() {
	fact[0] = modint(1);
	for (int i = 0; i < max_n - 1; i++) {
		fact[i + 1] = fact[i] * modint(i + 1);
	}
	factinv[max_n - 1] = modint(1) / fact[max_n - 1];
	for (int i = max_n - 2; i >= 0; i--) {
		factinv[i] = factinv[i + 1] * modint(i + 1);
	}
}
modint comb(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[b] * factinv[a - b];
}
modint combP(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[a - b];
}

ll gcd(ll a, ll b) {
	a = abs(a); b = abs(b);
	if (a < b)swap(a, b);
	while (b) {
		ll r = a % b; a = b; b = r;
	}
	return a;
}
typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-8;
const ld pi = acosl(-1.0);
int dx[4] = { 1,0,-1,0 };
int dy[4] = { 0,1,0,-1 };

using mP = pair<modint, modint>;
//-----------------------------------

typedef complex<ld> Point;
ld dot(Point a, Point b) { return real(conj(a) * b); }
ld cross(Point a, Point b) { return imag(conj(a) * b); }
namespace std {
	bool operator<(const Point& lhs, const Point& rhs) {
		return lhs.real() == rhs.real() ? lhs.imag() < rhs.imag() : lhs.real() < rhs.real();
	}
}
struct Line {
	Point a, b;
};
struct Circle {
	Point p; ld r;
};
int ccw(Point a, Point b, Point c) {
	b -= a; c -= a;
	if (cross(b, c) > eps)return 1;//counter clockwise
	if (cross(b, c) < -eps)return -1;//clock wise
	if (dot(b, c) < 0)return 2;//c--a--b on line
	if (norm(b) < norm(c))return -2;//a--b--c on line
	return 0; //a--c--b on line
}
bool eq(ld a, ld b) {
	return abs(a - b) < eps;
}
//2直線の交差判定
bool isis_ll(Line l, Line m) {
	return !eq(cross(l.b - l.a, m.b - m.a), 0);
}
//直線と線分の交差判定
//bool isis_ls(Line l, Line s) {
//	return (cross(l.b - l.a, s.a - l.a) * cross(l.b - l.a, s.b - l.a) < eps);
//}
//直線と線分の交差判定2
bool isis_ls(Line l, Line s) {
	//return ccw(l.a, l.b, s.a) * ccw(l.a, l.b, s.b) !=1;
	return (cross(l.b - l.a, s.a - l.a) * cross(l.b - l.a, s.b - l.a) < eps);
}
//点が直線上に存在するか
bool isis_lp(Line l, Point p) {
	return (abs(cross(l.b - p, l.a - p)) < eps);
}
//点が線分上に存在するか
bool isis_sp(Line s, Point p) {
	//誤差がisis_lpに比べて大きいので、できるだけisis_lpを使う
	return (abs(s.a - p) + abs(s.b - p) - abs(s.b - s.a) < eps);
}
//線分と線分の交差判定
//bool isis_ss(Line s, Line t) {
//	return(cross(s.b - s.a, t.a - s.a)*cross(s.b - s.a, t.b - s.a) < -eps && cross(t.b - t.a, s.a - t.a)*cross(t.b - t.a, s.b - t.a) < -eps);
//}
//線分と線分の交差判定2
bool isis_ss(Line s, Line t) {
	return ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) <= 0 && ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) <= 0;
}
//点から直線への垂線の足
Point proj(Line l, Point p) {
	ld t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
	return l.a + t * (l.a - l.b);
}
//直線と直線の交点
//平行な２直線に対しては使うな！！！！
Point is_ll(Line s, Line t) {
	Point sv = s.b - s.a; Point tv = t.b - t.a;
	return s.a + sv * cross(tv, t.a - s.a) / cross(tv, sv);
}
//直線と点の距離
ld dist_lp(Line l, Point p) {
	return abs(p - proj(l, p));
}
//直線と直線の距離
ld dist_ll(Line l, Line m) {
	return isis_ll(l, m) ? 0 : dist_lp(l, m.a);
}
//線分と直線の距離
ld dist_ls(Line l, Line s) {
	return isis_ls(l, s) ? 0 : min(dist_lp(l, s.a), dist_lp(l, s.b));
}
//線分と点の距離
ld dist_sp(Line s, Point p) {
	Point r = proj(s, p);
	return isis_sp(s, r) ? abs(p - r) : min(abs(p - s.a), abs(p - s.b));
}
//線分と線分の距離
ld dist_ss(Line s, Line t) {
	if (isis_ss(s, t))return 0;
	return min({ dist_sp(s,t.a),dist_sp(s,t.b),dist_sp(t,s.a),dist_sp(t,s.b) });
}
//線分と線分の交点、平行な場合は端点両方
vector<Point> is_ss(Line s1, Line s2) {
	if (!isis_ss(s1, s2))return {};
	vector<Point> res;
	if (abs(cross(s1.b - s1.a, s2.b - s2.a)) < eps) {
		if (isis_sp(s1, s2.a)) res.push_back(s2.a);
		if (isis_sp(s1, s2.b)) res.push_back(s2.b);
		if (isis_sp(s2, s1.a)) res.push_back(s1.a);
		if (isis_sp(s2, s1.b)) res.push_back(s1.b);
	}
	else {
		res.push_back(is_ll(s1, s2));
	}
	return res;
}

using polygon = vector<Point>;
//0 -> on polygon, 1-> in polygon, 2-> out polygon
int is_in_polygon(polygon& poly, Point p) {
	ld sum = 0;
	int n = poly.size();
	rep(i, n) {
		int ni = i + 1 == n ? 0 : i + 1;
		Point pl = poly[i];
		Point pr = poly[ni];
		Line e = { pl,pr };
		if (isis_sp(e, p))return 0;
		sum += arg((pr - p) / (pl - p));
	}
	if (abs(sum) < pi / 2)return 2;
	return 1;
}
bool edge_in_polygon(polygon& poly, Line l) {
	Point s = l.a, t = l.b;
	if (is_in_polygon(poly, s) == 2 || is_in_polygon(poly, t) == 2)return false;
	vector<ld> ts;
	int n = poly.size();
	rep(i, n) {
		int ni = i + 1 == n ? 0 : i + 1;
		Point pl = poly[i];
		Point pr = poly[ni];
		Line e = { pl,pr };
		vector<Point> vp = is_ss(l, e);
		for (Point p : vp) {
			ld val = abs(p - s) / abs(t - s);
			ts.push_back(val);
		}
	}
	ts.push_back(0);
	ts.push_back(1);
	sort(all(ts));
	rep(i, ts.size() - 1) {
		ld x = (ts[i] + ts[i + 1]) / 2;
		Point c = s + (t - s) * x;
		if (is_in_polygon(poly, c) == 2)return false;
	}
	return true;
}

int tmp = 0;
void outputx() {
	cout << "Case " << tmp << ": ";
}
int n;
void solve() {
	tmp++;
	polygon p(n);
	rep(i, n) {
		int x, y; cin >> x >> y;
		p[i] = { (ld)x,(ld)y };
	}
	ld ans = 0;
	rep(i, n)Rep(j, i + 1, n) {
		Line l = { p[i],p[j] };
		if (!edge_in_polygon(p, l))continue;
		vector<ld> ts;
		rep(k, n) {
			int nk = k + 1 == n ? 0 : k + 1;
			if (isis_ll(l, { p[k],p[nk] })&&isis_ls(l, { p[k],p[nk] })) {
				Point pp = is_ll(l, { p[k], p[nk] });
				//cout << "? " << pp << "\n";
				ld val = abs(pp - p[i]) / abs(p[j] - p[i]);
				if (ccw(p[i], p[j], pp) == 2)val *= -1;
				ts.push_back(val);
			}
		}
		sort(all(ts));
		Point cl = p[i], cr = p[j];
		rep(k, ts.size()) {
			if (ts[k] < 1 + eps)continue;
			Point z = p[i] + (p[j] - p[i]) * ts[k];
			Point mid = (cr + z); mid /= 2;
			if (is_in_polygon(p, mid)==2) {
				break;
			}
			cr = z;
		}
		per(k, ts.size()) {
			if (ts[k] > -eps)continue;
			Point z = p[i] + (p[j] - p[i]) * ts[k];
			Point mid = (cl + z); mid /= 2;
			if (is_in_polygon(p, mid)==2) {
				break;
			}
			cl=z;
		}
		//cout << cl << " " << cr << "\n";
		chmax(ans, abs(cl - cr));
	}
	outputx();
	cout << ans << "\n";
}


signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout << fixed << setprecision(10);
	//init_f();
	//init();
	//while(true)
	//expr();
	//int t; cin >> t; rep(i, t)
	while(cin>>n,n)
	solve();
	return 0;
}
accuracy: 1
time_ms: 890
memory_kb: 3600
final_rank: 20

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 1000000000000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;



#define SIZE 10005

struct Point{
	Point(double arg_x,double arg_y){
		x = arg_x;
		y = arg_y;
	}

	Point(){
		x = y = 0.0;
	}

	Point operator + (Point p){ return Point(x+p.x,y+p.y); }
	Point operator - (Point p){ return Point(x-p.x,y-p.y);}
	Point operator * (double a){ return Point(a*x,a*y); }
	Point operator / (double a){ return Point(x/a,y/a); }

	double abs(){ return sqrt(norm()); }
	double norm(){ return x*x + y*y; }

	bool operator<(const Point &p) const{
		return x != p.x? x < p.x: y < p.y;
	}

	bool operator == (const Point &p) const{
		return fabs(x-p.x) < EPS && fabs(y-p.y) < EPS;
	}

	void debug(){

		printf("(%.3lf,%.3lf)\n",x,y);
	}

	double x,y;
};

typedef Point Vector;
typedef vector<Point> Polygon;

struct Line{
	Line(){

	}
	Line(Point a,Point b){
		p[0] = a;
		p[1] = b;
	}
	void outPut(){

		printf("(%.3lf,%.3lf)-(%.3lf,%.3lf)\n",p[0].x,p[0].y,p[1].x,p[1].y);
	}
	Point p[2];
};


int N;
int num_case = 1;
Polygon P;
double NUM = 200000;

double calc_dist(Point A,Point B){

	return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));
}

double norm(Vector a){
	return a.x*a.x+a.y*a.y;
}

double abs(Vector a){
	return sqrt(norm(a));
}

double cross(Vector a,Vector b){
    return a.x*b.y-a.y*b.x;
}

double dot(Vector a,Vector b){
    return a.x*b.x + a.y*b.y;
}


int func(double x1,double y1,double x2, double y2, double xp, double yp){
	double naiseki,norm1,norm2,gaiseki;
	norm1 = sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
	norm2 = sqrt((xp-x1)*(xp-x1)+(yp-y1)*(yp-y1));
	naiseki = (xp-x1)*(x2-x1)+(yp-y1)*(y2-y1);
	gaiseki = (x2-x1)*(yp-y1)-(xp-x1)*(y2-y1);
	if(gaiseki > EPS){
		return 1;
	}else if(gaiseki < -EPS){
		return -1;
	}
	if(naiseki < -EPS){
		return 2;
	}

	if(norm1 < norm2){
		return -2;
	}
	return 0;
}


//★★直線ではなく、線分の交差判定★★
bool is_Cross(Line a,Line b){

	if(func(a.p[0].x,a.p[0].y,a.p[1].x,a.p[1].y,b.p[0].x,b.p[0].y)*
			func(a.p[0].x,a.p[0].y,a.p[1].x,a.p[1].y,b.p[1].x,b.p[1].y) <= 0 &&
			func(b.p[0].x,b.p[0].y,b.p[1].x,b.p[1].y,a.p[0].x,a.p[0].y)*
			func(b.p[0].x,b.p[0].y,b.p[1].x,b.p[1].y,a.p[1].x,a.p[1].y) <= 0){
		return true;
	}
	return false;
}

double calc_slope(Line A){

	if(fabs(A.p[0].x-A.p[1].x) < EPS){

		return DBL_MAX;

	}else if(fabs(A.p[0].y-A.p[1].y) < EPS){

		return 0;

	}else{

		return (A.p[1].y-A.p[0].y)/(A.p[1].x-A.p[0].x);
	}
}

Point calc_minus(Point a,Point b){
    Point ret;

    ret.x = a.x-b.x;
    ret.y = a.y-b.y;

    return ret;
}

double calc_len(Vector a){
    return sqrt(a.x*a.x+a.y*a.y);
}
//線分ではなく直線と点の距離
double getDistanceLP(Line l,Point p){
    return fabs(cross(calc_minus(l.p[1],l.p[0]),calc_minus(p,l.p[0]))/calc_len(calc_minus(l.p[1],l.p[0])));
}

//点と線分の距離
double getDistanceSP(Line l,Point p){
	if(dot(calc_minus(l.p[1],l.p[0]),calc_minus(p,l.p[0])) < 0.0)return calc_len(calc_minus(p,l.p[0]));
	if(dot(calc_minus(l.p[0],l.p[1]),calc_minus(p,l.p[1])) < 0.0)return calc_len(calc_minus(p,l.p[1]));
	return getDistanceLP(l,p);
}

//線分と線分の距離
double getDistance(Line A,Line B){
	if(is_Cross(A,B))return 0.0;
	return min(min(getDistanceSP(A,B.p[0]),getDistanceSP(A,B.p[1])),
			min(getDistanceSP(B,A.p[0]),getDistanceSP(B,A.p[1])));
}

static const int COUNTER_CLOCKWISE = 1;
static const int CLOCKWISE = -1;
static const int ONLINE_BACK = 2;
static const int ONLINE_FRONT = -2;
static const int ON_SEGMENT = 0;

int ccw(Point p0,Point p1,Point p2){

	Vector a = p1 - p0;
	Vector b = p2 - p0;

	if(cross(a,b) > EPS)return COUNTER_CLOCKWISE;
	if(cross(a,b) < -EPS)return CLOCKWISE;
	if(dot(a,b) < -EPS)return ONLINE_BACK;
	if(a.norm() < b.norm())return ONLINE_FRONT;

	return ON_SEGMENT;
}

//交点を求める関数
Point calc_Cross_Point(double x1,double x2,double x3,double x4,double y1,double y2,double y3,double y4){
	Point ret;
	ret.x = ((x2-x1)*(y3*(x4-x3)+x3*(y3-y4))-(x4-x3)*(y1*(x2-x1)+x1*(y1-y2)))/((y2-y1)*(x4-x3)-(y4-y3)*(x2-x1));
	if(fabs(x1-x2) > EPS){
		ret.y = ((y2-y1)*ret.x+y1*(x2-x1)+x1*(y1-y2))/(x2-x1);
	}else{
		ret.y = ((y4-y3)*ret.x+y3*(x4-x3)+x3*(y3-y4))/(x4-x3);
	}
	return ret;
}

//インタフェース関数
Point calc_Cross_Point(Point a,Point b,Point c,Point d){
	return calc_Cross_Point(a.x,b.x,c.x,d.x,a.y,b.y,c.y,d.y);
}

Point calc_Cross_Point(Line A,Line B){

	if(getDistanceSP(B,A.p[0]) < EPS){

		return A.p[0];

	}else if(getDistanceSP(B,A.p[1]) < EPS){

		return A.p[1];

	}else if(getDistanceSP(A,B.p[0]) < EPS){

		return B.p[0];

	}else if(getDistanceSP(A,B.p[1]) < EPS){

		return B.p[1];
	}

	return calc_Cross_Point(A.p[0],A.p[1],B.p[0],B.p[1]);
}

bool isSame(Point a,Point b){

	return abs(a-b) < EPS;
}

/*
 * IN 2
 * ON 1
 * OUT 0
 *
 */
int contains(Polygon g,Point p){
	int n = g.size();
	bool x = false;
	for(int i = 0; i < n; i++){
		Point a = g[i]-p,b = g[(i+1)%n]-p;
		if(abs(cross(a,b)) < EPS && dot(a,b) < EPS)return 1;
		if(a.y > b.y)swap(a,b);
		if(a.y < EPS && EPS < b.y && cross(a,b) > EPS) x = !x;
	}
	return (x ? 2:0);
}


void func(){

	P.clear();

	double x,y;

	for(int i = 0; i < N; i++){

		scanf("%lf %lf",&x,&y);
		P.push_back(Point(x,y));
	}

	Line bottom,proj_line,calc_line;
	vector<Line> L;


	for(int i = 0; i < N; i++){
		for(int k = i+1; k < N; k++){
			if(k == i)continue;

			L.push_back(Line(P[i],P[k]));
		}
	}

	Vector vec_next,vec_pre;

	double ans = 0;

	Line tmp_line,work_line;
	Point cross_point,base_p;

	vector<Point>  V;

	for(int i = 0; i < L.size(); i++){
		V.clear();

		double slope = calc_slope(L[i]);

		//両方向に直線を伸ばす

		if(fabs(slope-DBL_MAX) < EPS){ //垂直

			work_line = Line(Point(L[i].p[0].x,-NUM),Point(L[i].p[0].x,NUM));

		}else if(fabs(slope) < EPS){ //水平

			work_line = Line(Point(-NUM,L[i].p[0].y),Point(NUM,L[i].p[0].y));

		}else{

			if(L[i].p[0].x > L[i].p[1].x){

				work_line.p[0] = Point(L[i].p[0].x+NUM,L[i].p[0].y+NUM*slope);
				work_line.p[1] = Point(L[i].p[1].x-NUM,L[i].p[1].y-NUM*slope);

			}else{

				work_line.p[0] = Point(L[i].p[1].x+NUM,L[i].p[1].y+NUM*slope);
				work_line.p[1] = Point(L[i].p[0].x-NUM,L[i].p[0].y-NUM*slope);
			}
		}

		V.clear();

		for(int k = 0; k < N; k++){

			tmp_line.p[0] = P[k];
			tmp_line.p[1] = P[(k+1)%N];

			if(!is_Cross(tmp_line,work_line))continue;

			V.push_back(calc_Cross_Point(work_line,tmp_line));
		}

		V.push_back(Point(BIG_NUM,BIG_NUM));

		sort(V.begin(),V.end());
		V.erase(unique(V.begin(),V.end()),V.end());

		double tmp = 0;
		for(int k = 0; k < V.size()-1; k++){

			if(contains(P,(V[k]+V[k+1])/2) != 0){

				tmp += calc_dist(V[k],V[k+1]);
			}else{
				ans = max(ans,tmp);
				tmp = 0;
			}
		}
	}

	printf("Case %d: %.10lf\n",num_case,ans);

	num_case++;
}

int main(){

	while(true){

		scanf("%d",&N);
		if(N == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 140
memory_kb: 3372
final_rank: 14

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 1000000000000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;



#define SIZE 10005

struct Point{
	Point(double arg_x,double arg_y){
		x = arg_x;
		y = arg_y;
	}

	Point(){
		x = y = 0.0;
	}

	Point operator + (Point p){ return Point(x+p.x,y+p.y); }
	Point operator - (Point p){ return Point(x-p.x,y-p.y);}
	Point operator * (double a){ return Point(a*x,a*y); }
	Point operator / (double a){ return Point(x/a,y/a); }

	double abs(){ return sqrt(norm()); }
	double norm(){ return x*x + y*y; }

	bool operator<(const Point &p) const{
		return x != p.x? x < p.x: y < p.y;
	}

	bool operator == (const Point &p) const{
		return fabs(x-p.x) < EPS && fabs(y-p.y) < EPS;
	}

	void debug(){

		printf("(%.3lf,%.3lf)\n",x,y);
	}

	double x,y;
};

typedef Point Vector;
typedef vector<Point> Polygon;

struct Line{
	Line(){

	}
	Line(Point a,Point b){
		p[0] = a;
		p[1] = b;
	}
	void outPut(){

		printf("(%.3lf,%.3lf)-(%.3lf,%.3lf)\n",p[0].x,p[0].y,p[1].x,p[1].y);
	}
	Point p[2];
};

struct Info{

	Info(Point arg_tmp_p,double arg_dist){

		tmp_p = arg_tmp_p;
		dist = arg_dist;
	}
	bool operator<(const struct Info &arg) const{

		return dist < arg.dist;
	}

	Point tmp_p;
	double dist;
};

int N;
int num_case = 1;
Polygon P;
double NUM = 200000;

double calc_dist(Point A,Point B){

	return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));
}

double norm(Vector a){
	return a.x*a.x+a.y*a.y;
}

double abs(Vector a){
	return sqrt(norm(a));
}

double cross(Vector a,Vector b){
    return a.x*b.y-a.y*b.x;
}

double dot(Vector a,Vector b){
    return a.x*b.x + a.y*b.y;
}


int func(double x1,double y1,double x2, double y2, double xp, double yp){
	double naiseki,norm1,norm2,gaiseki;
	norm1 = sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
	norm2 = sqrt((xp-x1)*(xp-x1)+(yp-y1)*(yp-y1));
	naiseki = (xp-x1)*(x2-x1)+(yp-y1)*(y2-y1);
	gaiseki = (x2-x1)*(yp-y1)-(xp-x1)*(y2-y1);
	if(gaiseki > EPS){
		return 1;
	}else if(gaiseki < -EPS){
		return -1;
	}
	if(naiseki < -EPS){
		return 2;
	}

	if(norm1 < norm2){
		return -2;
	}
	return 0;
}


//★★直線ではなく、線分の交差判定★★
bool is_Cross(Line a,Line b){

	if(func(a.p[0].x,a.p[0].y,a.p[1].x,a.p[1].y,b.p[0].x,b.p[0].y)*
			func(a.p[0].x,a.p[0].y,a.p[1].x,a.p[1].y,b.p[1].x,b.p[1].y) <= 0 &&
			func(b.p[0].x,b.p[0].y,b.p[1].x,b.p[1].y,a.p[0].x,a.p[0].y)*
			func(b.p[0].x,b.p[0].y,b.p[1].x,b.p[1].y,a.p[1].x,a.p[1].y) <= 0){
		return true;
	}
	return false;
}

double calc_slope(Line A){

	if(fabs(A.p[0].x-A.p[1].x) < EPS){

		return DBL_MAX;

	}else if(fabs(A.p[0].y-A.p[1].y) < EPS){

		return 0;

	}else{

		return (A.p[1].y-A.p[0].y)/(A.p[1].x-A.p[0].x);
	}
}

Point project(Line l,Point p){

	Vector base = l.p[1]-l.p[0];
	double r = dot(p-l.p[0],base)/norm(base);
	return l.p[0]+base*r;
}

Point calc_minus(Point a,Point b){
    Point ret;

    ret.x = a.x-b.x;
    ret.y = a.y-b.y;

    return ret;
}

double calc_len(Vector a){
    return sqrt(a.x*a.x+a.y*a.y);
}
//線分ではなく直線と点の距離
double getDistanceLP(Line l,Point p){
    return fabs(cross(calc_minus(l.p[1],l.p[0]),calc_minus(p,l.p[0]))/calc_len(calc_minus(l.p[1],l.p[0])));
}

//点と線分の距離
double getDistanceSP(Line l,Point p){
	if(dot(calc_minus(l.p[1],l.p[0]),calc_minus(p,l.p[0])) < 0.0)return calc_len(calc_minus(p,l.p[0]));
	if(dot(calc_minus(l.p[0],l.p[1]),calc_minus(p,l.p[1])) < 0.0)return calc_len(calc_minus(p,l.p[1]));
	return getDistanceLP(l,p);
}

//線分と線分の距離
double getDistance(Line A,Line B){
	if(is_Cross(A,B))return 0.0;
	return min(min(getDistanceSP(A,B.p[0]),getDistanceSP(A,B.p[1])),
			min(getDistanceSP(B,A.p[0]),getDistanceSP(B,A.p[1])));
}

static const int COUNTER_CLOCKWISE = 1;
static const int CLOCKWISE = -1;
static const int ONLINE_BACK = 2;
static const int ONLINE_FRONT = -2;
static const int ON_SEGMENT = 0;

int ccw(Point p0,Point p1,Point p2){

	Vector a = p1 - p0;
	Vector b = p2 - p0;

	if(cross(a,b) > EPS)return COUNTER_CLOCKWISE;
	if(cross(a,b) < -EPS)return CLOCKWISE;
	if(dot(a,b) < -EPS)return ONLINE_BACK;
	if(a.norm() < b.norm())return ONLINE_FRONT;

	return ON_SEGMENT;
}

//交点を求める関数
Point calc_Cross_Point(double x1,double x2,double x3,double x4,double y1,double y2,double y3,double y4){
	Point ret;
	ret.x = ((x2-x1)*(y3*(x4-x3)+x3*(y3-y4))-(x4-x3)*(y1*(x2-x1)+x1*(y1-y2)))/((y2-y1)*(x4-x3)-(y4-y3)*(x2-x1));
	if(fabs(x1-x2) > EPS){
		ret.y = ((y2-y1)*ret.x+y1*(x2-x1)+x1*(y1-y2))/(x2-x1);
	}else{
		ret.y = ((y4-y3)*ret.x+y3*(x4-x3)+x3*(y3-y4))/(x4-x3);
	}
	return ret;
}

//インタフェース関数
Point calc_Cross_Point(Point a,Point b,Point c,Point d){
	return calc_Cross_Point(a.x,b.x,c.x,d.x,a.y,b.y,c.y,d.y);
}

Point calc_Cross_Point(Line A,Line B){

	if(getDistanceSP(B,A.p[0]) < EPS){

		return A.p[0];

	}else if(getDistanceSP(B,A.p[1]) < EPS){

		return A.p[1];

	}else if(getDistanceSP(A,B.p[0]) < EPS){

		return B.p[0];

	}else if(getDistanceSP(A,B.p[1]) < EPS){

		return B.p[1];
	}

	return calc_Cross_Point(A.p[0],A.p[1],B.p[0],B.p[1]);
}

bool isSame(Point a,Point b){

	return abs(a-b) < EPS;
}

/*
 * IN 2
 * ON 1
 * OUT 0
 *
 */
int contains(Polygon g,Point p){
	int n = g.size();
	bool x = false;
	for(int i = 0; i < n; i++){
		Point a = g[i]-p,b = g[(i+1)%n]-p;
		if(abs(cross(a,b)) < EPS && dot(a,b) < EPS)return 1;
		if(a.y > b.y)swap(a,b);
		if(a.y < EPS && EPS < b.y && cross(a,b) > EPS) x = !x;
	}
	return (x ? 2:0);
}


void func(){

	P.clear();

	double x,y;

	for(int i = 0; i < N; i++){

		scanf("%lf %lf",&x,&y);
		P.push_back(Point(x,y));
	}

	Line bottom,proj_line,calc_line;
	vector<Line> L;


	for(int i = 0; i < N; i++){
		for(int k = i+1; k < N; k++){
			if(k == i)continue;

			L.push_back(Line(P[i],P[k]));
		}

		for(int k = 0; k < N; k++){

			if(k == i || (k+1)%N == i)continue;
			bottom.p[0] = P[k];
			bottom.p[1] = P[(k+1)%N];

			Point proj_p = project(bottom,P[i]);
			proj_line.p[0] = P[i];
			proj_line.p[1] = proj_p;

			if(!is_Cross(bottom,proj_line))continue;

			Point tmp_cross_p = calc_Cross_Point(proj_line,bottom);

			L.push_back(Line(P[i],tmp_cross_p));
		}
	}

	Vector vec_next,vec_pre;

	double ans = 0;

	Line tmp_line,work_line;
	Point cross_point,base_p;

	vector<Point>  V;

	for(int i = 0; i < L.size(); i++){
		V.clear();

		double slope = calc_slope(L[i]);

		//両方向に直線を伸ばす

		if(fabs(slope-DBL_MAX) < EPS){ //垂直

			work_line = Line(Point(L[i].p[0].x,-NUM),Point(L[i].p[0].x,NUM));

		}else if(fabs(slope) < EPS){ //水平

			work_line = Line(Point(-NUM,L[i].p[0].y),Point(NUM,L[i].p[0].y));

		}else{

			if(L[i].p[0].x > L[i].p[1].x){

				work_line.p[0] = Point(L[i].p[0].x+NUM,L[i].p[0].y+NUM*slope);
				work_line.p[1] = Point(L[i].p[1].x-NUM,L[i].p[1].y-NUM*slope);

			}else{

				work_line.p[0] = Point(L[i].p[1].x+NUM,L[i].p[1].y+NUM*slope);
				work_line.p[1] = Point(L[i].p[0].x-NUM,L[i].p[0].y-NUM*slope);
			}
		}

		V.clear();

		for(int k = 0; k < N; k++){

			tmp_line.p[0] = P[k];
			tmp_line.p[1] = P[(k+1)%N];

			if(!is_Cross(tmp_line,work_line))continue;

			V.push_back(calc_Cross_Point(work_line,tmp_line));
		}

		V.push_back(Point(BIG_NUM,BIG_NUM));

		sort(V.begin(),V.end());
		V.erase(unique(V.begin(),V.end()),V.end());

		double tmp = 0;
		for(int k = 0; k < V.size()-1; k++){

			if(contains(P,(V[k]+V[k+1])/2) != 0){

				tmp += calc_dist(V[k],V[k+1]);
			}else{
				ans = max(ans,tmp);
				tmp = 0;
			}
		}
	}

	printf("Case %d: %.10lf\n",num_case,ans);

	num_case++;
}

int main(){

	while(true){

		scanf("%d",&N);
		if(N == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 190
memory_kb: 3432
final_rank: 15

code_snippet: #include <iostream>
#include <iomanip>
#include <complex>
#include <vector>
#include <algorithm>
#include <cmath>
#include <array>
using namespace std;
const double EPS = 1e-10;
const double INF = 1e12;
const double PI = acos(-1);
#define EQ(n,m) (abs((n)-(m)) < EPS)
#define X real()
#define Y imag()

typedef complex<double> P;
typedef vector<P> VP;
struct L : array<P, 2>{
    L(const P& a, const P& b){ at(0)=a; at(1)=b; }
    L(){}
};

namespace std{
    bool operator < (const P& a, const P& b){
        return !EQ(a.X,b.X) ? a.X<b.X : a.Y+EPS<b.Y;
    }
    bool operator == (const P& a, const P& b){
        return abs(a-b) < EPS;
    }
}

double dot(P a, P b){
    return (conj(a)*b).X;
}
double cross(P a, P b){
    return (conj(a)*b).Y;
}
int ccw(P a, P b, P c){
    b -= a;
    c -= a;
    if(cross(b,c) > EPS) return +1; //ccw
    if(cross(b,c) < -EPS) return -1; //cw
    if(dot(b,c) < -EPS) return +2; //c-a-b
    if(abs(c)-abs(b) > EPS) return -2; //a-b-c
    return 0; //a-c-b
}

P projection(const L& l, const P& p) {
    double t = dot(p-l[0], l[0]-l[1]) / norm(l[0]-l[1]);
    return l[0] + t*(l[0]-l[1]);
}
double distanceLP(const L &l, const P &p) {
    return abs(cross(l[1]-l[0], p-l[0])) /abs(l[1]-l[0]);
}

bool intersectLS(const L& l, const L& s){
    return cross(l[1]-l[0], s[0]-l[0])*
        cross(l[1]-l[0], s[1]-l[0]) < EPS;
}
bool intersectSP(const L& s, const P &p){
    return abs(cross(s[0]-p, s[1]-p))<EPS  && dot(s[0]-p, s[1]-p)<EPS;
}

bool isParallel(const P &a, const P &b){
    return abs(cross(a,b)) < EPS;
}
bool isParallel(const L &a, const L &b){
    return isParallel(a[1]-a[0], b[1]-b[0]);
}

P crosspointLL(const L &l, const L &m) {
  double A = cross(l[1]-l[0], m[1]-m[0]);
  double B = cross(l[1]-l[0], l[1]-m[0]);
  return m[0] + B/A *(m[1]-m[0]);
}

int in_poly(const P &p, const VP &poly){
    int n = poly.size();
    int ret = -1;
    for(int i=0; i<n; i++){
        P a = poly[i]-p;
        P b = poly[(i+1)%n]-p;
        if(a.Y > b.Y) swap(a,b);
        if(intersectSP(L(a,b), P(0,0))) return 0;
        if(a.Y<=0 && b.Y>0 && cross(a,b)<0) ret = -ret;
    }
    return ret;
}
double getarea(const VP &poly){
    int n = poly.size();
    double ret = 0;
    for (int i=0; i<n; i++){ 
        ret += cross(poly[i], poly[(i+1)%n]);
    }
    return ret*0.5;
}

double solve(const VP& poly){
    int n = poly.size();
    double ret = 0;
    vector<L> cand;
    for(int i=0; i<n; i++){
        for(int j=i+1; j<n; j++){
            cand.emplace_back(poly[i], poly[j]);
        }
        for(int j=0; j<n; j++){
            L edge(poly[j], poly[(j+1)%n]);
            if(distanceLP(edge, poly[i]) > EPS){
                cand.emplace_back(poly[i], projection(edge, poly[i]));
            }
        }
    }

    for(L &line: cand){
        VP plist;
        for(int k=0; k<n; k++){
            L edge(poly[k], poly[(k+1)%n]);
            if(!isParallel(line, edge) && intersectLS(line, edge)){
                plist.push_back(crosspointLL(line, edge));
            }
        }
        sort(plist.begin(), plist.end());
        plist.erase(unique(plist.begin(), plist.end()), plist.end());
        
        plist.emplace_back(INF, 0);
        double range = 0;
        for(int i=0; i<(int)plist.size()-1; i++){
            if(in_poly((plist[i] +plist[i+1]) /2.0, poly) >= 0){
                range += abs(plist[i+1] -plist[i]);
            }else{
                ret = max(ret, range);
                range = 0;
            }
        }
    }
    return ret;
}

int main(){
    int dn=0;
    while(1){
        dn++;
        int n;
        cin >> n;
        if(n == 0) break;

        VP p(n);
        for(int i=0; i<n; i++){
            double x,y;
            cin >> x >> y;
            p[i] = P(x, y);
        }
        cout << fixed << setprecision(10);
        cout << "Case " << dn << ": " << solve(p) << endl;
        
    }
    return 0;
}
accuracy: 1
time_ms: 380
memory_kb: 4048
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;

using ld = long double;
const ld eps = 1e-10, pi = acos(-1.0);

bool eq(ld a, ld b) {
	return abs(a - b) < eps;
}

using Point = complex<ld>;
class Line {
public:
	Point a, b;
};
ld dot(Point a, Point b) {
	return real(conj(a) * b);
}

ld cross(Point a, Point b) {
	return imag(conj(a) * b);
}

int ccw(Point a, Point b, Point c) {
	b -= a, c -= a;
	if (cross(b, c) > eps) return 1;	// a,b,c counter-clockwise
	if (cross(b, c) < -eps) return -1;	// a,b,c clockwise
	if (dot(b, c) < 0) return 2;		// c,a,b on a line
	if (norm(b) < norm(c)) return -2;	// a,b,c on a line
	return 0;							// a,c,b on a line
}

bool isis_ll(Line l, Line m) {
	return abs(cross(l.b - l.a, m.b - m.a)) > eps;
}

bool isis_ls(Line l, Line s) {
	return (cross(l.b - l.a, s.a - l.a) * cross(l.b - l.a, s.b - l.a) < eps);
}

bool isis_lp(Line l, Point p) {
	return abs(cross(l.b - p, l.a - p)) < eps;
}

bool isis_sp(Line s, Point p) {
	return abs(s.a - p) + abs(s.b - p) - abs(s.b - s.a) < eps;
}

Point proj(Line l, Point p) {
	ld t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
	return l.a + t * (l.a - l.b);
}

Point is_ll(Line s, Line t) {
	Point sv = s.b - s.a, tv = t.b - t.a;
	assert(cross(sv, tv) != 0);
	return s.a + sv * cross(tv, t.a - s.a) / cross(tv, sv);
}

bool isis_ss(Line s, Line t) {
	if (isis_ll(s, t)) return isis_ls(s, t) && isis_ls(t, s);
	return isis_sp(s, t.a) || isis_sp(s, t.b) || isis_sp(t, s.a);
}

ld dist_lp(Line l, Point p) {
	return abs(p - proj(l, p));
}

ld dist_ll(Line l, Line m) {
	return isis_ll(l, m) ? 0 : dist_lp(l, m.a);
}

ld dist_ls(Line l, Line s) {
	return isis_ls(l, s) ? 0 : min(dist_lp(l, s.a), dist_lp(l, s.b));
}

ld dist_sp(Line s, Point p) {
	Point r = proj(s, p);
	return isis_sp(s, r) ? abs(r - p) : min(abs(s.a - p), abs(s.b - p));
}

ld dist_ss(Line s, Line t) {
	if (isis_ss(s, t)) return 0;
	return min({ dist_sp(s, t.a), dist_sp(s, t.b), dist_sp(t, s.a), dist_sp(t, s.b) });
}

bool is_in_polygon(const vector<Point>& poly, const Point& p) {
	int n = poly.size();
	ld sum = 0;
	for (int i = 0; i < n; ++i) {
		Point p1 = poly[i], p2 = poly[(i + 1) % n];
		if (isis_sp((Line) { p1, p2 }, p)) return true;
		sum += arg((p2 - p) / (p1 - p));
	}
	return abs(sum) > pi;
}

ld calc(const Line& l, const vector<Point>& ps) {
	int n = ps.size();
	Point v = l.b - l.a;
	assert(abs(v) > eps);
	v /= abs(v);
	vector<ld> pos = { 0, abs(l.b - l.a) };
	for (int i = 0; i < n; i++) {
		Line s = { ps[i], ps[(i + 1) % n] };
		if (abs(cross(l.b - l.a, s.b - s.a)) > eps && isis_ss(l, s)) {
			auto pp = is_ll(l, s);
			ld x = dot(pp - l.a, v);
			if (0 < x && x < pos[1]) pos.push_back(x);
		}
	}
	sort(pos.begin(), pos.end());
	ld res = 0;
	for (int i = 1; i < (int)pos.size(); i++) {
		if (!is_in_polygon(ps, l.a + v * ((pos[i] + pos[i - 1]) / 2.0))) break;
		res = pos[i];
	}
	return res;
}

int main()
{
	ios::sync_with_stdio(false), cin.tie(0);
	cout << fixed << setprecision(10);
	int n, tcase = 0;
	while (cin >> n, n) {
		vector<Point> ps;
		for (int i = 0; i < n; i++) {
			ld x, y;
			cin >> x >> y;
			ps.emplace_back(x, y);
		}
		ld res = 0;
		for (int i = 0; i < n; i++) {
			for (int j = i + 1; j < n; j++) {
				Line l = { ps[i], ps[j] };
				if (calc(l, ps) < abs(l.a - l.b) - eps) continue;
				Point v = ps[j] - ps[i];
				assert(abs(v) > eps);
				v /= abs(v);
				Point p1 = ps[j] + v * calc((Line) { ps[j], ps[j] + v * (ld)1e5 }, ps);
				Point p2 = ps[i] - v * calc((Line) { ps[i], ps[i] - v * (ld)1e5 }, ps);
				res = max(res, abs(p1 - p2));
			}
		}
		cout << "Case " << ++tcase << ": " << res << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 780
memory_kb: 3324
final_rank: 19

code_snippet: #include <bits/stdc++.h>

using namespace std;

const int SIZE = 210;
const double eps = 1e-15;

typedef long long ll;
typedef long double ld;

typedef complex<ll> P;
typedef complex<ld> Pd;

inline ll dot(P a, P b){
  return (a * conj(b)).real();
}

inline ll cross(P a, P b){
  return (conj(a) * b).imag();
}

int ccw(P a, P b, P c){
  ll res1 = cross(b-a, c-a);
  if(res1 > 0) return 1; //CCW
  if(res1 < 0) return -1; //CW
  if(dot(b-a, c-a) < 0) return -2; //c -> a -> b
  if(dot(a-b, c-b) < 0) return 2; //a -> b -> c
  return 0;
}

bool iscollinear(P a1, P a2, P b1, P b2){
  return abs(cross(a2-a1, b2-b1)) == 0;
}

int isInterSS(P a1, P a2, P b1, P b2){
  if(iscollinear(a1, a2, b1, b2)) return false;
  
  int a = ccw(b1, b2, a1);
  int b = ccw(b1, b2, a2);
  int c = ccw(a1, a2, b1);
  int d = ccw(a1, a2, b2);

  if(a*b <= 0 && c*d < 0) return 1;
  if(a*b <= 0 && c == 0) return -1;
  if(a*b <= 0 && d == 0) return -2;
  return 0;
}

int isInterLS(P a1, P a2, P b1, P b2){
  if(iscollinear(a1, a2, b1, b2)) return false;

  int c = ccw(a1, a2, b1);
  int d = ccw(a1, a2, b2);
  
  if(abs(c) != 1) return -1;
  if(abs(d) != 1) return -2;
  if(c*d < 0) return 1;
  return 0;
}

bool iscontainedPP(int n, P *g, P p){
  bool f = false;
  for(int i=0;i<n;i++){
    P a = g[i] - p, b = g[(i+1)%n] - p;
    if(abs(cross(a,b)) <= 0 && dot(a,b) <= 0) return true;
    if(a.imag() > b.imag()) swap(a,b);
    if(a.imag() <= 0 && 0 < b.imag() && cross(a,b) > 0) f = !f;
  }
  return f;
}

Pd getCrossPoint(P a1, P a2, P b1, P b2){
  P a = a2 - a1;
  P b = b2 - b1;
  Pd ad = Pd(a.real(), a.imag());
  Pd a1d = Pd(a1.real(), a1.imag());
  return a1d + ad * (ld)cross(b, b1-a1) / (ld)cross(b, a);
}

double absll(P a){
  return sqrt(a.real() * a.real() + a.imag() * a.imag());
}

Pd toPd(P a){
  return Pd(a.real(), a.imag());
}

int T = 0;

bool solve(){
  int n;
  int x[SIZE], y[SIZE];
  P p[SIZE];
  Pd pd[SIZE];
  
  if(scanf("%d",&n) == EOF) return false;
  if(n == 0) return false;
  
  printf("Case %d: ",++T);
  
  for(int i=0;i<n;i++){
    scanf("%d%d",x+i, y+i);
    p[i] = P(x[i], y[i]);
    pd[i] = Pd(x[i], y[i]);
  }

  bool inS[SIZE][SIZE][2][2] = {}; // [a][b][{a:0,b:1}][{0:in,1:out}]
  
  for(int i=0;i<n;i++){
    for(int j=0;j<n;j++){
      if(i == j) continue;
      
      P a = p[(i-1+n)%n];
      P b = p[i];
      P c = p[(i+1)%n];
      P d = p[j];

      int r1 = ccw(b, a, c);
      int r2 = ccw(b, a, d);
      int r3 = ccw(b, d, c);
      
      inS[i][j][0][0] = (r2 == 2 || r2 == 0 || r3 == 2 || r3 == 0); // online
      inS[i][j][0][0] |= (r1 == 1 && (r2 * r3 == -1 || r2 == -2 || r3 == -2));
      inS[i][j][0][0] |= (r2 == -1 && r3 == -1);

      //cerr << i << " " << j << " : " << inS[i][j][0][0] << " " << inS[i][j][0][1] << endl;
      //cerr << r1 << " " << r2 << " " << r3 << endl;
      
      d = b * 2LL - d;
      r2 = ccw(b, a, d);
      r3 = ccw(b, d, c);
      
      inS[i][j][0][1] = (r2 == 2 || r2 == 0 || r3 == 2 || r3 == 0); // online
      inS[i][j][0][1] |= (r1 == 1 && (r2 * r3 == -1 || r2 == -2 || r3 == -2));
      inS[i][j][0][1] |= (r2 == -1 && r3 == -1);

      inS[j][i][1][0] = inS[i][j][0][0];
      inS[j][i][1][1] = inS[i][j][0][1];

      //cerr << i << " " << j << " : " << inS[i][j][0][0] << " " << inS[i][j][0][1] << endl;
      //cerr << r1 << " " << r2 << " " << r3 << endl;
    }
  }

  double ans = 0;

  for(int i=0;i<n;i++){
    ans = max(ans, absll(p[i] - p[(i+1)%n]));
  }
  
  for(int i=0;i<n;i++){
    for(int j=i+1;j<n;j++){
      bool f = true;

      if (i+1 != j){
        for(int k=0;k<n;k++){
          if(k == i || (k+1)%n == i || k == j || (k+1)%n == j) continue;

          int resISS = isInterSS(p[i], p[j], p[k], p[(k+1)%n]);
          
          if(resISS == 1 ||
             (resISS == -1 && (!inS[i][k][1][1] || !inS[i][k][1][0])) ||
             (resISS == -2 && (!inS[i][(k+1)%n][1][1] || !inS[i][(k+1)%n][1][0]))){
            f = false;
            break;
          }

        }
        if (!f) continue;
      }
      
      Pd cp1, cp2;
      bool cp1f = false, cp2f = false;
      
      for(int k=0;k<n;k++){
        if(k == i || (k+1)%n == i || k == j || (k+1)%n == j) continue;
        
        int resILS = isInterLS(p[i], p[j], p[k], p[(k+1)%n]);
        Pd cp = getCrossPoint(p[i], p[j], p[k], p[(k+1)%n]);
        
        if(resILS){
          bool near1 = false;
          bool near2 = false;
          
          if(abs(pd[i] - cp) < abs(pd[j] - cp)){
            if (!cp1f || abs(pd[i] - cp) < abs(pd[i] - cp1)){
              if(resILS == 1 ||
                 (resILS == -1 && !inS[i][k][1][1]) ||
                 (resILS == -2 && !inS[i][(k+1)%n][1][1]))
                near1 = true;
            }
          }else{
            if (!cp2f || abs(pd[j] - cp) < abs(pd[j] - cp2)){
              if(resILS == 1 ||
                 (resILS == -1 && !inS[j][k][1][1]) ||
                 (resILS == -2 && !inS[j][(k+1)%n][1][1]))
                near2 = true;
            }
          }
          
          if(near1){
            cp1 = cp; cp1f = true;
          }
          
          if(near2){
            cp2 = cp; cp2f = true;
          }
        }
      }

      
      if(inS[i][j][0][0]){
        ans = max(ans, absll(p[i] - p[j]));
      } else {
        continue;
      }

      //1
      
      if (cp1f && inS[i][j][0][1]){
        ans = max(ans, (double)abs(pd[j] - cp1));
      }
      
      //2
      if (cp2f && inS[i][j][1][1]) {
        ans = max(ans, (double)abs(cp2 - pd[i]));
        if(cp1f && inS[i][j][0][1])
          ans = max(ans, (double)abs(cp1-cp2));
      }
    }
  }
  
  printf("%.10lf\n",(double)ans);
  
  return true;
}
  

int main(){
  //while(solve());

  for(int i=0;;i++){
    if(!solve()) break;
  }
  return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3372
final_rank: 7

code_snippet: #include <bits/stdc++.h>

using namespace std;

const int SIZE = 210;
const double eps = 1e-10;

typedef complex<double> P;

inline double dot(P a, P b){
  return (a * conj(b)).real();
}

inline double cross(P a, P b){
  return (conj(a) * b).imag();
}

int ccw(P a, P b, P c){
  double res1 = cross(b-a, c-a);
  if(res1 > eps) return 1;
  if(res1 < -eps) return -1;
  if(dot(b-a, c-a) < -eps) return -2;
  if(dot(a-b, c-b) < -eps) return 2;
  return 0;
}

bool iscollinear(P a1, P a2, P b1, P b2){
  return abs(cross(a2-a1, b2-b1)) < eps;
}

int isInterSS(P a1, P a2, P b1, P b2){
  if(iscollinear(a1, a2, b1, b2)) return false;
  
  int a = ccw(b1, b2, a1);
  int b = ccw(b1, b2, a2);
  int c = ccw(a1, a2, b1);
  int d = ccw(a1, a2, b2);

  if(a*b <= 0 && c*d < 0) return 1;
  if(a*b <= 0 && c == 0) return -1;
  if(a*b <= 0 && d == 0) return -2;
  return 0;
}

int isInterLS(P a1, P a2, P b1, P b2){
  if(iscollinear(a1, a2, b1, b2)) return false;

  int c = ccw(a1, a2, b1);
  int d = ccw(a1, a2, b2);
  
  if(c == 0) return -1;
  if(d == 0) return -2;
  if(c*d < 0) return 1;
  return 0;
}

bool iscontainedPP(int n, P *g, P p){
  bool f = false;
  for(int i=0;i<n;i++){
    P a = g[i] -p, b = g[(i+1)%n] - p;
    if(abs(cross(a,b)) < eps && dot(a,b) < eps) return true;
    if(a.imag() > b.imag()) swap(a,b);
    if(a.imag() < eps && eps < b.imag() && cross(a,b) > eps) f = !f;
  }
  return f;
}

P getCrossPoint(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);
}

int T = 0;

bool solve(){
  int n;
  int x[SIZE], y[SIZE];
  P p[SIZE];
  
  if(scanf("%d",&n) == EOF) return false;
  if(n == 0) return false;

  printf("Case %d: ",++T);
  
  for(int i=0;i<n;i++){
    scanf("%d%d",x+i, y+i);
    p[i] = P(x[i], y[i]);
  }

  bool inS[SIZE][SIZE][2][2] = {}; // [a][b][{a:0,b:1}][0:in,1:out}]
  
  for(int i=0;i<n;i++){
    for(int j=i+1;j<n;j++){
      auto dir = (p[j] - p[i]); //i->j
      double e = 1e10;
      if (abs(dir.imag()) > eps) e = min(e, abs(dir.imag()));
      if (abs(dir.real()) > eps) e = min(e, abs(dir.real()));
      dir = dir / e * 1e-7;

      inS[i][j][0][0] = iscontainedPP(n, p, p[i] + dir);
      inS[i][j][0][1] = iscontainedPP(n, p, p[i] - dir);
      inS[i][j][1][0] = iscontainedPP(n, p, p[j] - dir);
      inS[i][j][1][1] = iscontainedPP(n, p, p[j] + dir);
      inS[j][i][0][0] = inS[j][i][1][0];
      inS[j][i][0][1] = inS[j][i][1][1];
      inS[j][i][1][0] = inS[j][i][0][0];
      inS[j][i][1][1] = inS[j][i][0][1];
    }
  }

  double ans = 0;

  for(int i=0;i<n;i++){
    ans = max(ans,abs(p[i] - p[(i+1)%n]));
  }
  
  for(int i=0;i<n;i++){
    for(int j=i+1;j<n;j++){
      bool f = true;

      if (i+1 != j){
        for(int k=0;k<n;k++){
          if(k == i || (k+1)%n == i || k == j || (k+1)%n == j) continue;

          int resISS = isInterSS(p[i], p[j], p[k], p[(k+1)%n]);
          
          if(resISS == 1 ||
             (resISS == -1 && (!inS[i][k][1][1] || !inS[i][k][1][0])) ||
             (resISS == -2 && (!inS[i][(k+1)%n][1][1] || !inS[i][(k+1)%n][1][0]))){
            f = false;
            break;
          }
        }

        if (!f) continue;
      }
      
      P cp1, cp2;
      bool cp1f = false, cp2f = false;
      
      for(int k=0;k<n;k++){
        if(k == i || (k+1)%n == i || k == j || (k+1)%n == j) continue;
        
        int resILS = isInterLS(p[i], p[j], p[k], p[(k+1)%n]);
        P cp = getCrossPoint(p[i], p[j], p[k], p[(k+1)%n]);
        
        if(resILS){
          bool near1 = false;
          bool near2 = false;
          
          if(abs(p[i] - cp) < abs(p[j] - cp)){
            if (!cp1f || abs(p[i] - cp) < abs(p[i] - cp1)){
              if(resILS == 1 ||
                 (resILS == -1 && !inS[i][k][1][1]) ||
                 (resILS == -2 && !inS[i][(k+1)%n][1][1]))
                near1 = true;
            }
          }else{
            if (!cp2f || abs(p[j] - cp) < abs(p[j] - cp2)){
              if(resILS == 1 ||
                 (resILS == -1 && !inS[j][k][1][1]) ||
                 (resILS == -2 && !inS[j][(k+1)%n][1][1]))
                near2 = true;
            }
          }
          
          if(near1){
            cp1 = cp; cp1f = true;
          }
          
          if(near2){
            cp2 = cp; cp2f = true;
          }
        }

        //cerr << i << " " << j << " " << k << " : " << resILS << endl;
      }

      
      if(inS[i][j][0][0]){
        ans = max(ans, abs(p[i] - p[j]));
      } else {
        continue;
      }

      //1
      
      if (cp1f && inS[i][j][0][1]){
        ans = max(ans, abs(p[j] - cp1));
      }
      
      //2
      if (cp2f && inS[i][j][1][1]) {
        ans = max(ans, abs(cp2 - p[i]));
        if(cp1f && inS[i][j][0][1])
          ans = max(ans, abs(cp1-cp2));
      }

      //cerr << i << " " << j << " : " << ans << endl;
    }
  }

  printf("%.10lf\n",ans);
  
  return true;
}
  

int main(){
  //while(solve());

  for(int i=0;;i++){
    if(!solve()) break;
  }
  return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 3404
final_rank: 11

code_snippet: #include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<list>
#include<queue>
#include<stack>
#include<vector>
#include<set>
#include<map>
#include<bitset>
#include<string>
#define sgn(v) (abs((v))<eps?0:((v)<0?-1:1))
#define sqr(v) ((v)*(v))
#define mb make_pair
#define debug 0
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;
typedef pair<int,LL> PIL;
typedef pair<LL,int> PLI;
typedef pair<LL,LL> PLL;
const double eps=1e-8;
const double pi=acos(-1);
const int maxn=101;
struct Point
{
    double x,y;
    Point(){}
    Point(double X,double Y)
    {
        x=X;y=Y;
    }
    bool operator <(const Point &p)const
    {
        if(sgn(x-p.x))return x<p.x;
        else return y<p.y;
    }
    bool operator ==(const Point &p)const
    {
        return sgn(x-p.x)==0&&sgn(y-p.y)==0;
    }
    Point operator -(const Point &p)
    {
        return Point(x-p.x,y-p.y);
    }
    Point operator +(const Point &p)
    {
        return Point(x+p.x,y+p.y);
    }
    double cross(const Point &p)const
    {
        return x*p.y-y*p.x;
    }
    double len()
    {
        return sqrt(sqr(x)+sqr(y));
    }
    void unit()
    {
        double tmp=len();
        x/=tmp;
        y/=tmp;
        x*=0.0001;
        y*=0.0001;
    }
}pt[maxn];
struct Segment
{
    Point st,ed;
};
double cross(const Point &p,const Point &q)
{
    return p.x*q.y-p.y*q.x;
}
double dot(const Point &p,const Point &q)
{
    return p.x*q.x+p.y*q.y;
}
Point Insect(Segment &p,Segment &q)
{
    double u=cross(p.ed-p.st,q.st-p.st),v=cross(p.st-p.ed,q.ed-p.st);
    return Point((q.st.x*v+q.ed.x*u)/(u+v),(q.st.y*v+q.ed.y*u)/(u+v));
}
vector<Point> tp,sp;
int n,cas;
int check(Point P,int deb)
{
    int con=0;
    Segment now,tmp;
    Point cp;
    now.st=P;
    con=0;
    now.ed.x=P.x+19950527;
    now.ed.y=P.y+27051995;
    for(int i=0;i<n;++i)
    {
        tmp.st=pt[i];
        tmp.ed=pt[(i+1)%n];
        if(sgn((tmp.ed-tmp.st).cross(now.ed-now.st)))
        {
            cp=Insect(tmp,now);
            if(cp==tmp.ed||cp==tmp.st)while(1);
            if(sgn(dot(tmp.ed-cp,cp-tmp.st))>0&&sgn(dot(now.ed-cp,cp-now.st))>0)
                ++con;
        }
    }
    return con%2;
}
     
double check(int i,int j)
{
    Segment now,tmp;
    Point cp;
    tp.clear();
    now.st=pt[i];
    now.ed=pt[j];
    for(i=0;i<n;++i)
    {
        tmp.st=pt[i];
        tmp.ed=pt[(i+1)%n];
        if(sgn((tmp.ed-tmp.st).cross(now.ed-now.st)))
        {
            cp=Insect(tmp,now);
            if(sgn(dot(tmp.ed-cp,cp-tmp.st))>0)
                tp.push_back(cp);
            else if(sgn(dot(tmp.ed-cp,cp-tmp.st))==0) // endpoints
            {
                if(cp==tmp.st)j=i;
                else j=i+1;
                if(cross(pt[(j-1+n)%n]-now.st,now.ed-now.st)*cross(pt[(j+1)%n]-now.st,now.ed-now.st)<0)
                    tp.push_back(cp);
            }
        }
        else if(sgn((tmp.st-now.st).cross(now.ed-now.st))==0&&sgn((tmp.ed-now.st).cross(now.ed-now.st))==0)
        {
            Point vec=tmp.ed-tmp.st;
            vec.unit();
            if(cross(pt[(i-1+n)%n]-now.st,now.ed-now.st)*cross(pt[(i+2)%n]-now.st,now.ed-now.st)<0)
            {
                if(!check(tmp.st-vec,0))
                    tp.push_back(tmp.st);
                if(!check(tmp.ed+vec,0))
                    tp.push_back(tmp.ed);
            }
        }
    }
    sort(tp.begin(),tp.end());
    int n=tp.size();
    sp.clear();
    for(i=0;i<n;++i)
        if(i==0||(!(tp[i]==tp[i-1])))sp.push_back(tp[i]);
    double ans=0;
    for(i=0;i<sp.size();i+=2)
        ans=max(ans,(sp[i+1]-sp[i]).len());
    return ans;
}
int main()
{
    int i,j;
    cas=0;
    while(scanf("%d",&n)!=EOF)
    {
        if(n==0)break;
        double len=0;
        for(i=0;i<n;++i)
            scanf("%lf%lf",&pt[i].x,&pt[i].y);
        for(i=0;i<n;++i)
            len=max(len,(pt[i]-pt[(i+1)%n]).len());
        for(i=0;i<n;++i)
            for(j=i+1;j<n;++j)
                len=max(len,check(i,j));
        printf("Case %d: %.10f\n",++cas,len);
        //cout <<len*len<<endl;
    }
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3112
final_rank: 5

code_snippet: #include<bits/stdc++.h>
#define inf 1<<29
#define linf 1e16
#define eps (1e-8)
#define mod 1000000007
#define pi acos(-1)
#define f first
#define s second
#define mp make_pair
#define pb push_back
#define all(a) (a).begin(),(a).end()
#define pd(a) printf("%.10f\n",(double)(a))
#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define RFOR(i,a,b) for(int i=(a)-1;(b)<=i;i--)
#define equals(a,b) (fabs((a)-(b))<eps)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<int,double> pid;
typedef pair<double,int> pdi;
typedef vector<int> vi;
typedef vector<pii> vpi;

class Point{
public:
  double x,y;
  Point(double x=0,double y=0):x(x),y(y){}

  Point operator+(Point p){ return Point(x+p.x,y+p.y);}
  Point operator-(Point p){ return Point(x-p.x,y-p.y);}
  Point operator*(double k){ return Point(x*k,y*k);}
  Point operator/(double k){ return Point(x/k,y/k);}
  bool operator==(Point p)const{ return fabs(x-p.x)<eps && fabs(y-p.y)<eps; }
  bool operator<(Point p)const{ 
    return equals(x,p.x) ? y-p.y<-eps : x-p.x<-eps; }
  double abs(){ return sqrt(norm());}
  double norm(){ return (x*x+y*y);}
};
typedef Point Vector;
typedef vector<Point> Polygon;

class Segment{
public:
  Point p1,p2;
  Segment(Point p1=Point(),Point p2=Point()):p1(p1),p2(p2){}
};
typedef Segment Line;

double norm(Vector a){ return (a.x*a.x+a.y*a.y);}
double abs(Vector a){ return sqrt(norm(a));}
double dot(Vector a,Vector b){ return (a.x*b.x+a.y*b.y);}
double cross(Vector a,Vector b){ return (a.x*b.y-a.y*b.x);}

bool isParallel(Vector a,Vector b){
  return equals(cross(a,b),0.0);
}

bool isParallel(Segment s,Segment t){
  return equals(cross(s.p1-s.p2,t.p1-t.p2),0.0);
}

bool intersect(Line L,Segment s){
  return cross(L.p2-L.p1,s.p1-L.p1)*cross(L.p2-L.p1,s.p2-L.p1)<eps;
}

Point getCrossPointLL(Line a,Line b){
  double A=cross(a.p2-a.p1,b.p2-b.p1);
  double B=cross(a.p2-a.p1,a.p2-b.p1);
  if(abs(A)<eps)return b.p1;
  return b.p1+(b.p2-b.p1)*(B/A);
}

int contains(Polygon g,Point p){
  int n=g.size();
  bool x=false;
  for(int i=0;i<n;i++){
    Vector a=g[i]-p,b=g[(i+1)%n]-p;
    if(abs(cross(a,b))<eps && dot(a,b)<eps)return 1;
    if(a.y>b.y)swap(a,b);
    if(a.y<eps && eps<b.y && cross(a,b)>eps)x=!x;
  }
  if(x)return 2;
  return 0;
}

int n;
Polygon p;

double cal(Line L){
  vector<Point> vp;
  FOR(i,0,n){
    Segment s(p[i],p[(i+1)%n]);
    if(isParallel(L,s))continue;
    if(!intersect(L,s))continue;
    vp.pb(getCrossPointLL(L,s));
  }
  sort(all(vp));
  vp.erase(unique(all(vp)),vp.end());
  double sum=0,res=0;
  FOR(i,0,vp.size()-1){
    Point a=vp[i],b=vp[i+1];
    if(a==b)continue;
    Point m=a+(b-a)/2.0;
    if(contains(p,m)==0)sum=0;
    else { sum+=abs(b-a); res=max(res,sum); }
  }
  return res;
}

double solve(){
  double res=0;
  FOR(i,0,n){
    FOR(j,i+1,n)res=max(res,cal(Line(p[i],p[j])));
  }
  return res;
}

int main()
{
  int c=1;
  while(cin>>n && n){
    p.clear();
    FOR(i,0,n){
      double x,y;
      cin>>x>>y;
      p.pb(Point(x,y));
    }
    cout<<"Case "<<c<<": "; pd(solve());
    c++;
  }
  return 0;
}
accuracy: 1
time_ms: 90
memory_kb: 3124
final_rank: 6

code_snippet: #include<bits/stdc++.h>
#define inf 1<<29
#define linf 1e16
#define eps (1e-8)
#define mod 1000000007
#define pi acos(-1)
#define f first
#define s second
#define mp make_pair
#define pb push_back
#define all(a) (a).begin(),(a).end()
#define pd(a) printf("%.10f\n",(double)(a))
#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define RFOR(i,a,b) for(int i=(a)-1;(b)<=i;i--)
#define equals(a,b) (fabs((a)-(b))<eps)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<int,double> pid;
typedef pair<double,int> pdi;
typedef vector<int> vi;
typedef vector<pii> vpi;
const int dx[8]={1,0,-1,0,1,1,-1,-1};
const int dy[8]={0,1,0,-1,1,-1,1,-1};

class Point{
public:
  double x,y;
  Point(double x=0,double y=0):x(x),y(y){}

  Point operator+(Point p){ return Point(x+p.x,y+p.y);}
  Point operator-(Point p){ return Point(x-p.x,y-p.y);}
  Point operator*(double k){ return Point(x*k,y*k);}
  Point operator/(double k){ return Point(x/k,y/k);}
  bool operator==(Point p)const{ return fabs(x-p.x)<eps && fabs(y-p.y)<eps;}
  bool operator<(Point p)const{ return 
    ( x!=p.x ? x-p.x<eps : y-p.y<eps);}
  double abs(){ return sqrt(norm());}
  double norm(){ return (x*x+y*y);}
};
typedef Point Vector;
typedef vector<Point> Polygon;

class Segment{
public:
  Point p1,p2;
  Segment(Point p1=Point(),Point p2=Point()):p1(p1),p2(p2){}
};
typedef Segment Line;

double norm(Vector a){ return (a.x*a.x+a.y*a.y);}
double abs(Vector a){ return sqrt(norm(a));}
double dot(Vector a,Vector b){ return (a.x*b.x+a.y*b.y);}
double cross(Vector a,Vector b){ return (a.x*b.y-a.y*b.x);}

bool isParallel(Vector a,Vector b){
  return equals(cross(a,b),0.0);
}

bool isParallel(Segment s,Segment t){
  return equals(cross(s.p1-s.p2,t.p1-t.p2),0.0);
}

int ccw(Point p0,Point p1,Point p2){
  Vector a=p1-p0;
  Vector b=p2-p0;
  if(cross(a,b)>eps)return 1;
  if(cross(a,b)<-eps)return -1;
  if(dot(a,b)<-eps)return 2;
  if(a.norm()<b.norm())return -2;
  return 0;
}

bool intersect(Line L,Segment s){
  return ccw(L.p1,L.p2,s.p1) * ccw(L.p1,L.p2,s.p2)<=0;
}

Point getCrossPointLL(Line a,Line b){
  double A=cross(a.p2-a.p1,b.p2-b.p1);
  double B=cross(a.p2-a.p1,a.p2-b.p1);
  if(abs(A)<eps || abs(B)<eps)return b.p1;
  return b.p1+(b.p2-b.p1)*(B/A);
}

int contains(Polygon g,Point p){
  int n=g.size();
  bool x=false;
  for(int i=0;i<n;i++){
    Vector a=g[i]-p,b=g[(i+1)%n]-p;
    if(abs(cross(a,b))<eps && dot(a,b)<eps)return 1;
    if(a.y>b.y)swap(a,b);
    if(a.y<eps && eps<b.y && cross(a,b)>eps)x=!x;
  }
  if(x)return 2;
  return 0;
}

int n;
Polygon p;

double cal(Line L){
  vector<pair<double,Point> > vp;
  Point mdp=getCrossPointLL(L,Line(Point(2000,-2000),Point(-2000,-2000)));
  FOR(i,0,n){
    Segment s(p[i],p[(i+1)%n]);
    if(isParallel(L,s))continue;
    if(!intersect(L,s))continue;
    Point m=getCrossPointLL(L,s);
    vp.pb(mp(abs(mdp-m),m));
  }
  sort(all(vp));
  vp.erase(unique(all(vp)),vp.end());
  double sum=0,res=0;
  FOR(i,0,vp.size()-1){
    Point a=vp[i].s,b=vp[i+1].s;
    Point m=a+(b-a)/4.0;
    if(contains(p,m)==0)sum=0;
    else {
      sum+=abs(b-a);
      res=max(res,sum);
    }
  }
  return res;
}

double solve(){
  double res=0;
  FOR(i,0,n){
    FOR(j,i+1,n)res=max(res,cal(Line(p[i],p[j])));
  }
  return res;
}

int main()
{
  int c=1;
  while(cin>>n && n){
    p.clear();
    FOR(i,0,n){
      double x,y;
      cin>>x>>y;
      p.pb(Point(x,y));
    }
    cout<<"Case "<<c<<": ";
    pd(solve());
    c++;
  }
  return 0;
}
accuracy: 1
time_ms: 100
memory_kb: 3224
final_rank: 9

code_snippet: #include<bits/stdc++.h>
#define inf 1<<29
#define linf 1e16
#define eps (1e-6)
#define mod 1000000007
#define pi acos(-1)
#define f first
#define s second
#define mp make_pair
#define pb push_back
#define all(a) (a).begin(),(a).end()
#define pd(a) printf("%.10f\n",(double)(a))
#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define RFOR(i,a,b) for(int i=(a)-1;(b)<=i;i--)
#define equals(a,b) (fabs((a)-(b))<eps)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<int,double> pid;
typedef pair<double,int> pdi;
typedef vector<int> vi;
typedef vector<pii> vpi;
const int dx[8]={1,0,-1,0,1,1,-1,-1};
const int dy[8]={0,1,0,-1,1,-1,1,-1};

class Point{
public:
  double x,y;
  Point(double x=0,double y=0):x(x),y(y){}

  Point operator+(Point p){ return Point(x+p.x,y+p.y);}
  Point operator-(Point p){ return Point(x-p.x,y-p.y);}
  Point operator*(double k){ return Point(x*k,y*k);}
  Point operator/(double k){ return Point(x/k,y/k);}
  bool operator<(Point p)const{ 
    return (x!=p.x ? x-p.x<-eps : y-p.y<-eps);}
  bool operator==(Point p)const{ 
    return fabs(x-p.x)<eps && fabs(y-p.y)<eps;}

  double abs(){ return sqrt(norm());}
  double norm(){ return (x*x+y*y);}
};
typedef Point Vector;
typedef vector<Point> Polygon;

class Segment{
public:
  Point p1,p2;
  Segment(Point p1=Point(),Point p2=Point()):p1(p1),p2(p2){}
};
typedef Segment Line;

double norm(Vector a){ return (a.x*a.x+a.y*a.y);}
double abs(Vector a){ return sqrt(norm(a));}
double dot(Vector a,Vector b){ return (a.x*b.x+a.y*b.y);}
double cross(Vector a,Vector b){ return (a.x*b.y-a.y*b.x);}

bool isParallel(Vector a,Vector b){
  return equals(cross(a,b),0.0);
}

bool isParallel(Segment s,Segment t){
  return equals(cross(s.p1-s.p2,t.p1-t.p2),0.0);
}

Point getCrossPointLL(Line a,Line b){
  double A=cross(a.p2-a.p1,b.p2-b.p1);
  double B=cross(a.p2-a.p1,a.p2-b.p1);
  if(abs(A)<eps || abs(B)<eps)return b.p1;
  return b.p1+(b.p2-b.p1)*(B/A);
}

int ccw(Point p0,Point p1,Point p2){
  Vector a=p1-p0;
  Vector b=p2-p0;
  if(cross(a,b)>eps)return 1;
  if(cross(a,b)<-eps)return -1;
  if(dot(a,b)<-eps)return 2;
  if(a.norm()<b.norm())return -2;
  return 0;
}

bool intersect(Point p1,Point p2,Point p3,Point p4){
  return (ccw(p1,p2,p3)*ccw(p1,p2,p4)<=0 &&
          ccw(p3,p4,p1)*ccw(p3,p4,p2)<=0);
}

bool intersect(Segment s1,Segment s2){
  return intersect(s1.p1,s1.p2,s2.p1,s2.p2);
}

bool intersectLS(Line l,Segment s){
  if(cross(l.p2-l.p1,s.p1-l.p1)*
     cross(l.p2-l.p1,s.p2-l.p1)<eps)return true;
  return false;
}
 
int contains(Polygon g,Point p){
  int n=g.size();
  bool x=false;
  for(int i=0;i<n;i++){
    Vector a=g[i]-p,b=g[(i+1)%n]-p;
    if(abs(cross(a,b))<eps && dot(a,b)<eps)return 1;
    if(a.y>b.y)swap(a,b);
    if(a.y<eps && eps<b.y && cross(a,b)>eps)x=!x;
  }
  if(x)return 2;
  return 0;
}

Polygon convex_hull(Polygon s){
  Polygon g;
  int n=s.size();
  if(n<3)return s;

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

  for(int i=0;i<n;i++){
    for(int n=g.size();n>=2&&ccw(g[n-2],g[n-1],s[i])==1;n--){
      g.pop_back();
    }
    g.push_back(s[i]);
  }
  for(int i=n-2;i>=0;i--){
    for(int n=g.size();n>=2&&ccw(g[n-2],g[n-1],s[i])==1;n--){
      g.pop_back();
    }
    g.push_back(s[i]);
  }
  reverse(g.begin(),g.end());
  g.pop_back();
  return g;
}

vector<Line> getTangent(Polygon a,Polygon b){
  vector<Line> res;
  int n=a.size(),m=b.size();

  FOR(i,0,n){
    FOR(j,0,m){
      int bi=(i+n-1)%n,bj=(j+m-1)%m;
      int ni=(i+1)%n,nj=(j+1)%m;
      if(ccw(a[i],b[j],a[ni])!=-1 && ccw(a[i],b[j],a[bi])!=-1 &&
         ccw(a[i],b[j],b[nj])!=-1 && ccw(a[i],b[j],b[bj])!=-1 ){
        res.pb(Line(a[i],b[j]));
      }
      if(ccw(a[i],b[j],a[ni])!=1 && ccw(a[i],b[j],a[bi])!=1 &&
         ccw(a[i],b[j],b[nj])!=1 && ccw(a[i],b[j],b[bj])!=1){
        res.pb(Line(a[i],b[j]));
      }
      if(ccw(a[i],b[j],a[ni])!=1 && ccw(a[i],b[j],a[bi])!=1 &&
         ccw(a[i],b[j],b[nj])!=-1 && ccw(a[i],b[j],b[bj])!=-1 ){
        res.pb(Line(a[i],b[j]));
      }
      if(ccw(a[i],b[j],a[ni])!=-1 && ccw(a[i],b[j],a[bi])!=-1 &&
         ccw(a[i],b[j],b[nj])!=1 && ccw(a[i],b[j],b[bj])!=1){
        res.pb(Line(a[i],b[j]));
      }
    }
  }
  return res;
}

int n;
Polygon p;

bool check(Segment a){
  if(contains(p,a.p1)==0)return false;
  if(contains(p,a.p2)==0)return false;
  vector<pair<double,Point> > vdp;
  vdp.pb(mp(0,a.p1));
  vdp.pb(mp(abs(a.p1-a.p2),a.p2));
  FOR(i,0,n){
    Segment b(p[i],p[(i+1)%n]);
    if(isParallel(a,b))continue;
    if(!intersect(a,b))continue;
    Point c=getCrossPointLL(a,b);
    vdp.pb(mp(abs(a.p1-c),c));
  }
  sort(all(vdp));
  FOR(i,0,vdp.size()-1){
    Point c=vdp[i].s,d=vdp[i+1].s;
    if(c==d)continue;
    Point m=c+(d-c)/2.0;
    if(contains(p,m)==0)return false;
  }
  return true;
}

double get(Polygon s,Line l){
  vector<Point> vp;
  FOR(i,0,s.size()){
    Point a=s[i],b=s[(i+1)%s.size()];
    if(isParallel(l,Segment(a,b)))continue;
    if(!intersectLS(l,Segment(a,b)))continue;
    Point c=getCrossPointLL(l,Segment(a,b));
    if(!(c==b))vp.pb(c);
  }
  double res=0;
  FOR(i,0,vp.size()){
    FOR(j,i+1,vp.size()){
      if(check(Segment(vp[i],vp[j])))res=max(res,abs(vp[i]-vp[j]));
    }
  }
  return res;
}

double solve(){
  double res=0.0;
  FOR(i,0,n)res=max(res,abs(p[i]-p[(i+1)%n]));

  FOR(i,0,n-2){
    FOR(j,i+2,n){
      if((j+1)%n==i)continue;
      Polygon R,L,s;
      s.pb(p[i]);
      s.pb(p[(i+1)%n]);
      s.pb(p[j]);
      s.pb(p[(j+1)%n]);

      s=convex_hull(s); 

      for(int k=(i+1)%n;k!=(j+1)%n;k=(k+1)%n)
        if(contains(s,p[k])!=0)R.pb(p[k]);
      for(int k=(j+1)%n;k!=(i+1)%n;k=(k+1)%n)
        if(contains(s,p[k])!=0)L.pb(p[k]);
      R=convex_hull(R);
      L=convex_hull(L);
      vector<Line> vs = getTangent(R,L);
      FOR(k,0,R.size()){
        res=max(res,get(s,Segment(R[k],R[(k+1)%R.size()])));
      }
      FOR(k,0,L.size()){
        res=max(res,get(s,Segment(L[k],L[(k+1)%L.size()])));
      }
      FOR(k,0,vs.size()){
        res=max(res,get(s,vs[k]));
      }
    }
  }
  return res;
}

int main()
{
  int c=1;
  while(cin>>n && n){
    p.clear();
    FOR(i,0,n){
      int x,y;
      cin>>x>>y;
      p.pb(Point(x,y));
    }
    cout<<"Case "<<c<<": ";
    pd(solve());
    c++;
  }
  return 0;
}
accuracy: 1
time_ms: 510
memory_kb: 3284
final_rank: 16

code_snippet: #include<bits/stdc++.h>
#define inf 1<<29
#define linf 1e16
#define eps (1e-6)
#define mod 1000000007
#define pi acos(-1)
#define f first
#define s second
#define mp make_pair
#define pb push_back
#define all(a) (a).begin(),(a).end()
#define pd(a) printf("%.10f\n",(double)(a))
#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define RFOR(i,a,b) for(int i=(a)-1;(b)<=i;i--)
#define equals(a,b) (fabs((a)-(b))<eps)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<int,double> pid;
typedef pair<double,int> pdi;
typedef vector<int> vi;
typedef vector<pii> vpi;
const int dx[8]={1,0,-1,0,1,1,-1,-1};
const int dy[8]={0,1,0,-1,1,-1,1,-1};

class Point{
public:
  double x,y;
  Point(double x=0,double y=0):x(x),y(y){}

  Point operator+(Point p){ return Point(x+p.x,y+p.y);}
  Point operator-(Point p){ return Point(x-p.x,y-p.y);}
  Point operator*(double k){ return Point(x*k,y*k);}
  Point operator/(double k){ return Point(x/k,y/k);}
  bool operator<(Point p)const{ 
    return (x!=p.x ? x-p.x<-eps : y-p.y<-eps);}
  bool operator==(Point p)const{ 
    return fabs(x-p.x)<eps && fabs(y-p.y)<eps;}

  double abs(){ return sqrt(norm());}
  double norm(){ return (x*x+y*y);}
};
typedef Point Vector;
typedef vector<Point> Polygon;

class Segment{
public:
  Point p1,p2;
  Segment(Point p1=Point(),Point p2=Point()):p1(p1),p2(p2){}
};
typedef Segment Line;

double norm(Vector a){ return (a.x*a.x+a.y*a.y);}
double abs(Vector a){ return sqrt(norm(a));}
double dot(Vector a,Vector b){ return (a.x*b.x+a.y*b.y);}
double cross(Vector a,Vector b){ return (a.x*b.y-a.y*b.x);}

bool isParallel(Vector a,Vector b){
  return equals(cross(a,b),0.0);
}

bool isParallel(Segment s,Segment t){
  return equals(cross(s.p1-s.p2,t.p1-t.p2),0.0);
}

Point getCrossPointLL(Line a,Line b){
  double A=cross(a.p2-a.p1,b.p2-b.p1);
  double B=cross(a.p2-a.p1,a.p2-b.p1);
  if(abs(A)<eps || abs(B)<eps)return b.p1;
  return b.p1+(b.p2-b.p1)*(B/A);
}

int ccw(Point p0,Point p1,Point p2){
  Vector a=p1-p0;
  Vector b=p2-p0;
  if(cross(a,b)>eps)return 1;
  if(cross(a,b)<-eps)return -1;
  if(dot(a,b)<-eps)return 2;
  if(a.norm()<b.norm())return -2;
  return 0;
}

bool intersect(Point p1,Point p2,Point p3,Point p4){
  return (ccw(p1,p2,p3)*ccw(p1,p2,p4)<=0 &&
          ccw(p3,p4,p1)*ccw(p3,p4,p2)<=0);
}

bool intersect(Segment s1,Segment s2){
  return intersect(s1.p1,s1.p2,s2.p1,s2.p2);
}

bool intersectLS(Line l,Segment s){
  if(cross(l.p2-l.p1,s.p1-l.p1)*
     cross(l.p2-l.p1,s.p2-l.p1)<eps)return true;
  return false;
}
 
int contains(Polygon g,Point p){
  int n=g.size();
  bool x=false;
  for(int i=0;i<n;i++){
    Vector a=g[i]-p,b=g[(i+1)%n]-p;
    if(abs(cross(a,b))<eps && dot(a,b)<eps)return 1;
    if(a.y>b.y)swap(a,b);
    if(a.y<eps && eps<b.y && cross(a,b)>eps)x=!x;
  }
  if(x)return 2;
  return 0;
}

Polygon convex_hull(Polygon s){
  Polygon g;
  int n=s.size();
  if(n<3)return s;

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

  for(int i=0;i<n;i++){
    for(int n=g.size();n>=2&&ccw(g[n-2],g[n-1],s[i])==1;n--){
      g.pop_back();
    }
    g.push_back(s[i]);
  }
  for(int i=n-2;i>=0;i--){
    for(int n=g.size();n>=2&&ccw(g[n-2],g[n-1],s[i])==1;n--){
      g.pop_back();
    }
    g.push_back(s[i]);
  }
  reverse(g.begin(),g.end());
  g.pop_back();
  return g;
}

vector<Line> getTangent(Polygon a,Polygon b){
  vector<Line> res;
  int n=a.size(),m=b.size();

  FOR(i,0,n){
    FOR(j,0,m){
      int bi=(i+n-1)%n,bj=(j+m-1)%m;
      int ni=(i+1)%n,nj=(j+1)%m;
      if(ccw(a[i],b[j],a[ni])!=-1 && ccw(a[i],b[j],a[bi])!=-1 &&
         ccw(a[i],b[j],b[nj])!=-1 && ccw(a[i],b[j],b[bj])!=-1 ){
        res.pb(Line(a[i],b[j]));
      }
      if(ccw(a[i],b[j],a[ni])!=1 && ccw(a[i],b[j],a[bi])!=1 &&
         ccw(a[i],b[j],b[nj])!=1 && ccw(a[i],b[j],b[bj])!=1){
        res.pb(Line(a[i],b[j]));
      }
      if(ccw(a[i],b[j],a[ni])!=1 && ccw(a[i],b[j],a[bi])!=1 &&
         ccw(a[i],b[j],b[nj])!=-1 && ccw(a[i],b[j],b[bj])!=-1 ){
        res.pb(Line(a[i],b[j]));
      }
      if(ccw(a[i],b[j],a[ni])!=-1 && ccw(a[i],b[j],a[bi])!=-1 &&
         ccw(a[i],b[j],b[nj])!=1 && ccw(a[i],b[j],b[bj])!=1){
        res.pb(Line(a[i],b[j]));
      }
    }
  }
  return res;
}

int n;
Polygon p;

bool check(Segment a){
  if(contains(p,a.p1)==0)return false;
  if(contains(p,a.p2)==0)return false;
  vector<pair<double,Point> > vdp;
  vdp.pb(mp(0,a.p1));
  vdp.pb(mp(abs(a.p1-a.p2),a.p2));
  FOR(i,0,n){
    Segment b(p[i],p[(i+1)%n]);
    if(isParallel(a,b))continue;
    if(!intersect(a,b))continue;
    Point c=getCrossPointLL(a,b);
    vdp.pb(mp(abs(a.p1-c),c));
  }
  sort(all(vdp));
  FOR(i,0,vdp.size()-1){
    Point c=vdp[i].s,d=vdp[i+1].s;
    if(c==d)continue;
    Point m=c+(d-c)/2.0;
    if(contains(p,m)==0)return false;
  }
  return true;
}

double get(Polygon s,Line l){
  vector<Point> vp;
  FOR(i,0,s.size()){
    Point a=s[i],b=s[(i+1)%s.size()];
    if(isParallel(l,Segment(a,b)))continue;
    if(!intersectLS(l,Segment(a,b)))continue;
    Point c=getCrossPointLL(l,Segment(a,b));
    if(!(c==b))vp.pb(c);
  }
  double res=0;
  FOR(i,0,vp.size()){
    FOR(j,i+1,vp.size()){
      
     // pd(abs(vp[i]-vp[j]));
      if(check(Segment(vp[i],vp[j])))res=max(res,abs(vp[i]-vp[j]));
    }
  }
  return res;
}

double solve(){
  double res=0.0;
  FOR(i,0,n)res=max(res,abs(p[i]-p[(i+1)%n]));

  FOR(i,0,n-2){
    FOR(j,i+2,n){
      if((j+1)%n==i)continue;
      Polygon R,L,s;
      s.pb(p[i]);
      s.pb(p[(i+1)%n]);
      s.pb(p[j]);
      s.pb(p[(j+1)%n]);
      Segment s1(s[0],s[3]),s2(s[1],s[2]);
      if(intersect(s1,s2))swap(s1.p2,s2.p2);
      bool flag=true;
      for(int k=(i+1)%n;k!=j;k=(k+1)%n){
        Segment seg=Segment(p[k],p[(k+1)%n]);
        if(isParallel(s1,seg))continue;
        if(!intersect(s1,seg))continue;
        Point tmp=getCrossPointLL(s1,seg);
        if(!(tmp==seg.p1) && !(tmp==seg.p2))flag=false;
      }
      for(int k=(j+1)%n;k!=i;k=(k+1)%n){
        Segment seg=Segment(p[k],p[(k+1)%n]);
        if(isParallel(s2,seg))continue;
        if(!intersect(s2,seg))continue;
        Point tmp=getCrossPointLL(s2,seg);
        if(!(tmp==seg.p1) && !(tmp==seg.p2))flag=false;
      }
      //if(!flag)continue;

      s=convex_hull(s); 

      for(int k=(i+1)%n;k!=(j+1)%n;k=(k+1)%n)
        if(contains(s,p[k])!=0)R.pb(p[k]);
      for(int k=(j+1)%n;k!=(i+1)%n;k=(k+1)%n)
        if(contains(s,p[k])!=0)L.pb(p[k]);
      R=convex_hull(R);
      L=convex_hull(L);
      vector<Line> vs = getTangent(R,L);
      FOR(k,0,R.size()){
        res=max(res,get(s,Segment(R[k],R[(k+1)%R.size()])));
      }
      FOR(k,0,L.size()){
        res=max(res,get(s,Segment(L[k],L[(k+1)%L.size()])));
      }
      FOR(k,0,vs.size()){
        res=max(res,get(s,vs[k]));
      }
    }
  }
  return res;
}

int main()
{
  int c=1;
  while(cin>>n && n){
    p.clear();
    FOR(i,0,n){
      int x,y;
      cin>>x>>y;
      p.pb(Point(x,y));
    }
    cout<<"Case "<<c<<": ";
    pd(solve());
    c++;
  }
  return 0;
}
accuracy: 1
time_ms: 540
memory_kb: 3296
final_rank: 17

code_snippet: #include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<list>
#include<queue>
#include<stack>
#include<vector>
#include<set>
#include<map>
#include<bitset>
#include<string>
#define sgn(v) (abs((v))<eps?0:((v)<0?-1:1))
#define sqr(v) ((v)*(v))
#define mb make_pair
#define debug 0
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;
typedef pair<int,LL> PIL;
typedef pair<LL,int> PLI;
typedef pair<LL,LL> PLL;
const double eps=1e-8;
const double pi=acos(-1);
const int maxn=101;
struct Point
{
	double x,y;
	Point(){}
	Point(double X,double Y)
	{
		x=X;y=Y;
	}
	bool operator <(const Point &p)const
	{
		if(sgn(x-p.x))return x<p.x;
		else return y<p.y;
	}
	bool operator ==(const Point &p)const
	{
		return sgn(x-p.x)==0&&sgn(y-p.y)==0;
	}
	Point operator -(const Point &p)
	{
		return Point(x-p.x,y-p.y);
	}
	Point operator +(const Point &p)
	{
		return Point(x+p.x,y+p.y);
	}
	double cross(const Point &p)const
	{
		return x*p.y-y*p.x;
	}
	double len()
	{
		return sqrt(sqr(x)+sqr(y));
	}
	void unit()
	{
		double tmp=len();
		x/=tmp;
		y/=tmp;
		x*=0.0001;
		y*=0.0001;
	}
}pt[maxn];
struct Segment
{
	Point st,ed;
};
double cross(const Point &p,const Point &q)
{
	return p.x*q.y-p.y*q.x;
}
double dot(const Point &p,const Point &q)
{
	return p.x*q.x+p.y*q.y;
}
Point Insect(Segment &p,Segment &q)
{
	double u=cross(p.ed-p.st,q.st-p.st),v=cross(p.st-p.ed,q.ed-p.st);
	return Point((q.st.x*v+q.ed.x*u)/(u+v),(q.st.y*v+q.ed.y*u)/(u+v));
}
vector<Point> tp,sp;
int n,cas;
int check(Point P,int deb)
{
	int con=0;
	Segment now,tmp;
	Point cp;
	now.st=P;
	con=0;
	now.ed.x=P.x+19950527;
	now.ed.y=P.y+27051995;
	for(int i=0;i<n;++i)
	{
		tmp.st=pt[i];
		tmp.ed=pt[(i+1)%n];
		if(sgn((tmp.ed-tmp.st).cross(now.ed-now.st)))
		{
			cp=Insect(tmp,now);
			if(cp==tmp.ed||cp==tmp.st)while(1);
			if(sgn(dot(tmp.ed-cp,cp-tmp.st))>0&&sgn(dot(now.ed-cp,cp-now.st))>0)
				++con;
		}
	}
	return con%2;
}
	
double check(int i,int j)
{
	Segment now,tmp;
	Point cp;
	tp.clear();
	now.st=pt[i];
	now.ed=pt[j];
	for(i=0;i<n;++i)
	{
		tmp.st=pt[i];
		tmp.ed=pt[(i+1)%n];
		if(sgn((tmp.ed-tmp.st).cross(now.ed-now.st)))
		{
			cp=Insect(tmp,now);
			if(sgn(dot(tmp.ed-cp,cp-tmp.st))>0)
				tp.push_back(cp);
			else if(sgn(dot(tmp.ed-cp,cp-tmp.st))==0) // endpoints
			{
				if(cp==tmp.st)j=i;
				else j=i+1;
				if(cross(pt[(j-1+n)%n]-now.st,now.ed-now.st)*cross(pt[(j+1)%n]-now.st,now.ed-now.st)<0)
					tp.push_back(cp);
			}
		}
		else if(sgn((tmp.st-now.st).cross(now.ed-now.st))==0&&sgn((tmp.ed-now.st).cross(now.ed-now.st))==0)
		{
			Point vec=tmp.ed-tmp.st;
			vec.unit();
			if(cross(pt[(i-1+n)%n]-now.st,now.ed-now.st)*cross(pt[(i+2)%n]-now.st,now.ed-now.st)<0)
			{
				if(!check(tmp.st-vec,0))
					tp.push_back(tmp.st);
				if(!check(tmp.ed+vec,0))
					tp.push_back(tmp.ed);
			}
		}
	}
	sort(tp.begin(),tp.end());
	int n=tp.size();
	sp.clear();
	for(i=0;i<n;++i)
		if(i==0||(!(tp[i]==tp[i-1])))sp.push_back(tp[i]);
	double ans=0;
	for(i=0;i<sp.size();i+=2)
		ans=max(ans,(sp[i+1]-sp[i]).len());
	return ans;
}
int main()
{
	int i,j;
	cas=0;
	while(scanf("%d",&n)!=EOF)
	{
		if(n==0)break;
		double len=0;
		for(i=0;i<n;++i)
			scanf("%lf%lf",&pt[i].x,&pt[i].y);
		for(i=0;i<n;++i)
			len=max(len,(pt[i]-pt[(i+1)%n]).len());
		for(i=0;i<n;++i)
			for(j=i+1;j<n;++j)
				len=max(len,check(i,j));
		printf("Case %d: %.10f\n",++cas,len);
		//cout <<len*len<<endl;
	}
	return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 1260
final_rank: 1

code_snippet: #include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<list>
#include<queue>
#include<stack>
#include<vector>
#include<set>
#include<map>
#include<bitset>
#include<string>
#define sgn(v) (abs((v))<eps?0:((v)<0?-1:1))
#define sqr(v) ((v)*(v))
#define mb make_pair
#define debug 0
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;
typedef pair<int,LL> PIL;
typedef pair<LL,int> PLI;
typedef pair<LL,LL> PLL;
const double eps=1e-8;
const double pi=acos(-1);
const int maxn=101;
struct Point
{
	double x,y;
	Point(){}
	Point(double X,double Y)
	{
		x=X;y=Y;
	}
	bool operator <(const Point &p)const
	{
		if(sgn(x-p.x))return x<p.x;
		else return y<p.y;
	}
	bool operator ==(const Point &p)const
	{
		return sgn(x-p.x)==0&&sgn(y-p.y)==0;
	}
	Point operator -(const Point &p)
	{
		return Point(x-p.x,y-p.y);
	}
	Point operator +(const Point &p)
	{
		return Point(x+p.x,y+p.y);
	}
	double cross(const Point &p)const
	{
		return x*p.y-y*p.x;
	}
	double len()
	{
		return sqrt(sqr(x)+sqr(y));
	}
	void unit()
	{
		double tmp=len();
		x/=tmp;
		y/=tmp;
		x*=0.0001;
		y*=0.0001;
	}
}pt[maxn];
struct Segment
{
	Point st,ed;
};
double cross(const Point &p,const Point &q)
{
	return p.x*q.y-p.y*q.x;
}
double dot(const Point &p,const Point &q)
{
	return p.x*q.x+p.y*q.y;
}
Point Insect(Segment &p,Segment &q)
{
	double u=cross(p.ed-p.st,q.st-p.st),v=cross(p.st-p.ed,q.ed-p.st);
	return Point((q.st.x*v+q.ed.x*u)/(u+v),(q.st.y*v+q.ed.y*u)/(u+v));
}
vector<Point> tp,sp;
int n,cas;
double go[][2]={{19942705,57051994},{-19942705,57051994},{19942705,-57051994},{-19942705,-57051994},{-19942705,27051994},{19942705,27051994},{19942705,-27051994},{-19942705,-27051994}};
int check(Point P,int deb)
{
	int avg=0,con;
	Segment now,tmp;
	Point cp;
	now.st=P;
	if(deb)cout <<P.x<<" "<<P.y<<endl;
	for(int j=0;j<1;++j)
	{
		con=0;
		now.ed.x=P.x+go[j][0];
		now.ed.y=P.y+go[j][1];
		for(int i=0;i<n;++i)
		{
			tmp.st=pt[i];
			tmp.ed=pt[(i+1)%n];
			if(sgn((tmp.ed-tmp.st).cross(now.ed-now.st)))
			{
				cp=Insect(tmp,now);
				if(sgn(dot(tmp.ed-cp,cp-tmp.st))>0&&sgn(dot(now.ed-cp,cp-now.st))>0)
				{
					if(deb)
					cout <<j<<" "<<"cross point:"<<cp.x<<" "<<cp.y<<" when:"<<tmp.st.x<<" "<<tmp.st.y<<" "<<tmp.ed.x<<" "<<tmp.ed.y<<endl;
					++con;
				}
			}
		}
	}
	if(deb)cout <<"avg: "<<avg<<endl;
	return con%2;
}
	
double check(int i,int j)
{
	int oi=i,oj=j;
	Segment now,tmp;
	Point cp;
	tp.clear();
	now.st=pt[i];
	now.ed=pt[j];
	//cout <<"------------Begin--------------"<<endl;cout <<now.st.x<<" "<<now.st.y<<endl;cout <<now.ed.x<<" "<<now.ed.y<<endl;
	for(i=0;i<n;++i)
	{
		tmp.st=pt[i];
		tmp.ed=pt[(i+1)%n];
		//cout <<tmp.st.x<<" "<<tmp.st.y<<endl;cout <<tmp.ed.x<<" "<<tmp.ed.y<<endl;
		//cout <<(tmp.ed-tmp.st).cross(now.ed-now.st)<<endl;
		if(sgn((tmp.ed-tmp.st).cross(now.ed-now.st)))
		{
			cp=Insect(tmp,now);
			//cout <<"HERE"<<" "<<cp.x<<" "<<cp.y<<" "<<dot(tmp.ed-cp,cp-tmp.st)<<endl;
			if(sgn(dot(tmp.ed-cp,cp-tmp.st))>0)
				tp.push_back(cp);
			else if(sgn(dot(tmp.ed-cp,cp-tmp.st))==0)
			{
				if(cp==tmp.st)j=i;
				else j=i+1;
				if(cross(pt[(j-1+n)%n]-now.st,now.ed-now.st)*cross(pt[(j+1)%n]-now.st,now.ed-now.st)<0)
				{

					//if(cas==12&&oi==12&&oj==33)cout <<"cp:"<<cp.x<<" "<<cp.y<<endl;
					tp.push_back(cp);
				}
			}
		}
		else if(sgn((now.st-tmp.st).cross(now.ed-now.st))==0&&sgn((now.st-tmp.ed).cross(now.ed-now.st))==0)
		{
			Point vec=tmp.ed-tmp.st;
			vec.unit();
			if(cross(pt[(i-1+n)%n]-now.st,now.ed-now.st)*cross(pt[(i+2)%n]-now.st,now.ed-now.st)<0)
			{
				//if(cas==12&&oi==0&&oj==61)check(tmp.st-vec,1);
				if(!check(tmp.st-vec,0))
					tp.push_back(tmp.st);
				if(!check(tmp.ed+vec,0))
					tp.push_back(tmp.ed);
			}
		}
	}
	sort(tp.begin(),tp.end());
	if(cas==-1&&oi==0&&oj==61){cout <<"0--tp--0"<<endl;for(i=0;i<tp.size();++i)cout<<tp[i].x<<" "<<tp[i].y<<endl;cout <<"0--end--0"<<endl;}
	int n=tp.size();
	sp.clear();
	for(i=0;i<n;++i)
		if(i==0||(!(tp[i]==tp[i-1])))sp.push_back(tp[i]);
	if(cas==-1&&oi==0&&oj==61){cout <<"0--sp--0"<<endl;for(i=0;i<sp.size();++i)cout<<sp[i].x<<" "<<sp[i].y<<endl;cout <<"0--end--0"<<endl;}
	double ans=0;
	for(i=0;i<sp.size();i+=2)
		ans=max(ans,(sp[i+1]-sp[i]).len());
	return ans;
}
int main()
{
	int i,j;
	cas=0;
	while(scanf("%d",&n)!=EOF)
	{
		if(n==0)break;
		//if(cas==12)cout <<n<<endl;
		double len=0;
		for(i=0;i<n;++i)
		{
			scanf("%lf%lf",&pt[i].x,&pt[i].y);
			//if(cas==12)cout <<pt[i].x<<" "<<pt[i].y<<endl;
		}
		for(i=0;i<n;++i)
			len=max(len,(pt[i]-pt[(i+1)%n]).len());
		for(i=0;i<n;++i)
			for(j=i+1;j<n;++j)
			{
				if(cas==-1)
				{
					if(len<check(i,j))
						cout <<len<<" "<<check(i,j)<<" "<<i<<" "<<j<<" "<<endl
							 <<pt[i].x<<" "<<pt[i].y<<endl
							 <<pt[j].x<<" "<<pt[j].y<<endl
							 <<"----------------------------------------------------"<<endl;
				}
				len=max(len,check(i,j));
			}
		printf("Case %d: %.10f\n",++cas,len);
		//cout <<len*len<<endl;
	}
	return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 1264
final_rank: 2

code_snippet: #include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<list>
#include<queue>
#include<stack>
#include<vector>
#include<set>
#include<map>
#include<bitset>
#include<string>
#define sgn(v) (abs((v))<eps?0:((v)<0?-1:1))
#define sqr(v) ((v)*(v))
#define mb make_pair
#define debug 0
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;
typedef pair<int,LL> PIL;
typedef pair<LL,int> PLI;
typedef pair<LL,LL> PLL;
const double eps=1e-8;
const double pi=acos(-1);
const int maxn=101;
struct Point
{
	double x,y;
	Point(){}
	Point(double X,double Y)
	{
		x=X;y=Y;
	}
	bool operator <(const Point &p)const
	{
		if(sgn(x-p.x))return x<p.x;
		else return y<p.y;
	}
	bool operator ==(const Point &p)const
	{
		return sgn(x-p.x)==0&&sgn(y-p.y)==0;
	}
	Point operator -(const Point &p)
	{
		return Point(x-p.x,y-p.y);
	}
	Point operator +(const Point &p)
	{
		return Point(x+p.x,y+p.y);
	}
	double cross(const Point &p)const
	{
		return x*p.y-y*p.x;
	}
	double len()
	{
		return sqrt(sqr(x)+sqr(y));
	}
	void unit()
	{
		x*=0.00000001;
		y*=0.00000001;
	}
}pt[maxn];
struct Segment
{
	Point st,ed;
};
double cross(const Point &p,const Point &q)
{
	return p.x*q.y-p.y*q.x;
}
double dot(const Point &p,const Point &q)
{
	return p.x*q.x+p.y*q.y;
}
Point Insect(Segment &p,Segment &q)
{
	double u=cross(p.ed-p.st,q.st-p.st),v=cross(p.st-p.ed,q.ed-p.st);
	return Point((q.st.x*v+q.ed.x*u)/(u+v),(q.st.y*v+q.ed.y*u)/(u+v));
}
vector<Point> tp,sp;
int n,cas;
double go[][2]={{19942705,57051994},{-19942705,57051994},{19942705,-57051994},{-19942705,-57051994}};
int con[4];
int check(Point P,int deb)
{
	double avg=0;
	con[0]=con[1]=con[2]=con[3]=0;
	Segment now,tmp;
	Point cp;
	now.st=P;
	for(int j=0;j<3;++j)
	{
		now.ed.x=P.x+go[j][0];
		now.ed.y=P.y+go[j][1];
		for(int i=0;i<n;++i)
		{
			tmp.st=pt[i];
			tmp.ed=pt[(i+1)%n];
			if(sgn((tmp.ed-tmp.st).cross(now.ed-now.st)))
			{
				cp=Insect(tmp,now);
				if(sgn(dot(tmp.ed-cp,cp-tmp.st))>0&&sgn(dot(now.ed-cp,cp-now.st))>0)
				{
					if(deb)
					{
						cout <<"cross point:"<<cp.x<<" "<<cp.y<<" when:"<<tmp.st.x<<" "<<tmp.st.y<<" "<<tmp.ed.x<<" "<<tmp.ed.y<<endl;
						cout <<dot(now.ed-cp,cp-now.st)/(now.ed-cp).len()/(now.st-cp).len()<<endl;
					}
					++con[j];
				}
			}
		}
		avg+=((con[j])%2);
	}
	return round(avg/4);
}
	
double check(int i,int j)
{
	int oi=i,oj=j;
	Segment now,tmp;
	Point cp;
	tp.clear();
	now.st=pt[i];
	now.ed=pt[j];
	//cout <<"------------Begin--------------"<<endl;cout <<now.st.x<<" "<<now.st.y<<endl;cout <<now.ed.x<<" "<<now.ed.y<<endl;
	for(i=0;i<n;++i)
	{
		tmp.st=pt[i];
		tmp.ed=pt[(i+1)%n];
		//cout <<tmp.st.x<<" "<<tmp.st.y<<endl;cout <<tmp.ed.x<<" "<<tmp.ed.y<<endl;
		//cout <<(tmp.ed-tmp.st).cross(now.ed-now.st)<<endl;
		if(sgn((tmp.ed-tmp.st).cross(now.ed-now.st)))
		{
			cp=Insect(tmp,now);
			//cout <<"HERE"<<" "<<cp.x<<" "<<cp.y<<" "<<dot(tmp.ed-cp,cp-tmp.st)<<endl;
			if(sgn(dot(tmp.ed-cp,cp-tmp.st))>0)
				tp.push_back(cp);
			else if(sgn(dot(tmp.ed-cp,cp-tmp.st))==0)
			{
				if(cp==tmp.st)j=i;
				else j=i+1;
				if(cross(pt[(j-1+n)%n]-now.st,now.ed-now.st)*cross(pt[(j+1)%n]-now.st,now.ed-now.st)<0)
				{

					//if(cas==12&&oi==12&&oj==33)cout <<"cp:"<<cp.x<<" "<<cp.y<<endl;
					tp.push_back(cp);
				}
			}
		}
		else if(sgn((now.st-tmp.st).cross(now.ed-now.st))==0&&sgn((now.st-tmp.ed).cross(now.ed-now.st))==0)
		{
			Point vec=tmp.ed-tmp.st;
			vec.unit();
			if(cross(pt[(i-1+n)%n]-now.st,now.ed-now.st)*cross(pt[(i+2)%n]-now.st,now.ed-now.st)<0)
			{
				if(check(tmp.st-vec,0)%2==0)
				{
					//if(cas==12&&oi==12&&oj==33)cout <<(tmp.st-vec).x<<" st "<<(tmp.st-vec).y<<" "<<vec.x<<" "<<vec.y<<" "<<check(tmp.st-vec,1)<<endl;
					tp.push_back(tmp.st);
				}
				if(check(tmp.ed+vec,0)%2==0)
				{
					//if(cas==12&&oi==12&&oj==33)cout <<tmp.ed.x<<" ed "<<tmp.ed.y<<endl;
					tp.push_back(tmp.ed);
				}
			}
		}
	}
	sort(tp.begin(),tp.end());
	if(cas==-1&&oi==0&&oj==61){cout <<"0--tp--0"<<endl;for(i=0;i<tp.size();++i)cout<<tp[i].x<<" "<<tp[i].y<<endl;cout <<"0--end--0"<<endl;}
	int n=tp.size();
	sp.clear();
	for(i=0;i<n;++i)
		if(i==0||(!(tp[i]==tp[i-1])))sp.push_back(tp[i]);
	if(cas==-1&&oi==0&&oj==61){cout <<"0--sp--0"<<endl;for(i=0;i<sp.size();++i)cout<<sp[i].x<<" "<<sp[i].y<<endl;cout <<"0--end--0"<<endl;}
	double ans=0;
	for(i=0;i<sp.size();i+=2)
		ans=max(ans,(sp[i+1]-sp[i]).len());
	return ans;
}
int main()
{
	int i,j;
	cas=0;
	while(scanf("%d",&n)!=EOF)
	{
		if(n==0)break;
		//if(cas==12)cout <<n<<endl;
		double len=0;
		for(i=0;i<n;++i)
		{
			scanf("%lf%lf",&pt[i].x,&pt[i].y);
			//if(cas==12)cout <<pt[i].x<<" "<<pt[i].y<<endl;
		}
		for(i=0;i<n;++i)
			len=max(len,(pt[i]-pt[(i+1)%n]).len());
		for(i=0;i<n;++i)
			for(j=i+1;j<n;++j)
			{
				if(cas==-1)
				{
					if(len<check(i,j))
						cout <<len<<" "<<check(i,j)<<" "<<i<<" "<<j<<" "<<endl
							 <<pt[i].x<<" "<<pt[i].y<<endl
							 <<pt[j].x<<" "<<pt[j].y<<endl
							 <<"----------------------------------------------------"<<endl;
				}
				len=max(len,check(i,j));
			}
		printf("Case %d: %.10f\n",++cas,len);
		//cout <<len*len<<endl;
	}
	return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 1276
final_rank: 3