Problem:
シールの重なり

1 辺の長さが 10 の正方形の折り紙に半径 1 の円形のシールを n 枚貼ります。シールは重ねて貼ることができます。シールを貼る位置の座標を読み込んで、折り紙上でもっとも多くシールが重なっている場所(シールが１枚だけでも"重なっている"とする)でのシールの枚数を出力するプログラムを作成してください。

折り紙の左下を原点とした x, y 座標を与えます。この x, y を円の中心としてシールを貼ることとします。円の中心が折り紙の外に出ることはありません。また、同一座標に複数のシールが貼られることはありません。

Input

複数のデータセットが与えられます。各データセットは以下のような形式で与えられます。

n
x1,y1
x2,y2
:
xn,yn

１行目にシールの枚数 n (0 ≤ 100) が与えられます。続く n 行に、各シールの中心座標が与えられます。
xi, yi は i 枚目のシールの中心の x 座標と y 座標を表します。各値は小数点以下最大 6 桁までの数字を含む実数で与えられます。

n が 0 のとき、入力の最後とします。データセットの数は 50 を超えません。

Output

各データセットに対し、折り紙上で最も多くシールが重なっている場所でのシールの枚数（整数）を出力して下さい。

Sample Input

15
3.14979,8.51743
2.39506,3.84915
2.68432,5.39095
5.61904,9.16332
7.85653,4.75593
2.84021,5.41511
1.79500,8.59211
7.55389,8.17604
4.70665,4.66125
1.63470,4.42538
7.34959,4.61981
5.09003,8.11122
5.24373,1.30066
0.13517,1.83659
7.57313,1.58150
0

Output for the Sample Input

4

Hint

入力例のようにシールを貼った図です。円はシール、数字は入力例の行数を表しています。
点(2.3,4.6)では、入力例の 2 行目、3 行目、6 行目、10 行目の 4 枚のシールが重なっています。

6 と 9 のおのおのの中心の距離は 2.01293 なので、シールは重なっていません。1 と 12 のおのおのの中心の距離は 1.98231 なので、シールは重なっています。

２つの円が接しているとき（おのおのの中心の距離が 2 のとき）は、重なっているものとします。

Solution in JAVA (judge verdict: Wrong Answer)

import java.awt.geom.Point2D;
import java.util.*;

public class Main {
	Scanner in = new Scanner(System.in);
	public static void main(String[] args) {
		new Main();
	}

	public Main() {
		new AOJ0090().doIt();
	}

	class AOJ0090{
		void doIt(){
			while(true){
				int n = in.nextInt();
				if(n==0)break;
				ArrayList<Point2D> p = new ArrayList<Point2D>();
				ArrayList<Point2D> list = new ArrayList<Point2D>();
				for(int i=0;i<n;i++){
					String res[] = in.next().split(",");
					p.add(new Point2D.Double(Double.parseDouble(res[0]),Double.parseDouble(res[1])));
				}
				for(int i=0;i<n;i++)for(int s=i+1;s<n;s++){
					Point2D[] a = intersectPtCC(new Circle(p.get(i),1),new Circle(p.get(s),1));
					if(a==null)continue;
					list.add(a[0]);list.add(a[1]);
				}
				int result = 1;
				for(int i=0;i<list.size();i++){
					int cnt = 0;
					for(int s=0;s<n;s++)if(list.get(i).distance(p.get(s))<=1){
						cnt++;
					}
					result = Math.max(result, cnt);
//					if(cnt>=5)System.out.println(list.get(i));
				}
				System.out.println(result);
			}
		}

		class Circle{
			Point2D p;
			double r;
			Circle(Point2D p,double r){ 
				this.p=p;
				this.r=r;
			}
			Circle(double x,double y,double r){  
				this.p=new Point2D.Double(x,y); 
				this.r=r;
			}
		}
		 //円と円の交点
		Point2D [] intersectPtCC(Circle a,Circle b){
		double dis = a.p.distance(b.p);
		if(dis > a.r + b.r)return null;
		Point2D v = sub(b.p, a.p);
		double rc=(dis*dis+a.r*a.r- b.r*b.r)/(2*dis);
		double rate = rc / dis;
		v = mul(rate, v);
		Point2D c = add(v, a.p);
		double disC2c = c.distance(b.p);
		double disqc = Math.sqrt(b.r * b.r - disC2c * disC2c);
		Point2D v2 = sub(b.p, c);
		v2 = mul(disqc / disC2c, v2);
		Point2D [] res = new Point2D[2];
		res[0] = add(normalVector1(v2), c);
		res[1] = add(normalVector2(v2), c);
		return res;
		}

		Point2D normalVector1(Point2D p){
			return new Point2D.Double(-p.getY(), p.getX());
		}
		Point2D normalVector2(Point2D p){
			return new Point2D.Double(p.getY(), -p.getX());
		}
		Point2D mul(double n,Point2D p1){
			return new Point2D.Double(p1.getX()*n,p1.getY()*n);
		}
		Point2D sub(Point2D p1,Point2D p2){
			return new Point2D.Double(p1.getX()-p2.getX(),p1.getY()-p2.getY());
		}
		Point2D add(Point2D p1,Point2D p2){
			return new Point2D.Double(p1.getX()+p2.getX(), p1.getY()+p2.getY());
		}
	}
}