import java.util.*;

public class Target {
	public final static int MAX=1000;

	public static Point [] b = new Point[MAX];		// balloon locations

	public static Line [] lines = new Line[MAX/3];

	public static int nlines;

	public static int minLines;		// minimum number of lines used (set in bestCover)

	public static boolean onLine(Point p, Line l)
	{
		int dx = p.x-l.start.x;
		int dy = p.y-l.start.y;
	//cout << "     dx, dy = " << dx << ',' << dy << endl;
	//cout << " delx, dely = " << l.delx << ',' << l.dely << endl;
		if (dx*l.dely != dy*l.delx)
			return false;
		int dz = p.z-l.start.z;
		if (dz*l.dely != dy*l.delz)
			return false;
	//cout << "     dx, dz = " << dx << ',' << dz << endl;
	//cout << " delx, delz = " << l.delx << ',' << l.delz << endl;
		return (dx*l.delz == dz*l.delx);
	}

	public static void getLines(int n)	// determine lines which pass through 3 or more balloons
	{
		int i, j, k;
		int [] list = new int[MAX];
		int count;

		nlines = 0;
		for(i=0; i<n-2; i++) {
			list[0] = i;
			for(j=i+1; j<n-1; j++) {
				list[1] = j;
				count = 2;
				Point p = b[j];
				lines[nlines] = new Line();
				lines[nlines].start = b[i];
				lines[nlines].delx = p.x-lines[nlines].start.x;
				lines[nlines].dely = p.y-lines[nlines].start.y;
				lines[nlines].delz = p.z-lines[nlines].start.z;
				boolean found=false;
				for(k=0; k<n; k++) {
	//cout << "checking " << i << ',' << j << ',' << k << endl;
					if (onLine(b[k], lines[nlines])) {
						if (k == i || k == j)
							continue;
						else if (k<j)
							break;	// already found this line
						else  {
							found = true;
							list[count++] = k;
						}
					}
				}
				if (found) {
	//cout << "found line through balloons";
					lines[nlines].n = count;
					lines[nlines].list = new int[count];
					for(k=0; k<count; k++) {
						lines[nlines].list[k] = list[k];
	//cout << " " << list[k];
					}
						// insert new line in sorted order
						//    (dicreasing by # of balloons in line)
					for(k=nlines-1; k>=0; k--) {
						if (lines[k+1].n < lines[k].n)
							break;
						Line temp = lines[k+1];
						lines[k+1] = lines[k];
						lines[k] = temp;
					}
	//cout << endl;
					nlines++;
				}
			}
		}
	}

	public static void bestCover(int i, int numL, int numB, int hits[], int cover, int linesUsed)
	{
	//cout << "i, cover, linesUsed" << i << ',' << cover << ',' << linesUsed << endl;
		int j;

		if (i == numL || numB-cover <=2) {
			if (linesUsed + (numB-cover+1)/2 < minLines) {
				minLines = linesUsed + (numB-cover+1)/2;
			}
		}
		else if (linesUsed + (numB-cover)/lines[i].n >= minLines)
			return;
		else {
					// use line i;
			int newHits=0;
			for(j=0; j<lines[i].n; j++) {
				hits[lines[i].list[j]]++;
				if (hits[lines[i].list[j]] == 1)
					newHits++;
			}
			bestCover(i+1, numL, numB, hits, cover+newHits, linesUsed+1);
			for(j=0; j<lines[i].n; j++) {
				hits[lines[i].list[j]]--;
			}
					// don't use line i;
			bestCover(i+1, numL, numB, hits, cover, linesUsed);
		}
	}

	public static void main(String [] args)
	{
		Scanner in = new Scanner(System.in);
		int i, n, icase=0;

		n = in.nextInt();
		while (n != 0) {
			icase++;
			int [] hits = new int[n];
			for(i=0; i<n; i++) {
				b[i] = new Point();
				b[i].x = in.nextInt();
				b[i].y = in.nextInt();
				b[i].z = in.nextInt();
				hits[i] = 0;
			}
			getLines(n);
	//for(i=0; i<nlines; i++) {
	//cout << lines[i].n << ":";
	//for(int j=0; j<lines[i].n; j++)
	//cout << " " << lines[i].list[j];
	//cout << endl;
	//}
			minLines = (n+1)/2;
			bestCover(0, nlines, n, hits, 0, 0);
			System.out.println("Target set " + icase + " can be cleared using only " + minLines + " shots.");

			n = in.nextInt();
		}
	}
}

class Point
{
	public int x, y, z;
}

class Line
{
	public Point start;
	public int delx, dely, delz;
	public int n;		// number of balloons hit by line (>=3)
	public int [] list;	// list of balloons
}

