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<cstdio>
#include<string.h>
using namespace std;
int main() {
	int a, b[101][101] = { 0 }, ruio = 0;
	char str[101];
	while (1) {
		cin >> a;
		if (a == 0)return 0;
		ruio = a;
		for (int i = 1; i <= a; i++) {
			for (int j = 1; j <= 6; j++) {
				scanf("%s", str);
				if (strstr(str, "Red") != NULL) {
					b[i][j] = 1;
				}
				if (strstr(str, "Yellow") != NULL) {
					b[i][j] = 2;
				}
				if (strstr(str, "Blue") != NULL) {
					b[i][j] = 3;
				}
				if (strstr(str, "Magenta") != NULL) {
					b[i][j] = 4;
				}
				if (strstr(str, "Green") != NULL) {
					b[i][j] = 5;
				}
				if (strstr(str, "Cyan") != NULL) {
					b[i][j] = 6;
				}
			}
		}
		for (int i = 1; i <= a; i++) {
			for (int j = 1; j <= 6; j++) {
				cout << b[i][j] << ",";
			}
			cout << endl;
		}
		int tatuo = 0;
		for (int i = 1; i <= a; i++) {
			for (int j = 1; j <= a; j++) {
				if (j != i && b[j][1] != -1 &&b[i][1]!=-1) {
					if (b[i][1] + b[i][6] == b[j][1] + b[j][6]) {
						if (b[i][3] + b[i][4] == b[j][3] + b[j][4]) {
							if (b[i][2] + b[i][5] == b[j][2] + b[j][5]) {
								b[i][1] = -1;
								ruio--;
								tatuo++;
							}
							if (tatuo > 0)break;
						}
						if (tatuo > 0)break;
					}
					if (tatuo > 0) break;
				}
				if (tatuo > 0) {
					tatuo = 0;
					break;
				}
			}
		}
		cout << a-ruio << endl;
	}
}

C++: #include <iostream> 
#include <sstream> 
#include <iomanip> 
#include <algorithm> 
#include <cmath> 
#include <string> 
#include <vector> 
#include <list> 
#include <queue> 
#include <stack> 
#include <set> 
#include <map> 
#include <bitset> 
#include <numeric> 
#include <climits> 
#include <cfloat> 
using namespace std; 

class Dice
{
public:
    vector<char> pip; // ì¼kãºÌÚ
    Dice(){
        pip.assign(6, -1);
    }
    void roll(int d){ // ì¼kE¶Éñ]
        int dir[][4] = {{4,2,5,0},{4,3,5,1},{4,0,5,2},{4,1,5,3},{0,3,2,1},{0,1,2,3}};
        char tmp = pip[dir[d][0]];
        for(int i=0; i<3; ++i)
            pip[dir[d][i]] = pip[dir[d][i+1]];
        pip[dir[d][3]] = tmp;
    }
    bool operator==(const Dice& d) const{
        return pip == d.pip;
    }
};

bool same(Dice& dice1, Dice& dice2)
{
    for(int i=0; i<6; ++i){
        if(i < 4)
            dice1.roll(0);
        else{
            dice1.roll(1);
            if(i == 5)
                dice1.roll(1);
        }
        for(int j=0; j<4; ++j){
            dice1.roll(4);
            if(dice1 == dice2)
                return true;
        }
    }
    return false;
}

int main()
{
    for(;;){
        int n;
        cin >> n;
        if(n == 0)
            return 0;

        vector<Dice> dice(n);
        for(int i=0; i<n; ++i){
            vector<string> s(6);
            for(int j=0; j<6; ++j)
                cin >> s[j];

            dice[i].pip[4] = s[0][0];
            dice[i].pip[0] = s[1][0];
            dice[i].pip[1] = s[2][0];
            dice[i].pip[3] = s[3][0];
            dice[i].pip[2] = s[4][0];
            dice[i].pip[5] = s[5][0];
        }

        int ret = 0;
        for(int i=0; i<n; ++i){
            for(int j=i+1; j<n; ++j){
                if(same(dice[i], dice[j])){
                    ++ ret;
                    break;
                }
            }
        }
        cout << ret << endl;
    }
}

C++: #include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<map>
#include<set>
#include<utility>
#include<cmath>
#include<cstring>
#include<queue>
#include<cstdio>
#include<sstream>
#define loop(i,a,b) for(int i=a;i<b;i++) 
#define rep(i,a) loop(i,0,a)
#define pb push_back
#define mp make_pair
#define all(in) in.begin(),in.end()
const double PI=acos(-1);
const double EPS=1e-10;
const int inf=1e8;
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int> pii;
struct UnionFind{
    vector<int> data;
    UnionFind(int size) : data(size, -1) {}
    bool unionSet(int x,int y){
        x=root(x);y=root(y);
        if(x==y)return 0;
        if(data[y]<data[x])swap(x,y);
        data[x]+=data[y],data[y]=x;
        return 1;
    }
    bool findSet(int x,int y){
        return root(x)==root(y);
    }
    int root(int x){
        return data[x]<0 ? x : data[x]=root(data[x]);
    }
    int size(int x){
        return -data[root(x)];
    }
};
int main(){
	int n;
	while(cin>>n,n){
		vector<vector<string> >in(n,vector<string>(6));
		rep(i,n)rep(j,6)cin>>in[i][j];
		int a[]={3,1,0,5,4,2};
		rep(i,n){
			if(in[i][1]!="Blue"&&in[i][4]!="Blue")
			while(in[i][0]!="Blue"){
				vector<string>tmp(6);
				rep(j,6)tmp[j]=in[i][a[j]];
				in[i]=tmp;
			}
			
		}
		int b[]={4,0,2,3,5,1};
		rep(i,n){
			while(in[i][0]!="Blue"){
				vector<string>tmp(6);
				rep(j,6)tmp[j]=in[i][b[j]];				
				in[i]=tmp;
			}
		}
		UnionFind uf(n);
		int co=0;
		rep(i,n)rep(j,n)if(i!=j&&in[i][5]==in[j][5]){
			int c[]={0,3,1,4,2,5};
			while(in[i][1]!=in[j][1]){
				vector<string>tmp(6);
				rep(k,6)tmp[k]=in[j][c[k]];
				in[j]=tmp;
			}
			bool h=true;
			rep(k,6)if(in[i][k]!=in[j][k])h=false;
			if(h){
				if(!uf.findSet(i,j))co++;
				uf.unionSet(i,j);
			}
		}
		cout<<co<<endl;
	}
}

C++: #include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#define lol(i,n) for(int i=0;i<n;i++)
#define mod 1000000007
typedef long long ll;
using namespace std;
string s[50][6];
int d[12][6]={
  {0,1,2,3,4,5},
  {0,2,3,4,1,5},
  {0,3,4,1,2,5},
  {0,4,1,2,3,5},
  
  {0,1,2,3,4,5},
  {3,1,0,5,4,2},
  {5,1,3,2,4,0},
  {2,1,5,0,4,3},
  
  {0,1,2,3,4,5},
  {1,4,2,3,5,0},
  {4,5,2,3,0,1},
  {5,0,2,3,1,4}
};
int main(){
  int n;
  while(cin>>n&&n){
    int ans=0;
    lol(i,n){
      lol(j,6)cin>>s[i][j];
      bool same=false;
      lol(j,i){
	lol(r,12){
	  bool ok=true;
	  lol(k,6){
	    if(s[i][k]!=s[j][d[r][k]])ok=false;
	  }
	  if(ok)same=true;
	}
      }
      if(same)ans++;
    }
    cout<<ans<<endl;
  }
  return 0;
}