#include <cstdio>
#include <cmath>
#include <cstring>
#include <cassert>
#include <iostream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <algorithm>
#include <map>

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

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

class Solve_ {
public:
  int operator () () {
    /*
    int res = 0;
    int valid[32] = {}; // not removed
    for(int i = 0; i < n; ++i) valid[i] = true;
    for(;;) {
      bool remove_flag = false;
      bool top[32]   = {}; // not overlaped
      for(int i = 0; i < n; ++i) top[i] = true;
      for(int i = 0; i < n; ++i) {
        if( not valid[i] ) continue;
        for(int j = 0; j < i; ++j) {
          if( not valid[j] ) continue;
          if( (x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j]) < (r[i] + r[j]) * (r[i] + r[j]) ) {
            top[i] = false;
          }
        }
      }
      for(int i = 0; i < n; ++i) {
        if( not valid[i] ) continue;
        if( not top[i] ) continue;
      }
      for(int i = 0; i < n; ++i) {
        if( not valid[i] ) continue;
        if( not top[i] ) continue;
        for(int j = i + 1; j < n; ++j) {
          if( not valid[j] ) continue;
          if( not top[j] ) continue;
          if( c[i] != c[j] ) continue;
          valid[i] = false;
          valid[j] = false;
          remove_flag = true;
          res += 2;
        }
      }
      if( not remove_flag ) break;
    }
    */
    for(int i = 0; i < (1 << 24); ++i) {
      memo[i] = 0;
    }
    bool valid[32] = {};
    for(int i = 0; i < n; ++i) valid[i] = true;
    int res = dfs(valid);
    return res;
  }
  int dfs(bool valid[32]) {
    int memoid = CalcMemoId(valid);
    if( memo[memoid] != 0 ) {
      return memo[memoid];
    }
    int res = 0;
    bool top[32];
    calc_top(valid, top);
    for(int i = 0; i < n; ++i) {
      if( not valid[i] ) continue;
      if( not top[i] ) continue;
      for(int j = 0; j < i; ++j) {
        if( not valid[j] ) continue;
        if( not top[j] ) continue;
        if( c[i] != c[j] ) continue;

        valid[i] = valid[j] = false;
        res = std::max(res, dfs(valid) + 2);
        valid[i] = valid[j] = true;
        if( res == 24 ) return res;
      }
    }
    memo[memoid] = res;
    return res;
  }
  void calc_top(bool valid[32], bool top[32]) {
    for(int i = 0; i < n; ++i) {
      top[i] = (valid[i] ? true : false);
    }
    for(int i = 0; i < n; ++i) {
      if( not valid[i] ) continue;
      for(int j = 0; j < i; ++j) {
        if( not valid[j] ) continue;
        if( (x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j]) < (r[i] + r[j]) * (r[i] + r[j]) ) {
          top[i] = false;
        }
      }
    }        
  }
  int CalcMemoId(bool valid[32]) {
    int res = 0;
    for(int i = 0; i < n; ++i) {
      if( valid[i] ) {
        res |= (1 << i);
      }
    }
    return res;
  }
private:
  int8_t memo[1<<24];
};
Solve_ Solve;

int main() {
  for(;;) {
    Load();
    if( n == 0 ) break;
    int res = Solve();
    printf("%d\n", res);
  }  
  
  return 0;
}

Measured memory_bytes: 19500