Go: package main

import (
	"bufio"
	"os"
	"strconv"
	"strings"
		"reflect"
	"fmt"
)

var scanner = bufio.NewScanner(os.Stdin)

func main() {
	// 上面の色を固定してから、左右方向に回転して一致するものがあるかを調べる
	round := [][]int{
		{1,2,3,4,5,6}, {1,3,5,2,4,6}, {1,4,2,5,3,6}, {1,5,4,3,2,6}, // c1を上面に固定して回転
		{2,6,3,4,1,5}, {2,3,1,6,4,5}, {2,1,4,3,6,5}, {2,4,6,1,3,5}, // c2を上面に固定して回転
		{3,1,2,5,6,4}, {3,2,6,1,5,4}, {3,5,1,6,2,4}, {3,6,5,2,1,4}, // c3を上面に固定して回転
		{4,1,5,2,6,3}, {4,2,1,6,5,3}, {4,5,6,1,2,3}, {4,6,2,5,1,3}, // c4を上面に固定して回転
		{5,1,3,4,6,2}, {5,3,6,1,4,2}, {5,4,1,6,3,2}, {5,6,4,3,1,2}, // c5を上面に固定して回転
		{6,2,4,3,5,1}, {6,3,2,5,4,1}, {6,5,3,4,2,1}, {6,4,5,2,3,1}, // c6を上面に固定して回転

	}
	for scanner.Scan() {
		n, _ := strconv.Atoi(scanner.Text())
		if n == 0 {
			break
		}
		cubes := make([][]string, n)
		for i := 0; i < n; i++ {
			scanner.Scan()
			cubes[i] = strings.Split(scanner.Text(), " ")
		}
		check := func(a, b int) bool {
			tmp := make([]string, 6)
			for i := 0; i < 24; i++ {
				for j := 0; j < 6; j++ {
					tmp[j] = cubes[b][round[i][j]-1]
				}
				if reflect.DeepEqual(tmp, cubes[a]) {
					return true
				}
			}
			return false
		}
		tbl := make([]int, n)
		// 全ての組み合わせを調べる
		for i := 0; i < n; i++ {
			if tbl[i] == 1 {
				continue
			}
			for j := i+1; j < n; j++ {
				if check(i, j) {
					tbl[j] = 1
				}
			}
		}
		fmt.Println(sum(tbl))
	}
}

func sum(a []int) int {
	ret := 0
	for _, v := range a {
		ret += v
	}
	return ret
}

C++: #include <iostream>
#include <string>
#include <algorithm>

using namespace std;
bool func2(string s1[7], string s2[7]);
bool func3(string s1[7], string s2[7]);
void rtt(string s[7]);
void swp(string s[7], int u, int v);

bool func(string s1[7], string s2[7])
{
	if(!func2(s1, s2)){
		return false;
	}
	
	swp(s2, 1, 6);
	if(!func2(s1, s2)){
		return false;
	}
	swp(s2, 1, 6);
	
	swp(s2, 1, 2);
	swp(s2, 5, 6);
	if(!func2(s1, s2)){
		return false;
	}
	
	swp(s2, 2, 5);
	if(!func2(s1, s2)){
		return false;
	}
	swp(s2, 2, 5);
	swp(s2, 1, 2);
	swp(s2, 5, 6);
	
	swp(s2, 1, 3);
	swp(s2, 4, 6);
	if(!func2(s1, s2)){
		return false;
	}
	swp(s2, 3, 4);
	if(!func2(s1, s2)){
		return false;
	}
	swp(s2, 3, 4);
	swp(s2, 1, 3);
	swp(s2, 4, 6);
	
	return true;
}

bool func2(string s1[7], string s2[7])
{
	string str;
	
	if(!func3(s1, s2)){
		return false;
	}
	rtt(s2);
	if(!func3(s1, s2)){
		return false;
	}
	rtt(s2);
	if(!func3(s1, s2)){
		return false;
	}
	rtt(s2);
	if(!func3(s1, s2)){
		return false;
	}
	rtt(s2);
	
	swp(s2, 3, 4);
	if(!func3(s1, s2)){
		return false;
	}
	swp(s2, 3, 4);
	swp(s2, 2, 5);
	if(!func3(s1, s2)){
		return false;
	}
	swp(s2, 2, 5);
	
	return true;
}

bool func3(string s1[7], string s2[7])
{
	bool f = false;
	for(int i = 1; i <= 6; i++){
		if(s1[i] != s2[i]){
			f = true;
			break;
		}
	}
	
	return f;
}

void rtt(string s[7])
{
	string str;
	str = s[2];
	s[2] = s[3];
	s[3] = s[4];
	s[4] = s[5];
	s[5] = str;
	
	return ;
}

void swp(string s[7], int u, int v)
{
	string str;
	str = s[u];
	s[u] = s[v];
	s[v] = str;
	
	return ;
}

int main()
{
	int n, c;
	string cubes[31][7];
	bool f[31];
	
	while(cin>>n&&n){
		c = 0;
		fill(f, f+31, true);
		for(int i = 0; i < n; i++){
			for(int j = 1; j <= 6; j++){
				cin >> cubes[i][j];
			}
		}
		
		for(int i = 0; i < n; i++){
			for(int j = i+1; j < n && f[i]; j++){
				f[j] = func(cubes[i], cubes[j]);
			}
		}
		
		for(int i = 0; i < n; i++){
			if(f[i]){
				c++;
			}
		}
		cout << n-c << endl;
	}
	
	return 0;
}

C++: #include <iostream>
#include <string>

using namespace std;

