#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cctype>
#include<math.h>
#include<string>
#include<string.h>
#include<stack>
#include<queue>
#include<vector>
#include<utility>
#include<set>
#include<map>
#include<stdlib.h>
#include<iomanip>
#include<complex>


using namespace std;

#define ll long long
#define ld long double
#define INF 1e9
#define LINF (ll)INF*INF
#define MOD 1000000007
#define rep(i,n) for(int i=0;i<(n);i++)
#define loop(i,a,n) for(int i=a;i<(n);i++)
#define all(in) in.begin(),in.end()
#define shosu(x) fixed<<setprecision(x)

#define int ll //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int,int> pii;
typedef vector<pii> vp;

int gcd(int a, int b){
    if(b==0) return a;
    return gcd(b,a%b);
}
int lcm(int a, int b){
    return a/gcd(a,b)*b;
}

const double PI=acos(-1);
const double EPS=1e-9; //うまくいかなかったらゆるめる
typedef complex<double> P;
typedef vector<P> G;
#define shosu(x) fixed<<setprecision(x)
#define diff(P,i) (P[(i+1)%P.size()] - P[i])

struct L : public vector<P> {
  L(const P &a, const P &b) {
    push_back(a); push_back(b);
  }
  L(){;}
};
struct C {
  P c;double r;
  C(const P &c,double r):c(c),r(r){}
  C(){;}
};

namespace std{//演算子の定義
  bool operator < (const P& a,const P& b) {
    return real(a)!= real(b) ? real(a) < real(b) : imag(a) < imag(b);
    //return imag(a) != imag(b) ? imag(a) < imag(b) : real(a) < real(b)
  }
  bool operator == (const P& a,const P& b) {
    return a.real()==b.real() && a.imag()==b.imag();
  }
}


void printP(const P &p){
  cout << shosu(10) << p.real() << " " << p.imag() << endl;
}

void printL(const L &l) {
  	cout << shosu(10) << l[0].real() << " " << l[0].imag() << " " << l[1].real() << " " << l[1].imag() << endl;
}

void printG(const G &g) {
  for(int i = 0; i < g.size(); i++){
    cout << shosu(10) << g[i].real() << " " << g[i].imag() << endl;
  }
}



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

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


L crosspointCC(C a,C b){ //2円の交点
	P tmp = b.c - a.c;
	double d = abs(tmp);
	double q = acos((a.r * a.r + d * d - b.r * b.r)/(2 * a.r * d));
	double t = arg(tmp);//atan(tmp.imag()/tmp.real());
	P p1 = a.c + polar(a.r, t + q);
	P p2 = a.c + polar(a.r, t - q);
	if(p2 < p1) swap(p1,p2);
	return L(p1, p2);
}


double distancePP(const P &p, const P &q){ //2点間の距離
  return hypot(p.real()-q.real(), p.imag()-q.imag());
}

P inP(){
  double x,y;
  scanf("%lf,%lf", &x, &y);
  //cin >> x >> y;
  P p(x,y);
  return p;
}

C inC(){
  P p = inP();
  double r = 1.0;
  C c(p,r);
  return c;
}



signed main(void) {
    int n;
    while(cin >> n, n){
        vector<C> v(n);
        rep(i,n)v[i] = inC();
        int ans = 1;
        rep(i,n)loop(j,i+1,n){
            if(distancePP(v[i].c, v[j].c) > 2)continue;
            L l = crosspointCC(v[i],v[j]);
            vi t(2);
            rep(k,n)if(k != i && k != j){
                rep(x,2)if(distancePP(l[x],v[k].c) <= 1 + EPS)t[x]++;
            }
            ans = max(ans, max(t[0],t[1])+2);
        }
        cout << ans << endl;
    }
}

