Problem:
And Then, How Many Are There?    To Mr. Solitarius, who is a famous solo play game creator, a new idea
occurs like every day.
His new game requires discs of various colors and sizes.    To start with, all the discs are randomly scattered around the
center of a table.
During the play, you can remove a pair of discs of the same color if
neither of them has any discs on top of it.
Note that a disc is not considered to be on top of another when they
are externally tangent to each other.     Figure D-1: Seven discs on the table     For example, in Figure D-1, you can only remove the two black
discs first and then their removal makes it possible to remove the two
white ones.
In contrast, gray ones never become removable.    You are requested to write a computer program that, for given colors,
sizes, and initial placings of discs, calculates the maximum number of discs
that can be removed.   Input   The input consists of multiple datasets, each being in the
following format and representing the state of a game just after all
the discs are scattered.    n  x 1  y 1  r 1  c 1  x 2  y 2  r 2  c 2 ...  x n  y n  r n  c n    The first line consists of a positive integer n representing
the number of discs.
The following n lines, each containing 4 integers separated by
a single space, represent the colors, sizes, and initial placings of
the n discs in the following manner:  ( x i , y i ), r i , and c i are
the xy -coordinates of the center, the radius, and the color index
number, respectively, of the i -th disc, and  whenever the i -th disc is put on top of the j -th
disc, i < j must be satisfied.      You may assume that every color index number is between 1 and 4,
inclusive, and at most 6 discs in a dataset are of the same
color.
You may also assume that the x - and y -coordinates of the
center of every disc are between 0 and 100, inclusive, and the radius
between 1 and 100, inclusive.    The end of the input is indicated by a single zero.   Output   For each dataset, print a line containing an integer indicating the
maximum number of discs that can be removed.   Sample Input  4
0 0 50 1
0 0 50 2
100 0 50 1
0 0 100 2
7
12 40 8 1
10 40 10 2
30 40 10 2
10 10 10 1
20 10 9 3
30 10 8 3
40 10 7 3
2
0 0 100 1
100 32 5 1
0  Output for the Sample Input  2
4
0

Solution (Python):
import math,string,itertools,fractions,heapq,collections,re,array,bisect,sys,random,time,copy,functools

sys.setrecursionlimit(10**7)
inf = 10**20
eps = 1.0 / 10**10
mod = 10**9+7
dd = [(-1,0),(0,1),(1,0),(0,-1)]
ddn = [(-1,0),(-1,1),(0,1),(1,1),(1,0),(1,-1),(0,-1),(-1,-1)]

def LI(): return [int(x) for x in sys.stdin.readline().split()]
def LI_(): return [int(x)-1 for x in sys.stdin.readline().split()]
def LF(): return [float(x) for x in sys.stdin.readline().split()]
def LS(): return sys.stdin.readline().split()
def I(): return int(sys.stdin.readline())
def F(): return float(sys.stdin.readline())
def S(): return input()
def pf(s): return print(s, flush=True)


def main():
    rr = []

    while True:
        n = I()
        if n == 0:
            break

        a = [LI() for _ in range(n)]
        s = [set() for _ in range(n)]
        d = collections.defaultdict(list)
        for i in range(n):
            d[a[i][3]].append(i)
            for j in range(i):
                k = (a[i][0] - a[j][0]) ** 2 + (a[i][1] - a[j][1]) ** 2
                l = (a[i][2] + a[j][2]) ** 2
                if k < l:
                    s[i].add(j)

        ps = None
        for v in d.values():
            l = len(v) // 2
            vs = set(map(lambda x: tuple(sorted([tuple(sorted([x[i*2], x[i*2+1]])) for i in range(l)])), itertools.permutations(v)))
            vl = list(vs)
            if ps is None:
                ps = vl
            else:
                ps = list(map(lambda x: list(x[0]) + list(x[1]),itertools.product(ps,vl)))

        r = 0
        for pa in ps:
            f = True
            ts = set(range(n))
            pas = set(pa)
            tr = 0
            while f:
                f = False
                for p in list(pas):
                    if len(ts & s[p[0]]) == 0 and len(ts & s[p[1]]) == 0:
                        ts.remove(p[0])
                        ts.remove(p[1])
                        pas.remove(p)
                        f = True
                        tr += 2
            if r < tr:
                r = tr

        rr.append(r)

    return '\n'.join(map(str, rr))



print(main())