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>
#define rep(i, n) for ( int i = 0; i < n; i++ )
using namespace std;
#define MAX 100
class Cube{
    public:
    string f[6];
    Cube(){}
    void roll_z(){ roll(1, 2, 4, 3);}
    void roll_y(){ roll(0, 2, 5, 3);}
    void roll_x(){ roll(0, 1, 5, 4);}
    void roll(int i, int j, int k, int l){
	string t = f[i]; f[i] = f[j]; f[j] = f[k]; f[k] = f[l]; f[l] = t;
    }
};

Cube C[MAX];
int n;

bool eq( Cube c1, Cube c2 ){
    rep(i, 6) if ( c1.f[i] != c2.f[i] ) return false;
    return true;
}

bool equal( Cube c1, Cube c2 ){
    rep(i, 6){
	rep(j, 4){
	    if ( eq(c1, c2) ) return true;
	    c1.roll_z();
	}
	if ( i % 2 == 0 ) c1.roll_y();
	else c1.roll_x();
    }
    return false;
}

main(){
    while( cin >> n && n ){
	rep(i, n) rep(j, 6) cin >> C[i].f[j];
	int cnt = 0;
	rep(i,n) {
	    bool hasSame = false;
	    for(int j=i+1; j<=n-1;j++) if (equal(C[i],C[j])) {hasSame = true;break;}
	    if ( !hasSame ) cnt++;
	}
	cout << n - cnt << endl;
    }
}

C++: #include<iostream>
#include<algorithm>
#include<string>
using namespace std;

bool arrequ(int a1[], int a2[], int size){
	for(int i = 0;i < size;i++){
		bool equ = true;
		for(int j = 0;j < size;j++){
			if(a1[j] != a2[(i + j) % size]){
				equ = false;
			}
		}
		if(equ) return true;
	}
	return false;
}

void arrrev(int arr[], int size){
	for(int i = 0;i < size / 2;i++){
		swap(arr[i], arr[size - i - 1]);
	}
}

int main_(){
	int a1[4], a2[4];
	for(int i = 0;i < 4;i++) cin >> a1[i];
	for(int i = 0;i < 4;i++) cin >> a2[i];
	cout << arrequ(a1, a2, 4) << endl;
	return 0;
}

int main(){
	while(1){
		int n;
		cin >> n;
		if(n == 0) break;
		int box[30][6] = {0};
		for(int i = 0;i < n;i++){
			for(int j = 0;j < 6;j++){
				string c;
				cin >> c;
				if(c == "Red") box[i][j] = 0;
				else if(c == "Yellow") box[i][j] = 1;
				else if(c == "Blue") box[i][j] = 2;
				else if(c == "Magenta") box[i][j] = 3;
				else if(c == "Green") box[i][j] = 4;
				else if(c == "Cyan") box[i][j] = 5;
			}
		}
		int set1[3][4] = {
			{1, 2, 4, 3}, 
			{0, 2, 5, 3},
			{0, 1 ,5, 4}
		};
		int set2[3][2] = {
			{0, 5},
			{1, 4},
			{2, 3}
		};
		int ans = 0;
		for(int i1 = 0;i1 < n;i1++){
			for(int i2 = i1 + 1;i2 < n;i2++){
				int a1[4] = {0}, a2[4] = {0}, b1[2] = {0}, b2[2] = {0};
				for(int j = 0;j < 3;j++){
					for(int k = 0;k < 4;k++){
						a1[k] = box[i1][set1[j][k]];
						a2[k] = box[i2][set1[j][k]];
					}
					for(int k = 0;k < 2;k++){
						b1[k] = box[i1][set2[j][k]];
						b2[k] = box[i2][set2[j][k]];
					}
					if(arrequ(a1, a2, 4) && arrequ(b1, b2, 2)){
						//cout << i1 << " & " << i2 << endl;
						ans++;
						break;
					}
					arrrev(a1, 4);
					arrrev(b1, 2);
					if(arrequ(a1, a2, 4) && arrequ(b1, b2, 2)){
						//cout << i1 << " & " << i2 << endl;
						ans++;
						break;
					}
				}
			}
		}
		cout << ans << endl;
	}
	return 0;
}

