#include <iostream>
#include <algorithm>
#include <complex>
#include <vector>
#include <string>
#include <sstream>
#include <cmath>
using namespace std;
typedef complex<double> P;

const double eps = 1e-8;

bool equals(double a, double b) {
  return abs(a-b) < eps;
}

struct C {
  P o;
  double r;
  C() {}
  C(P o, double r) : o(o), r(r) {}
};

int isIntersect(C a, C b) {
  double x = a.o.real() - b.o.real();
  double y = a.o.imag() - b.o.imag();
  double s = a.r + b.r;
  double d = x*x + y*y;
  s *= s;
  if(equals(d, s)) return 1;
  if(d > s) return 0;
  double r = abs(a.r - b.r);
  r *= r;
  if(equals(d, r)) return -1;
  if(d > r) return 2;
  return -2;
}

bool isIn(C c, P p) {
  return abs(c.o - p) < c.r + eps;
}


vector<P> getCrossP(C c1, C c2) {
  vector<P> v;
  int cp = isIntersect(c1,c2);
  if(cp == 0 || cp == -2) return v;
  
  double ll = norm(c1.o - c2.o);
  double A = ( c1.r * c1.r - c2.r * c2.r + ll ) / ( 2.0 * ll );
  P base = c2.o - c1.o;

  if(abs(cp) == 1) {
    v.push_back(c1.o + A*base);
  } else {
    P n(-base.imag(), base.real());
    n /= abs(n);
    double h = sqrt(c1.r * c1.r - A*A*ll);
    v.push_back(c1.o + A*base + h*n);
    v.push_back(c1.o + A*base - h*n);
  }
  return v;
}

int N;
vector<P> ps;

int main() {
  while(cin >> N && N) {
    ps.resize(N);
    for(int i = 0; i < N; ++i) {
      string s;
      cin >> s;
      replace(s.begin(), s.end(), ',', ' ');
      stringstream ss(s);
      ss >> ps[i].real() >> ps[i].imag();
    }
    vector<P> ps2;
    for(int i = 0; i < N; ++i) {
      for(int j = i+1; j < N; ++j) {
        vector<P> v = getCrossP(C(ps[i], 1.0), C(ps[j], 1.0));
        for(int k = 0; k < v.size(); ++k) {
          ps2.push_back(v[k]);
        }
      }
    }

    int ans = 1;
    for(int i = 0; i < ps2.size(); ++i) {
      int sum = 0;
      for(int j = 0; j < ps.size(); ++j) {
        sum += isIn(C(ps[j], 1.0), ps2[i]);
      }
      ans = max(ans, sum);
    }
    cout << ans << endl;
  }
  return 0;
}