#include <iostream>
#include <cmath>
#include <tuple>
#include <vector>
#include <string>
#include <algorithm>
struct Vector;
struct Point {
	long double x{ 0 }, y{ 0 };
	Point() {}
	Point(long double ax, long double ay) :x{ ax }, y{ ay } {};
	Vector to_vec() const;
	Point center(const Point other) const {
		return Point((x + other.x) / 2, (y + other.y) / 2);
	}
};
struct Angle {
	long double sin, cos;
	Angle(long double ax, long double ay) :cos{ ax / std::sqrt(ax * ax + ay * ay) }, sin{ ay / std::sqrt(ax * ax + ay * ay) } {}
	Angle perpendicular() const {
		return Angle(-sin, cos);
	}
	Angle operator+(const Angle angle) const {
		return Angle(cos * angle.cos - sin * angle.sin, sin * angle.cos + cos * angle.sin);
	}
	Angle operator-(const Angle angle) const {
		return Angle(cos * angle.cos + sin * angle.sin, sin * angle.cos - cos * angle.sin);
	}

};
struct Vector {
	long double x, y;
	Vector(long double ax, long double ay) :x{ ax }, y{ ay } {}
	Vector(const Point from, const Point to) :x{ to.x - from.x }, y{ to.y - from.y } {}
	Angle to_angle() const {
		return Angle(x, y);
	}
	Vector operator+(const Vector other) const {
		return Vector(x + other.x, y + other.y);
	}
	Vector operator-(const Vector other) const {
		return Vector(x - other.x, y - other.y);
	}
	long double length() const {
		return std::sqrt(x * x + y * y);
	}
};
Vector Point::to_vec() const {
	return Vector(x, y);
}
template<typename T>
class Option {
	T * const val{ nullptr };
	Option() {};
	Option(Option<T> &) = delete;
public:
	Option(T &&v) :val{ new T(std::move(v)) } {}
	Option(Option<T> &&other) :val{ other.val } { other.val = nullptr; }
	static Option<T> None() {
		return Option<T>();
	}
	~Option() { delete val; }
	bool is_nil() const { return val == nullptr; }
	const T & get() const { return *val; }
};
class Circle {
	Point center;
public:
	Circle() {}
	Circle(const Point p) :center{ p } {}
	Option<std::tuple<Angle, Angle>> cross_point(const Circle other) const {
		if (Vector(center, other.center).length() >= 2) {
			return Option<std::tuple<Angle, Angle>>::None();
		}
		else {
			auto mid = center.center(other.center);
			auto vec = Vector(center, mid);
			auto cos = vec.length();
			return Option<std::tuple<Angle, Angle>>(std::make_tuple(vec.to_angle() + Angle(cos, std::sqrt(1 - cos * cos)), vec.to_angle() - Angle(cos, std::sqrt(1 - cos * cos))));
		}
	}
};
void f(int n) {
	std::vector<Circle> circles(n);
	{
		std::string coord;
		for (auto &circle : circles) {
			std::cin >> coord;
			auto itr = coord.find(',');
			auto x = std::stold(coord.substr(0, itr));
			auto y = std::stold(coord.substr(itr + 1));
			circle = Circle(Point(x, y));
		}
	}
	std::vector<std::vector<std::tuple<bool, Angle>>> points(n, std::vector<std::tuple<bool, Angle>>());
	int res{ 0 };
	for (auto i = 0; i < n; ++i) {
		for (auto j = i + 1; j < n; ++j) {
			auto res = circles[i].cross_point(circles[j]);
			if (!res.is_nil()) {
				points[i].push_back(std::make_tuple(true, std::get<0>(res.get())));
				points[i].push_back(std::make_tuple(false, std::get<1>(res.get())));
			}
		}
		std::sort(points[i].begin(), points[i].end(), [](const std::tuple<bool, Angle> &a, const std::tuple<bool, Angle> &b) {return (std::get<1>(a) - std::get<1>(b)).sin > 0; });
		int max{ 0 }, min{ 0 }, now{ 0 };
		for (const auto &p : points[i]) {
			if (std::get<0>(p)) {
				++now;
				if (now > max) max = now;
			}
			else {
				--now;
				if (now < min) min = now;
			}
		}
		if (res < max - min) res = max - min;
	}
	std::cout << res + 1 << std::endl;
}
int main() {
	int n;
	for (std::cin >> n; n != 0; std::cin >> n) {
		f(n);
	}
}
