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<algorithm>
#include<iostream>
#include<string>
#include<set>
using namespace std;
string face[6];
int n;
int main(){
  while(cin >> n, n){
    set<string> ans;
    for(int j = 0;j < n;j++){
      cin >> face[0] >> face[1] >> face[2] >> face[3] >> face[4] >> face[5];
      string p;
      for(int i = 0;i < 4;i++){
	if(face[0] == "Blue")break;
	swap(face[0], face[1]);
	swap(face[1], face[5]);
	swap(face[5], face[4]);
      }
      for(int i = 0;i < 4;i++){
	if(face[0] == "Blue")break;
	swap(face[0], face[2]);
	swap(face[2], face[5]);
	swap(face[5], face[3]);
      }
      for(int i = 1;i < 5;i++){
	if(i == 1)p = face[i];
	p = min(p, face[i]);
      }
      while(face[1] != p){
	swap(face[1], face[2]);
	swap(face[2], face[4]);
	swap(face[4], face[3]);
      }
      string res ="";
      for(int i = 0;i < 6;i++){
	res += face[i][0];
      }
      ans.insert(res);
    }
    cout << n - ans.size() << endl;
  }
  return 0;
}

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

using namespace std;

void rotate(string& a,string& b,string& c,string& d)
{
	string temp=a;
	a=b;
	b=c;
	c=d;
	d=temp;
}
void turnx(vector<string>& d)
{
	rotate(d[0],d[2],d[5],d[3]);
}
void turny(vector<string>& d)
{
	rotate(d[0],d[4],d[5],d[1]);
}
void turnz(vector<string>& d)
{
	rotate(d[1],d[3],d[4],d[2]);
}
void turnmin(vector<string>& d)
{
	vector<string> res=d;
	for(int i=0;i<6;i++){
		for(int j=0;j<4;j++){
			res=min(res,d);
			turnz(d);
		}
		(i&1?turnx:turny)(d);
	}
	d=res;
}

int main()
{
	for(int n;cin>>n,n;){
		vector<vector<string> > ds(n,vector<string>(6));
		for(int i=0;i<n;i++)
			for(int j=0;j<6;j++)
				cin>>ds[i][j];
		
		for(int i=0;i<n;i++)
			turnmin(ds[i]);
		
		sort(ds.begin(),ds.end());
		ds.erase(unique(ds.begin(),ds.end()),ds.end());
		
		cout<<n-ds.size()<<endl;
	}
	
	return 0;
}

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

struct BOX {
  string top;
  string back, left, right, head;
  string buttom;
  bool operator==(const BOX& b) const {
    return(top    == b.top   &&
           back   == b.back  &&
           left   == b.left  &&
           right  == b.right &&
           head   == b.head  &&
           buttom == b.buttom);
  }
};
struct UnionFind{
  vector< int > data;
  UnionFind(int sz) {
    data.assign(sz, -1);
  }
  int Find(int k) {
    return(data[k] < 0 ? k : data[k] = Find(data[k]));
  }
  void Unite(int a, int b) {
    a = Find(a), b = Find(b);
    if(a == b) return;
    data[a] += data[b];
    data[b] = a;
  }
};

void Roll(BOX& B)
{
  string temp = B.head;
  B.head = B.right;
  B.right = B.back;
  B.back = B.left;
  B.left = temp;
}

void RoLL(BOX& B) {
  string temp = B.head;
  B.head = B.top;
  B.top = B.back;
  B.back = B.buttom;
  B.buttom = temp;
}

bool Myon(BOX& a, BOX& b)
{
  for(int k = 0; k < 4; k++) {
    Roll(a);
    for(int l = 0; l < 4; l++) {
      RoLL(a);
      if(a == b) return(true); 
    }
  }
  return(false);
}

