#include <bits/stdc++.h>
struct P {
  P() {}
  P(double _r, double _i) : r(_r), i(_i) {}
  void real(const double& v) { r = v; }
  void imag(const double& v) { i = v; }
  double r, i;
};
double real(const P& p) { return p.r; }
double imag(const P& p) { return p.i; }
double norm(const P& p) {
  double r = real(p), i = imag(p);
  return r * r + i * i;
}
double dist(const P& p) { return std::sqrt(norm(p)); }
P operator+(const P& lhs, const P& rhs) {
  return P(real(lhs) + real(rhs), imag(lhs) + imag(rhs));
}
P operator-(const P& lhs, const P& rhs) {
  return P(real(lhs) - real(rhs), imag(lhs) - imag(rhs));
}
P operator-(const P& p) { return P(-real(p), -imag(p)); }
double cross(const P& lhs, const P& rhs) {
  return real(lhs) * imag(rhs) - imag(lhs) * real(rhs);
}
double dot(const P& lhs, const P& rhs) {
  return real(lhs) * real(rhs) + imag(lhs) * imag(rhs);
}
const double EPS = 1e-9, D_THETA = 0.06, D_R = 0.06;
int N;
P ps[100];
std::vector<P> is;
void addIntersection(int i, int j) {
  if (dist(ps[i] - ps[j]) > 2.0) {
    return;
  }
  P m{(real(ps[j]) - real(ps[i])) / 2, (imag(ps[j]) - imag(ps[i])) / 2},
      n{-imag(m), real(m)};
  {
    double d = dist(n);
    n.real(real(n) / d);
    n.imag(imag(n) / d);
  }
  for (int k = -1; k <= 1; k += 2) {
    P p{0.5 * k * dist(m) * real(n), 0.5 * k * dist(m) * imag(n)};
    is.push_back(ps[i] + m + p);
  }
}
int count(P p) {
  int res = 0;
  for (int i = 0; i < N; i++) {
    if (dist(ps[i] - p) < 1.0 + EPS) {
      res++;
    }
  }
  return res;
}
int main() {
  scanf("%d", &N);
  for (int i = 0; i < N; i++) {
    double x, y;
    scanf("%lf,%lf", &x, &y);
    ps[i].real(x);
    ps[i].imag(y);
  }
  for (int i = 0; i < N; i++) {
    for (int j = i + 1; j < N; j++) {
      addIntersection(i, j);
    }
  }
  int res = 0;
  for (auto i : is) {
    res = std::max(res, count(i));
  }
  printf("%d\n", res);
}
