#include <bits/stdc++.h>
namespace geometry {
struct point {
  double x;
  double y;
  point() {}
  point(double x, double y) : x(x), y(y) {}
  point& operator+=(const point& rhs) {
    x += rhs.x;
    y += rhs.y;
    return *this;
  }
  point& operator-=(const point& rhs) {
    x -= rhs.x;
    y -= rhs.y;
    return *this;
  }
  point& operator/=(double factor) {
    x /= factor;
    y /= factor;
    return *this;
  }
  point& operator*=(double factor) {
    x *= factor;
    y *= factor;
    return *this;
  }
  bool operator==(const point& rhs) const {
    return (std::abs(x - rhs.x) < 1E-10) && (std::abs(y - rhs.y) < 1E-10);
  }
  bool operator!=(const point& rhs) const { return !(*this == rhs); }
  bool operator<=(const point& rhs) const {
    return x < rhs.x || (x == rhs.x && y <= rhs.y);
  }
  bool operator>=(const point& rhs) const {
    return x > rhs.x || (x == rhs.x && y >= rhs.y);
  }
  bool operator<(const point& rhs) const { return !(*this >= rhs); }
  bool operator>(const point& rhs) const { return !(*this <= rhs); }
  double arg() const { return atan2(y, x); }
  double norm() const { return sqrt(x * x + y * y); }
  point get_normal() const { return point(-y, x); }
};
struct circle {
  point center;
  double radius;
  circle() {}
  circle(double x, double y, double r) : center(x, y), radius(r) {}
};
struct line {
  double a;
  double b;
  double c;
};
enum rotate_dir { rotate_None = 0, rotate_CW = 1, rotate_CCW = -1 };
point operator+(const point& p1, const point& p2) {
  point p(p1);
  p += p2;
  return p;
}
point operator/(const point& p1, double factor) {
  point p(p1);
  p /= factor;
  return p;
}
point operator*(const point& p1, double factor) {
  point p(p1);
  p *= factor;
  return p;
}
point operator*(double factor, const point& p1) {
  point p(p1);
  p *= factor;
  return p;
}
point operator-(const point& p1, const point& p2) {
  point p(p1);
  p -= p2;
  return p;
}
std::istream& operator>>(std::istream& is, point& p) {
  is >> p.x >> p.y;
  return is;
}
double get_dist_pow2(const point& p1, const point& p2) {
  return pow(p1.x - p2.x, 2) + pow(p1.y - p2.y, 2);
}
double get_distance(const point& p1, const point& p2) {
  return sqrt(get_dist_pow2(p1, p2));
}
bool get_crosspoint(const circle& c1, const circle& c2, point* p1, point* p2) {
  double distance = get_distance(c1.center, c2.center);
  point c1_to_c2 = c2.center - c1.center;
  if (c2.radius + distance < c1.radius) {
    return false;
  } else if (c1.radius + distance < c2.radius) {
    return false;
  } else if (c1.radius + c2.radius < distance) {
    return false;
  }
  double a =
      (distance * distance + c1.radius * c1.radius - c2.radius * c2.radius) /
      (2 * distance);
  point base = c1.center + a * c1_to_c2 / c1_to_c2.norm();
  point base_to_cross = sqrt(c1.radius * c1.radius - a * a) *
                        c1_to_c2.get_normal() / c1_to_c2.norm();
  *p1 = base + base_to_cross;
  *p2 = base - base_to_cross;
  return true;
}
}  // namespace geometry
using namespace geometry;
using namespace std;
int get_max_overlapped_seals(const vector<circle>& seals) {
  int n = seals.size();
  int max_seals = 1;
  for (int i = 0; i < n; i++) {
    for (int j = i + 1; j < n; j++) {
      point p1, p2;
      if (!get_crosspoint(seals[i], seals[j], &p1, &p2)) {
        continue;
      }
      int n1 = count_if(seals.begin(), seals.end(), [&](circle c) {
        return get_dist_pow2(p1, c.center) <= c.radius;
      });
      int n2 = count_if(seals.begin(), seals.end(), [&](circle c) {
        return get_dist_pow2(p2, c.center) <= c.radius;
      });
      max_seals = max(max_seals, max(n1, n2));
    }
  }
  return max_seals;
}
int main(void) {
  int n;
  vector<circle> seals;
  cin >> n;
  for (int i = 0; i < n; i++) {
    double x, y;
    char s;
    cin >> x >> s >> y;
    seals.emplace_back(x, y, 1.0);
  }
  cout << get_max_overlapped_seals(seals) << endl;
}
