Problem:
立方体の作品

芸術家品川は n 点の作品を出展するように依頼されました。そこで、立方体の 6 面をペンキで色付けしたものを作品として出展することにしました。作品は、Red、Yellow、Blue、Magenta、Green、Cyan の 6 色全てが使われていて、各面は 1 色で塗りつぶされています。品川は形が同じ立方体の作品でも色の配置の仕方を変え、異なる作品として n 点作成しました。

彼の友人であるあなたは、友人のよしみで作品を出展前に閲覧させてもらいましたが、そこであることに気が付きました。それらの作品の中に異なる色付けをされているように見えても、実は同じ色の組み合わせをした立方体が存在していたのです。このままでは、 n 点の作品を出展することできなくなってしまいます。

作成した作品の数と各作品の色の情報を入力とし、出展するためにあと何点必要かを出力するプログラムを作成してください。

立方体の各面の色は c1 から c6 までの記号で表され、 以下のような配置となっています。また、c1 から c6 のそれぞれは Red、Yellow、Blue、Magenta、Green、Cyan のいずれか 1 色となります。

Input

複数のデータセットの並びが入力として与えられます。 入力の終わりはゼロひとつの行で示されます。
各データセットは以下の形式で与えられます。

n
cube1
cube2
:
cuben

１行目に作品の数 n (1 ≤ n ≤ 30)、続く n 行に i 番目の作品の情報が与えられます。各作品の情報は次の形式で与えられます。

c1 c2 c3 c4 c5 c6

作品の色の配置 ci が空白区切りで与えられます。

データセットの数は 100 を超えません。

Output

データセットごとに、出展するのにあと何点の作品が必要かを１行に出力します。

Sample Input

3
Cyan Yellow Red Magenta Green Blue
Cyan Yellow Red Magenta Green Blue
Red Yellow Magenta Blue Green Cyan
4
Red Magenta Blue Green Yellow Cyan
Red Yellow Magenta Blue Green Cyan
Magenta Green Red Cyan Yellow Blue
Cyan Green Yellow Blue Magenta Red
0

Output for the Sample Input

1
1

Solution in JAVA (judge verdict: Accepted)

import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;

public class Main {
    static int ans;

    public static void main(String[] args) throws Exception {
        Scanner sc = new Scanner(System.in);
        Map<String, Integer> color = new HashMap<String, Integer>();
        color.put("Red", 1);
        color.put("Yellow", 2);
        color.put("Blue", 3);
        color.put("Magenta", 4);
        color.put("Green", 5);
        color.put("Cyan", 6);
        while (true) {
            int n = sc.nextInt();
            if (n == 0)
                break;
            Set<String> set = new HashSet<String>();
            for (int i = 0; i < n; i++) {
                Dice d = new Dice(color.get(sc.next()), color.get(sc.next()),
                        color.get(sc.next()), color.get(sc.next()),
                        color.get(sc.next()), color.get(sc.next()));
                for (int j = 0; j < 4; j++) {
                    d = d.North();
                    for (int k = 0; k < 4; k++) {
                        d = d.Right();
                        set.add(d.toString());
                    }
                }
                d = d.East();
                for (int k = 0; k < 4; k++) {
                    d = d.Right();
                    set.add(d.toString());
                }
                d = d.East().East();
                for (int k = 0; k < 4; k++) {
                    d = d.Right();
                    set.add(d.toString());
                }
            }
            System.out.println(n - set.size() / 24);
        }
    }
}

class Dice {
    Integer cs[] = new Integer[7];

    Dice(Integer c1, Integer c2, Integer c3, Integer c4, Integer c5, Integer c6) {
        cs[1] = c1;
        cs[2] = c2;
        cs[3] = c3;
        cs[4] = c4;
        cs[5] = c5;
        cs[6] = c6;
    }

    public Dice North() {
        return new Dice(cs[2], cs[6], cs[3], cs[4], cs[1], cs[5]);
    }

    public Dice East() {
        return new Dice(cs[4], cs[2], cs[1], cs[6], cs[5], cs[3]);
    }

    public Dice Right() {
        return new Dice(cs[1], cs[4], cs[2], cs[5], cs[3], cs[6]);
    }

    public String toString() {
        return Arrays.toString(cs);
    }
}