int main()
{
  int n;
  vector< BOX > boxes;
  while(cin >> n, n) {
    UnionFind uf(n);

    boxes.resize(n);
    int ret = 0;

    for(int i = 0; i < n; i++) {
      BOX &b = boxes[i];
      cin >> b.top >> b.head >> b.right >> b.back >> b.left >> b.buttom;
    }
    for(int i = 0; i < n; i++) {
      for(int j = i + 1; j < n; j++) {
        if(Myon(boxes[i], boxes[j])) uf.Unite(i, j);
      }
    }
    for(int i = 0; i < n; i++) {
      ret += uf.Find(i) == i;
    }
    cout << n - ret << endl;
  }
}

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

int cheak(int n,string c[][6]){
    int cou=0;
    for (int i=0; i<n; i++) {
        for (int j=i+1; j<n; j++) {
            for (int a=0; a<4; a++) {
                if(c[i][0]==c[j][0]){
                    for (int b=0; b<4; b++) {
                        if(c[i][1]==c[j][1]&&c[i][2]==c[j][2]&&c[i][3]==c[j][3]&&c[i][4]==c[j][4]){
                            cou++;
                            break;
                        }
                        swap(c[i][1], c[i][3]);
                        swap(c[i][1], c[i][4]);
                        swap(c[i][1], c[i][2]);
                    }
                    break;
                }
                swap(c[i][0],c[i][3]);
                swap(c[i][0],c[i][5]);
                swap(c[i][0],c[i][2]);
            }
        }
    }
    return cou;
}

int main(){
    int n;
    string cube[30][6];
    while (1) {
        cin>>n;
        if(n==0)break;
        for (int i=0; i<n; i++) {
            for (int j=0; j<6; j++) {
                cin>>cube[i][j];
            }
        }
        cout<<cheak(n, cube)<<endl;
    }
    return 0;
}

C++: #include <iostream>
#include <set>
#include <vector>
#include <string>
using namespace std;
class Cube{
public:
	int c[6];
	Cube(){}
	bool operator == (const Cube &p) const{
		for(int i=0;i<6;i++)if(c[i]!=p.c[i])return false;
		return true;
	}
	void r1(){
		int tmp[6];
		for(int i=0;i<6;i++)tmp[i]=c[i];
		c[0]=tmp[4];
		c[1]=tmp[0];
		c[4]=tmp[5];
		c[5]=tmp[1];
		return;
	}
	void r2(){
		int tmp[6];
		for(int i=0;i<6;i++)tmp[i]=c[i];
		c[0]=tmp[2];
		c[2]=tmp[5];
		c[3]=tmp[0];
		c[5]=tmp[3];
		return;
	}
	void r3(){
		int tmp[6];
		for(int i=0;i<6;i++)tmp[i]=c[i];
		c[1]=tmp[3];
		c[2]=tmp[1];
		c[3]=tmp[4];
		c[4]=tmp[2];
		return;
	}
};
bool onaji(Cube &a,Cube &b){
	for(int i=0;i<4;i++){
		for(int j=0;j<4;j++){
			if(a==b)return true;
			a.r1();
		}
		a.r2();
	}
	a.r3();
	for(int j=0;j<4;j++){
		if(a==b)return true;
		a.r1();
	}
	a.r3();a.r3();
	for(int j=0;j<4;j++){
		if(a==b)return true;
		a.r1();
	}
	return false;
}
int GetID(string s){
	if(s=="Red")return 1;
	if(s=="Yellow")return 2;
	if(s=="Blue")return 3;
	if(s=="Magenta")return 4;
	if(s=="Green")return 5;
	if(s=="Cyan")return 6;
}
int main()
{
	int n;
	while(cin>>n&&n){
		Cube sta[30];
		vector<Cube> ans;
		for(int i=0;i<n;i++){
			string s;
			for(int j=0;j<6;j++){
				cin>>s;
				sta[i].c[j]=GetID(s);
			}
			bool neww=true;
			for(auto it=ans.begin();it<ans.end();it++){
				Cube tmp;tmp=ans.at(it-ans.begin());
				if(onaji(tmp,sta[i]))neww=false;
			}
			if(neww)ans.push_back(sta[i]);
		}
		cout<<n-(int)ans.size()<<endl;
	}
    
    return 0;
}