class Box{
public:
	string c1,c2,c3,c4,c5,c6;

	bool operator==( const Box& lhs ){
		return c1 == lhs.c1 && c2 == lhs.c2 && c3 == lhs.c3 && c4 == lhs.c4 && c5 == lhs.c5 && c6 == lhs.c6;
	}

	void rotatet(){
		string d1,d2;
		d1 = c1;
		c1 = c5;
		d2 = c2;
		c2 = d1;
		c5 = c6;
		c6 = d2;
	}

	void rotatey(){
		string d1,d2;
		d1 = c1;
		c1 = c3;
		d2 = c4;
		c4 = d1;
		c3 = c6;
		c6 = d2;
	}
};


int main( void )
{
	int n;
	Box box[31];
	bool check[31];

	while( cin >> n && n != 0 ){
		for( int i = 0;i < 31;i++ ) check[i] = false;
		for( int i = 0;i < n;i++ ){
			cin >> box[i].c1 >>  box[i].c2 >>  box[i].c3 >>  box[i].c4 >>  box[i].c5 >>  box[i].c6; 
		}

		int count = 0;

		for( int i = 0;i < n;i++ ){
			check[i] = true;
			for( int j = i;j < n;j++ ){
				if( check[j] == false ){
					for( int k = 0;k < 4;k++ ){
						box[j].rotatet();
						for( int n = 0;n < 4;n++ ){
							box[j].rotatey();
							if( box[i] == box[j] ){
								count++;
								check[j] = true;
								goto END;
							}
						}
					}
				}
END:;
			}
		}
		cout << count << endl;
	}
				

	return 0;
}

C++: #include<bits/stdc++.h>
#define rep(i,n)for(int i=0;i<(n);i++)
using namespace std;
typedef vector<string>cube;

cube s[30];
bool used[30];
bool equal(cube a, cube b) {
	rep(i, 6) {
		if (a[i] != b[i])return false;
	}
	return true;
}
bool judge(cube a, cube b) {
	cube c;
	rep(i, 6) {
		c = a; a[3] = c[0]; a[0] = c[2]; a[2] = c[5]; a[5] = c[3];
		rep(j, 4) {
			c = a; a[3] = c[1]; a[1] = c[2]; a[2] = c[4]; a[4] = c[3];
			if (equal(a, b))return true;
		}
	}
	return false;
}
int main() {
	int n;
	while (cin >> n, n) {
		rep(i, n) {
			s[i] = cube(6);
			rep(j, 6)cin >> s[i][j];
		}
		vector<int>v[30];
		rep(i, n)for (int j = i + 1; j < n; j++) {
			if (judge(s[i], s[j])) {
				v[i].push_back(j);
			}
		}
		int cnt = 0;
		memset(used, 0, sizeof(used));
		rep(i, n) {
			if (used[i])continue;
			cnt++;
			for (int j : v[i])used[j] = true;
		}
		printf("%d\n", n - cnt);
	}
}

C++: #include <bits/stdc++.h>
using namespace std;

struct Dice {
	vector<int> val;
	Dice(){ val.resize(6); }
	bool operator == (const Dice &t) const {
		return val == t.val;
	}
	bool operator != (const Dice &t) const {
		return val != t.val;
	}
	bool operator < (const Dice &t) const {
		return val < t.val;
	}
	void rotate_right(){
		int tmp = val[1];
		val[1] = val[2];
		val[2] = val[4];
		val[4] = val[3];
		val[3] = tmp;
	}
	void roll_front(){
		int tmp = val[0];
		val[0] = val[1];
		val[1] = val[5];
		val[5] = val[4];
		val[4] = tmp;
	}
	void roll_right(){
		int tmp = val[0];
		val[0] = val[3];
		val[3] = val[5];
		val[5] = val[2];
		val[2] = tmp;
	}
	vector<Dice> all_pattern(){
		vector<Dice> res;
		Dice d = *this;
		for (int i = 0; i < 6; i++){
			for (int j = 0; j < 4; j++){
				res.push_back(d);
				d.rotate_right();
			}
			if (i == 0) d.roll_front();
			else if (i < 5) d.roll_right();
			else d.roll_front();
		}
		return res;
	}
};


map<string, int> ctoi;
int n;
vector<Dice> dices;

bool check(const vector<Dice> &A, const vector<Dice> &B)
{
	for (int i = 0; i < A.size(); i++){
		for (int j = 0; j < B.size(); j++){
			if (A[i] == B[j]) return true;
		}
	}
	return false;
}

void solve()
{
	vector<vector<Dice> > pats;
	for (int i = 0; i < n; i++){
		pats.push_back(dices[i].all_pattern());
	}
	
	int res = 0;
	
	for (int i = 0; i < n; i++){
		for (int j = i + 1; j < n; j++){
			vector<Dice> &A = pats[i];
			vector<Dice> &B = pats[j];
			if (check(A, B)){
				res++;
				continue;
			};
		}
	}
	
	printf("%d\n", res);
}

int main()
{
	ctoi["Red"] = 0;
	ctoi["Yellow"] = 1;
	ctoi["Blue"] = 2;
	ctoi["Magenta"] = 3;
	ctoi["Green"] = 4;
	ctoi["Cyan"] = 5;
	
	while (scanf("%d", &n), n){
		dices.clear();
		for (int i = 0; i < n; i++){
			Dice d;
			for (int j = 0; j < 6; j++){
				string str;
				cin >> str;
				d.val[j] = ctoi[str];
			}
			dices.push_back(d);
		}
		solve();
	}
	
	return 0;
}