#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>

#define N_BIT (1<<24)

#define isDeleted(i,s) (s & (1<<i)) ? 1:0
#define removeDisc(i,j,s) (s | (1<<i) | (1<<j))


typedef struct data{
	int x;
	int y;
	int r;
	int c;
}disc;

int n;				//Disc????????°
int max;		//?????????????????°????????§???
int dp[N_BIT];		//??¶????????????????????¨??????????????¶????????¢?????¢?´¢????????§???????????????????????¨?????????
disc* d;			//Disc???????´?????????????


double discDistance(int i,int j){		//i,j?????????Disc????????¢?????????
	disc s = d[i];
	disc t = d[j];
	return sqrt((s.x-t.x)*(s.x-t.x) + (s.y-t.y)*(s.y-t.y));
}

/*
int isDeleted(int i,int s){			//??¶???s????????????i?????????Disc?????????????????§?????????
	int i_bit = 1 << i;				//i?????????????????????1
	return (s & i_bit) ? 1 : 0;			//s???i?????????1??????1,0??????0?????????
}
*/

int isRemovable(int i,int s){			//??¶???s????????????i?????????Disc?????????????????§?????????
	int k;
	if(isDeleted(i,s)){			//??¢?????????????????????0?????????
		return 0;
	}
	for(k=i-1;k>=0;k--){
		if(isDeleted(k,s)){		//k???????????¢??????????????????????£???°???
			continue;
		}
		if(d[i].r + d[k].r > discDistance(i,k)){		//?????¢?????¢???????????????
			return 0;
		}
	}
	return 1;
}

int deletedDiscNumber(int s){		//??¶???s???????????????????????????Disc????????°
	int cnt = 0;
	while(s){		//s=0??????????????§?????????
		if(s & 1){		//s????????????????????????1
			cnt++;		//????????????
		}
		s = s >> 1;		//????????????(??????????????????????¶????)
	}
	return cnt;
}

/*
int removeDisc(int i,int j,int s){		//i,j?????????Disc?????????????????¶???????????????????????????
	int i_bit = 1 << i;				//i?????????????????????1
	int j_bit = 1 << j;				//j?????????????????????1
	return (s | i_bit | j_bit);			//i,j?????????????????????1(????????????)?????????
}
*/

void initDP(){		//dp??????????????????
	int i;
	for(i=0;i<N_BIT;i++){
		dp[i] = 0;			//??¨????????¢?´¢??¨??????
	}
}

//??±???????????¢?´¢(?????¢????????°)
void dfsearch(int s){		//s?????¶????????????
	int i,j,deleted;
	if(dp[s] == 1){		//??¶???s?????¢?????¢?´¢????????§????????°?¨?????????????
		return;
	}else{
		dp[s] = 0;		//??¢?´¢????????¨??????
	}
	deleted = deletedDiscNumber(s);		//??¶???s??§?????????????????????Disc?????°
	if(deleted > max){
		max = deleted;			//?????§????????´??°
	}
	if(n - max <= 1){		//Disc?????????1?????\?????????????????\???????????????
		return;
	}
	for(i=0;i<n;i++){
		if(isRemovable(i,s)){		//??¶???s????????????i?????????Disc???????????????Disc???????????£??????????????´???
			for(j=i+1;j<n;j++){
				if(isRemovable(j,s) && d[i].c == d[j].c){	//??¶???s????????????j?????????Disc???????????????Disc???????????£????????????,?????????j????????¨?????????????????´???
					dfsearch(removeDisc(i,j,s));		//i,j?????????Disc????????????????????°
					if(n - max <= 1){		//Disc?????????1?????\?????????????????\???????????????
						return;
					}
				}
			}
		}
	}
}

int main(void){
	int i;
	clock_t t1 = clock();
	while(1){
		scanf("%d",&n);
		if(n == 0){
			break;
		}
		d = (disc*)malloc(n*sizeof(disc));		//Disc?????????
		for(i=0;i<n;i++){
			scanf("%d %d %d %d",&d[i].x,&d[i].y,&d[i].r,&d[i].c);
		}
		max = 0;		//?????§???????????????
		initDP();		//??¢?´¢??????????????????
		dfsearch(0);	//s=0:??¨??????Disc????????¨????????¶???
		printf("%d\n",max);
		free(d);
	}
	clock_t t2 = clock();
	printf("%f\n",(double)(t2-t1)/CLOCKS_PER_SEC);
	return 0;
}