C++: #include<stdio.h>
int main(void)
{
	int n,i,j,z,A[101]={0};
   char c1[101][101],c2[101][101],c3[101][101],c4[101][101],c5[101][101],c6[101][101];
   scanf("%d",&n);
    while(n!=0){
		for(i=0;i<n;i++){
		A[i]=0;
		}
    for(i=0;i<n;i++){
        scanf("%s %s %s %s %s %s",c1[i],c2[i],c3[i],c4[i],c5[i],c6[i]);
    }
	z=0;
    for(i=0;i<n-1;i++){
        for(j=i+1;j<n;j++){
			if(A[j]==1) continue;
        if(c1[i][0]==c1[j][0] && c2[i][0]==c2[j][0]&& c3[i][0]==c3[j][0] && c4[i][0]==c4[j][0] && c5[i][0]==c5[j][0] && c6[i][0]==c6[j][0]){
            z=z+1;
			//printf("%d %d\n",i,j);
			A[j]=1;
        }
        else if(c4[i][0]==c4[j][0] && c1[i][0]==c1[j][0] && c3[i][0]==c3[j][0] && c6[i][0]==c6[j][0]){
            if(c5[i][0]==c5[j][0] && c2[i][0]==c2[j][0]){
                z=z+1;
				A[j]=1;
            }
        }
        else if(c4[i][0]==c6[j][0] && c1[i][0]==c3[j][0] && c3[i][0]==c1[j][0] && c6[i][0]==c4[j][0]){
            if(c5[i][0]==c2[j][0] && c2[i][0]==c5[j][0]){
                z=z+1;
				A[j]=1;
            }
        }
        else if(c6[i][0]==c6[j][0] && c3[i][0]==c3[j][0] && c1[i][0]==c1[j][0] && c4[i][0]==c4[j][0]){
            if(c5[i][0]==c5[j][0] && c2[i][0]==c2[j][0]){
                z=z+1;
				A[j]=1;
            }
        }
        else if(c6[i][0]==c4[j][0] && c3[i][0]==c1[j][0] && c1[i][0]==c3[j][0] && c4[i][0]==c6[j][0]){
            if(c2[i][0]==c5[j][0] && c5[i][0]==c2[j][0]){
                z=z+1;
				A[j]=1;
            }
        }
        else if(c2[i][0]==c2[j][0] && c1[i][0]==c1[j][0] && c5[i][0]==c5[j][0] && c6[i][0]==c6[j][0]){
            if(c4[i][0]==c4[j][0] && c3[i][0]==c3[j][0]){
                z=z+1;
				A[j]=1;
            }
        }
        else if(c2[i][0]==c6[j][0] && c1[i][0]==c5[j][0] && c5[i][0]==c1[j][0] && c6[i][0]==c2[j][0]){
            if(c4[i][0]==c3[j][0] && c3[i][0]==c4[j][0]){
                z=z+1;
				A[j]=1;
            }
        }
        else if(c6[i][0]==c6[j][0] && c5[i][0]==c5[j][0] && c1[i][0]==c1[j][0] && c2[i][0]==c2[j][0]){
            if(c3[i][0]==c3[j][0] && c4[i][0]==c4[j][0]){
                z=z+1;
				A[j]=1;
            }
        }
        else if(c6[i][0]==c2[j][0] && c5[i][0]==c1[j][0] && c1[i][0]==c5[j][0] && c2[i][0]==c6[j][0]){
            if(c3[i][0]==c4[j][0] && c4[i][0]==c3[j][0]){
                z=z+1;
				A[j]=1;
            }
        }
        }
    }
    printf("%d\n",z);
    scanf("%d",&n);
    }
    return 0;
}

C++: #include<cstdio>
#include<iostream>
#include<string>
#include<map>
#include<queue>
#include<set>

using namespace std;

#define rep(i,n) for(int i=0;i<n;i++)
#define reps(i,n) for(int i=1;i<=n;i++)

class S{
	public:
	vector<int> a;
	S(){}
	S(vector<int> a):a(a){}
	void x(){
		int tmp = a[0];
		a[0]=a[4];
		a[4]=a[5];
		a[5]=a[1];
		a[1]=tmp;
	}
	void y(){
		int tmp = a[1];
		a[1]=a[2];
		a[2]=a[4];
		a[4]=a[3];
		a[3]=tmp;
	}
	void z(){
		int tmp = a[0];
		a[0]=a[2];
		a[2]=a[5];
		a[5]=a[3];
		a[3]=tmp;
	}
};

int main(){
	while(1){
		int n;
		cin>>n;
		if(n==0)break;
		
		map<vector<int>,int> memo;
		
		rep(i,n){
			vector<int> b;
			rep(j,6){
				string a;
				cin>>a;
				switch(a[0]){
					case 'C':b.push_back(0);break;
					case 'Y':b.push_back(1);break;
					case 'R':b.push_back(2);break;
					case 'M':b.push_back(3);break;
					case 'G':b.push_back(4);break;
					case 'B':b.push_back(5);break;
				}
			}
			
			S si = S(b);
			rep(j,4){
				si.x();
				rep(k,4){
					si.y();
					rep(p,4){
						si.z();
						memo[si.a]=1;
					}
				}
			}
		}
		
		printf("%d\n",n-(memo.size()/24));
		
	}
}