#include <bits/stdc++.h>
using namespace std;
static const int tx[] = {0, 1, 0, -1};
static const int ty[] = {-1, 0, 1, 0};
static const double EPS = 1e-12;
namespace std {
bool operator<(const complex<double> &a, const complex<double> &b) {
  return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
}
}  // namespace std
double cross(const complex<double> &a, const complex<double> &b) {
  return imag(conj(a) * b);
}
double dot(const complex<double> &a, const complex<double> &b) {
  return real(conj(a) * b);
}
struct Line : public vector<complex<double> > {
  Line(const complex<double> &a, const complex<double> &b) {
    push_back(a);
    push_back(b);
  }
};
struct Circle {
  complex<double> p;
  double r;
  Circle(const complex<double> &p, double r) : p(p), r(r) {}
};
int ccw(complex<double> a, complex<double> b, complex<double> c) {
  b -= a;
  c -= a;
  if (cross(b, c) > 0) return +1;
  if (cross(b, c) < 0) return -1;
  if (dot(b, c) < 0) return +2;
  if (norm(b) < norm(c)) return -2;
  return 0;
}
bool intersectSS(const Line &s, const Line &t) {
  return ccw(s[0], s[1], t[0]) * ccw(s[0], s[1], t[1]) <= 0 &&
         ccw(t[0], t[1], s[0]) * ccw(t[0], t[1], s[1]) <= 0;
}
bool intersectCC(const Circle &s, const Circle &t) {
  double abs_distance = (imag(s.p) - imag(t.p)) * (imag(s.p) - imag(t.p)) +
                        (real(s.p) - real(t.p)) * (real(s.p) - real(t.p));
  return (abs_distance <= (s.r + t.r) * (s.r + t.r));
}
vector<complex<double> > crosspointsCC(const Circle &s, const Circle &t) {
  double a = real(s.p) - real(t.p);
  double b = imag(s.p) - imag(t.p);
  double c = 0.5 * ((s.r - t.r) * (s.r + t.r) - a * (real(s.p) + real(t.p)) -
                    b * (imag(s.p) + imag(t.p)));
  double l = a * a + b * b;
  double k = a * real(s.p) + b * imag(s.p) + c;
  double d = l * s.r * s.r - k * k;
  vector<complex<double> > res;
  if (d > 0) {
    double ds = sqrt(d);
    double apl = a / l;
    double bpl = b / l;
    double xc = real(s.p) - apl * k;
    double yc = imag(s.p) - bpl * k;
    double xd = bpl * ds;
    double yd = apl * ds;
    res.push_back(complex<double>(xc - xd, yc + yd));
    res.push_back(complex<double>(xc + xd, yc - yd));
  } else if (d == 0) {
    res.push_back(
        complex<double>(real(s.p) - a * k / l, imag(s.p) - b * k / l));
  } else {
  }
  return res;
}
complex<double> crosspointLL(const Line &l, const Line &m) {
  double A = cross(l[1] - l[0], m[1] - m[0]);
  double B = cross(l[1] - l[0], l[1] - m[0]);
  if (abs(A) < EPS && abs(B) < EPS) return m[0];
  if (abs(A) < EPS) assert(false);
  return m[0] + B / A * (m[1] - m[0]);
}
double compute_area(const complex<double> &l, const complex<double> &m) {
  return abs(cross(l, m)) / 2.0;
}
bool is_equal(const complex<double> &l, const complex<double> &m) {
  return ((abs(real(l) - real(m)) < EPS) && (abs(imag(l) - imag(m) < EPS)));
}
bool include(Circle s, const complex<double> &t) {
  s.p -= t;
  return dot(s.p, s.p) <= s.r;
}
int main() {
  int total_seals;
  while (~scanf("%d", &total_seals)) {
    if (total_seals == 0) break;
    vector<Circle> circles;
    for (int i = 0; i < total_seals; i++) {
      double x, y;
      scanf("%lf,%lf", &x, &y);
      circles.push_back(Circle(complex<double>(x, y), 1.0));
    }
    vector<complex<double> > points;
    for (int i = 0; i < circles.size(); i++) {
      for (int j = i + 1; j < circles.size(); j++) {
        vector<complex<double> > cross_points;
        cross_points = crosspointsCC(circles[i], circles[j]);
        for (int k = 0; k < cross_points.size(); k++) {
          points.push_back(cross_points[k]);
        }
      }
    }
    int res = 0;
    for (int i = 0; i < points.size(); i++) {
      int count = 0;
      for (int j = 0; j < circles.size(); j++) {
        if (include(circles[j], points[i])) {
          count++;
        }
      }
      res = max(count, res);
    }
    printf("%d\n", res);
  }
}
