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<algorithm>
#include<string>

using namespace std;

struct Dice
{
  int c[6];
  void rot(int type){
    char newc[6];
    if( type == 0 ){ // front
      newc[2]=c[2];newc[3]=c[3];
      newc[0]=c[1];newc[1]=c[5];newc[4]=c[0];newc[5]=c[4];
    }
    if( type == 1 ){ // right
      newc[1]=c[1];newc[4]=c[4];
      newc[0]=c[3];newc[2]=c[0];newc[3]=c[5];newc[5]=c[2];
    }
    if( type == 2 ){ // hor
      newc[0]=c[0];newc[5]=c[5];
      newc[1]=c[2];newc[2]=c[4];newc[3]=c[1];newc[4]=c[3];
    }
    for(int i = 0; i < 6; ++i)c[i]=newc[i];
  }
  bool samePattern(Dice d)const{
    const int rots[] = {0,0,0,1,1,1, 1};
    for(int i = 0; i < sizeof(rots)/sizeof(*rots);++i){
      for(int j = 0; j < 4; ++j){
	if( same(d) ) return true;
	d.rot(2);
      }
      d.rot( rots[i] );
    }
    return false;
  }
  bool same(const Dice &d)const{
    for(int i = 0; i < 6; ++i){
      if( c[i] != d.c[i] ) return false;
    }
    return true;
  }
};
int main()
{
  while(true){
    int n;
    int ans = 0;
    cin >> n;
    if( n == 0 )break;
    Dice dice[n];
    bool inv[n];
    fill(inv,inv+n,false);
    for(int i = 0; i < n; ++i){
      for(int j = 0; j < 6; ++j){
	string s;
	cin >> s;
	if( s == "Cyan" )    dice[i].c[j]=0;
	if( s == "Yellow" )  dice[i].c[j]=1;
	if( s == "Red" )     dice[i].c[j]=2;
	if( s == "Magenta" ) dice[i].c[j]=3;
	if( s == "Green" )   dice[i].c[j]=4;
	if( s == "Blue" )    dice[i].c[j]=5;
      }
    }
   

    for(int i = 0; i < n; ++i){
      if( !inv[i] ){
	for(int j = i+1; j < n; ++j){
	  if( !inv[j] ){
	    if( dice[i].samePattern( dice[j] ) ){
	      inv[j]=true;
	    }
	  }
	}
      }
    }
    for(int i = 0; i < n; ++i){
      if( inv[i] ){
	++ans;
      }
    }
    cout << ans << endl;
  }
  return 0;
}

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

bool arrequshift(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;
}

bool arrequ(int a1[], int a2[], int size){
	if(arrequshift(a1, a2, size)) return true;
	for(int i = 0;i < size / 2;i++){
		swap(a2[i], a2[size - i - 1]);
	}
	if(arrequshift(a1, a2, size)) return true;
	return false;
}

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;
					}
				}
			}
		}
		cout << ans << endl;
	}
	return 0;
}