#include <stdio.h>
#include <stdbool.h>

#define MAX_NUM 24

#define SQUARE(x) ((x) * (x))
#define MAX(x, y) ((x) > (y) ? (x) : (y))

int n;
int x[MAX_NUM];
int y[MAX_NUM];
int r[MAX_NUM];
int c[MAX_NUM];

int overlap[MAX_NUM];

// bit
// i番の円盤がない（取り除いた）とき、LSBから数えてi桁目を1とする
char maxRemovableNum[1 << MAX_NUM];
bool isVisited[1 << MAX_NUM];

void init()
{
	int i;
	for (i = 0; i < 1 << MAX_NUM; ++i)
	{
		maxRemovableNum[i] = 0;
		isVisited[i] = false;
	}
}

bool overlapBetween(int a, int b) { return SQUARE(r[a] + r[b]) > SQUARE(x[a] - x[b]) + SQUARE(y[a] - y[b]); }

bool exist(int a, long stateNumber) { return (stateNumber & 1L << a) == 0L; }

bool isTop(int a, long stateNumber)
{
	int i;
	for (i = 0; i < a; ++i)
	{
		if (!exist(i, stateNumber)) { continue; }
		if (overlap[a] & 1 << i) { return false; }
	}

	return true;
}

char solve(long stateNumber)
{
	if (isVisited[stateNumber]) { return maxRemovableNum[stateNumber]; }

	int i, j;
	for (i = 0; i < n; ++i)
	{
		if (!exist(i, stateNumber) || !isTop(i, stateNumber)) { continue; }

		for (j = i + 1; j < n; ++j)
		{
			if (!exist(j, stateNumber) || !isTop(j, stateNumber) || c[i] != c[j]) { continue; }

			maxRemovableNum[stateNumber] = MAX(maxRemovableNum[stateNumber],
			                                   (char)(solve(stateNumber | 1 << i | 1 << j) + 2));
		}
	}

	isVisited[stateNumber] = true;
	return maxRemovableNum[stateNumber];
}

int main()
{
	while (true)
	{
		//region DataInput
		scanf("%d", &n);
		if (n == 0) { break; }

		init();

		int i, j;
		for (i = 0; i < n; ++i)
		{
			scanf("%d %d %d %d", &x[i], &y[i], &r[i], &c[i]);

			overlap[i] = 0;
			for (j = 0; j < i; ++j)
			{
				if (overlapBetween(i, j)) { overlap[i] |= 1 << j; }
			}
		}
		//endregion

		printf("%d\n", solve(0L));
	}

	return 0;
}
