#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES

#include <stdio.h>
#include <ctype.h>
#include <string>
#include <iostream>
#include <vector>
#include <stack>
#include <fstream>
#include <sstream>
#include <queue>
#include <exception>
#include <cmath>

using namespace std;

template <typename _Ty>
std::ostream& operator << (std::ostream& ostr, const std::vector<_Ty> v) {
	if (v.empty()) return ostr;
	for (auto itr = v.begin(); itr != v.end(); itr++) {
		if (itr == v.begin()) {
			std::cout << "{" << *itr;
		}
		else std::cout << ", " << *itr;
	}
	std::cout << "}";
	return ostr;
}

class Point2i {
public:
	int x;
	int y;

	Point2i() {
		this->x = x; this->y = y;
	}
	Point2i(int x, int y) {
		this->x = x; this->y = y;
	}

	friend std::ostream& operator << (std::ostream& ostr, const Point2i& p) {
		std::cout << "{" << p.x << ", " << p.y << "}";
		return ostr;
	}
};

class Point2f {
public:
	double x;
	double y;

	Point2f() {
		this->x = x; this->y = y;
	}
	Point2f(double x, double y) {
		this->x = x; this->y = y;
	}

	friend std::ostream& operator << (std::ostream& ostr, const Point2f& p) {
		std::cout << "{" << p.x << ", " << p.y << "}";
		return ostr;
	}
};

double distance(Point2f p1, Point2f p2) {
	return sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));
}

bool isOverlapped(Point2f p1, Point2f p2)
{
	return distance(p1, p2) <= 2.0 + 1e-6;
}

pair<Point2f, Point2f> intersection(Point2f p1, Point2f p2) {
	double dist = distance(p1, p2);
	double costheta = dist / 2;
	double sintheta = sqrt(1 - costheta * costheta);
	Point2f i1, i2;
	i1.x = p1.x + (costheta * (p2.x - p1.x) - sintheta * (p2.y - p1.y)) / dist;
	i1.y = p1.y + (sintheta * (p2.x - p1.x) + costheta * (p2.y - p1.y)) / dist;
	i2.x = p1.x + (costheta * (p2.x - p1.x) + sintheta * (p2.y - p1.y)) / dist;
	i2.y = p1.y + (-sintheta * (p2.x - p1.x) + costheta * (p2.y - p1.y)) / dist;
	return pair<Point2f, Point2f>(i1, i2);
}

bool AOJ0090()
{
	int n;
	cin >> n;
	if (n == 0) return false;
	vector<Point2f> p;
	vector<bool> b(n, false);
	vector<Point2i> pair;

	for (int i = 0; i < n; i++) {
		double x, y;
		scanf("%lf,%lf", &x, &y);
		p.push_back(Point2f(x, y));
	}

	for (int i = 0; i < p.size() - 1; i++) {
		for (int j = i + 1; j < p.size(); j++) {
			if (isOverlapped(p[i], p[j])) {
				pair.push_back(Point2i(i, j));
				b[i] = b[j] = true;
				//cout << "(" << i + 1 << ", " << j + 1 << ")" << endl;
			}
		}
	}

	//cout << pair << endl;
	//cout << b << endl;
	
	int maxOverlaps = 1;
	for (auto itr = pair.begin(); itr != pair.end(); itr++) {
		int np1 = itr->x, np2 = itr->y;
		auto inter = intersection(p[np1], p[np2]);
		
		int overlaps[2] = { 2, 2 };
		for (int i = 0; i < n; i++) {
			if (!b[i] || i == np1 || i == np2) continue;
			if (distance(inter.first, p[i]) <= 1.0 + 1e-6) overlaps[0]++;
			if (distance(inter.second, p[i]) <= 1.0 + 1e-6) overlaps[1]++;
		}
		maxOverlaps = max(maxOverlaps, max(overlaps[0], overlaps[1]));
	}

	cout << maxOverlaps << endl;

	return true;
}

int main()
{
	while (AOJ0090()) {

	}

	return 0;
}