#include <iostream>
#include <algorithm>
#include <cassert>
#include <vector>
#include <cmath>

//-------------------------------------------------------------------------
// geometric library
 
namespace geometry {
 
#define EPS 1E-10 ///< 0とみなすサイズ。適当
 
    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) < EPS) && (std::abs(y - rhs.y) < EPS); }
        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); }
    };
	typedef point vec2d;
 
    struct circle {
        point center;
        double radius;
		circle() {}
		circle(double x, double y, double r) : center(x, y), radius(r) {}
    };
 
    struct line {
        // ax + by + c = 0
        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;
    }
  
    ///! 2点の距離
    double get_dist_pow2(const point& p1, const point& p2)
    {
        return pow(p1.x - p2.x, 2) + pow(p1.y - p2.y, 2);
    }

    ///! 2点の距離
    double get_distance(const point& p1, const point& p2)
    {
        return sqrt(get_dist_pow2(p1, p2));
    }

	///! 2円の交点を求める。ない場合はfalse
	bool get_crosspoint(const circle& c1, const circle& c2, point *p1, point *p2)
	{
		double distance = get_distance(c1.center, c2.center);
		vec2d c1_to_c2 = c2.center - c1.center;

		if      (c2.radius + distance < c1.radius) { return false;  } // c2 is in c1
        else if (c1.radius + distance < c2.radius) { return false; } // c1 is in c2
        else if (c1.radius + c2.radius < distance) { return false;  } // don't overlap

		double a = (distance * distance + c1.radius * c1.radius - c2.radius * c2.radius) / (2 * distance);

		// 2交点の中点
		point base = c1.center + a * c1_to_c2 / c1_to_c2.norm();

		vec2d 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;
			}
			// 2円の交点を求め、その交点を含む円の数を数える。シールの重なり数は交点で最大になる
			int n1 = count_if(seals.begin(), seals.end(), [&](circle c){ return get_distance(p1, c.center) <= c.radius + EPS; } );
			int n2 = count_if(seals.begin(), seals.end(), [&](circle c){ return get_distance(p2, c.center) <= c.radius + EPS; } );
			max_seals = max(max_seals, max(n1, n2));
		}
	}
	return max_seals;
}

int main(void) {
	int n;

	while (cin >> n) {
		vector<circle> seals;

		if (n == 0) {
			break;
		}

		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;
	}
}

Measured memory_bytes: 1252