#include <stdio.h>
#include <list>
#include <string.h>
#include <algorithm>
#include <vector>

using namespace std;

#define SQ(x) ((x) * (x))

typedef struct {
	int index;
	int degree;
} SORTDATA;

bool operator<(const SORTDATA& a, const SORTDATA& b)
{
	return (a.degree > b.degree);
}

int n;
char G[100][100];
int ans;
SORTDATA sort_data[100];
char next[100];

int check(char use[] , int depth)
{
	int next_count;
	int i, j;
	
	/*for (int i = 0; i < depth; i++){
		printf("%d ", use[i]);
	}
	puts("");
	*/
	if (depth > ans){
		ans = depth;
	}
	
	memset(next, 1, sizeof(next));
	
	next_count = n;
	for (i = 0; i < n; i++){
		if (sort_data[i].degree <= ans - 1){
			break;
		}
		for (j = 0; j < depth; j++){
			if (G[sort_data[i].index][use[j]] == 0 && next[sort_data[i].index] != 0){
				next[sort_data[i].index] = 0;
				next_count--;
			}
		}
	}
	if (i < n){
		next[sort_data[i].index] = -1;
		next_count -= n - i;
	}
	
	if (next_count == 0){
		return (0);
	}
	
	for (i = 0; i < n; i++){
		if (next[sort_data[i].index] == -1) break;
		if (next[sort_data[i].index] != 0){
			use[depth] = sort_data[i].index;
			check(use, depth + 1);
		}
	}
	
	return (0);
}

int main(void)
{
	double x[100], y[100];
	char use[100];
	
	while (1){
		scanf("%d", &n);
		if (n == 0){
			break;
		}
		
		memset(G, 0 , sizeof(G));
		memset(sort_data, 0, sizeof(sort_data));
		
		for (int i = 0; i < n; i++){
			scanf("%lf,%lf", &x[i], &y[i]);
		}
		
		for (int i = 0; i < n; i++){
			for (int j = i + 1; j < n; j++){
				if (SQ(x[i] - x[j]) + SQ(y[i] - y[j]) <= 4.0){
					G[i][j] = G[j][i] = 1;
					sort_data[i].degree++;
					sort_data[j].degree++;
				}
			}
			sort_data[i].index = i;
		}
		sort(sort_data, sort_data + n);
		
		memset(use, 0, sizeof(use));
		ans = 1;
		for (int i = 0; i < n; i++){
			
			if (sort_data[i].degree > ans - 1){
				use[0] = sort_data[i].index;
				check(use, 1);
			}
			else {
				break;
			}
		}
		printf("%d\n", ans);
	}
	
	return (0);
}