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<cstdio>
#include<string>
#include<iostream>
using namespace std;
class CUBE{
private:
	string men[6];
public:
	void spinl(){string temp;temp=men[0];men[0]=men[2];men[2]=men[5];men[5]=men[3];men[3]=temp;}
	void spinu(){string temp;temp=men[0];men[0]=men[1];men[1]=men[5];men[5]=men[4];men[4]=temp;}
	string get(int element){return men[element]; }
	void set(){cin>>men[0]>>men[1]>>men[2]>>men[3]>>men[4]>>men[5];}
};
CUBE *cube;
int main(){
	int n;
	int *flg;
	int counter=0;
	scanf("%d",&n);
	while(n!=0){
		//初期化
		counter=0;
		cube=new CUBE [n];
		//入力部
		flg=new int [n];
		for(int i=0;i<n;i++){
			cube[i].set();
			flg[i]=0;
		}
		//処理部
		for(int i=0;i<n;i++){
			for(int j=i+1;j<n;j++){
				if(cube[i].get(0)==cube[j].get(0)&&cube[i].get(1)==cube[j].get(1)&&cube[i].get(2)==cube[j].get(2)&&cube[i].get(3)==cube[j].get(3)&&cube[i].get(4)==cube[j].get(4)&&cube[i].get(5)==cube[j].get(5)){
					flg[j]=1;
				}
				else{
					for(int n1=0;n1<4;n1++){
						cube[j].spinl();
						for(int n2=0;n2<4;n2++){
							cube[j].spinu();
							if(cube[i].get(0)==cube[j].get(0)&&cube[i].get(1)==cube[j].get(1)&&cube[i].get(2)==cube[j].get(2)&&cube[i].get(3)==cube[j].get(3)&&cube[i].get(4)==cube[j].get(4)&&cube[i].get(5)==cube[j].get(5)){
								flg[j]=1;
							}
						}
					}
				}
			}
		}
		for(int i=0;i<n;i++){
			counter+=flg[i];
		}
		printf("%d\n",counter);
		delete []cube;
		scanf("%d",&n);
	}
	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 = 0; 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>
#include<vector>

#define REP(i, b, n) for(int i = b; i<(int)n; i++)
#define rep(i, n) REP(i, 0, n)

using namespace std;

enum{TOP=0,FRONT,RIGHT,LEFT,BACK,BOTTOM}; 
#define rotate_swap(x,a,b,c,d) swap(x.m[a],x.m[b]);swap(x.m[b],x.m[c]);swap(x.m[c],x.m[d]);
  
const int dy[] = {-1, 0, 1, 0};
const int dx[] = {0, 1, 0, -1};
 
class Dice{
public:
  int y, x;
  string m[6];
  Dice(){
    y = x = 0;
  }
  bool operator<(const Dice &a)const{
    rep(i,6)if (m[i] != a.m[i])return m[i] < a.m[i];
    return false;
  }
  bool operator==(const Dice &a)const{
    rep(i,6)if (m[i] != a.m[i])return false;
    return true;
  }
};
 
void rotate_r(Dice &x){
  x.x++;
  rotate_swap(x,TOP,LEFT,BOTTOM,RIGHT);
}
  
void rotate_l(Dice &x){
  x.x--;
  rotate_swap(x,TOP,RIGHT,BOTTOM,LEFT);
}
  
void rotate_f(Dice &x){
  x.y--;
  rotate_swap(x,TOP,BACK,BOTTOM,FRONT);
}
  
void rotate_b(Dice &x){
  x.y++;
  rotate_swap(x,TOP,FRONT,BOTTOM,BACK);
}
  
void rotate_cw(Dice &x){
  rotate_swap(x,BACK,LEFT,FRONT,RIGHT);
}
  
void rotate_ccw(Dice &x){
  rotate_swap(x,BACK,RIGHT,FRONT,LEFT);
}
  
vector<Dice> generate_all(Dice x){
  vector<Dice> res;
  rep(i,6){
    rep(j,4){
      res.push_back(x);
      rotate_cw(x);
    }
    if (i%2 == 0)rotate_r(x);
    else rotate_f(x);
  }
  return res;
}

int main() {
  while (true) {
    int n;
    cin >> n; 
    if (n == 0) break;
    vector<vector<Dice> > v;
    rep (i, n) {
      Dice dice;
      cin >> dice.m[TOP];
      cin >> dice.m[FRONT];
      cin >> dice.m[RIGHT];
      cin >> dice.m[LEFT];
      cin >> dice.m[BACK];
      cin >> dice.m[BOTTOM];
      v.push_back(generate_all(dice));
    }
    int res = 0;
    rep (i, n) {
      rep (j, i) rep (ii, 24) rep (jj, 24) {
	if (v[i][ii] == v[j][jj]) {
	  ++res;
	  goto next;
	}
      }
    next:;
    }
    cout << res << endl;
  }
  return 0;
}

C++: #include<algorithm>
#include<iostream>
#include<string>
#include<set>
using namespace std;
string a, b, c, d, e, f;
int n;
int main(){
  while(cin >> n, n){
    set<int> num;
    for(int i = 0;i < n;i++){
      cin >> a >> b >> c >> d >> e >> f;
      int p = (int)(b[0] + e[0]) * (int)(c[0] + d[0]) * (int)(a[0] + f[0]);
      if(((a<f) + (b<e) + (c<d)) % 3)p *= -1;
      num.insert(p);
    }
    cout << n - num.size() << endl;
  }
  return 0;
}

C++: #include<iostream>
#include<vector>
#include<map>
#include<set>
#define rep(i,n) for(int i=0;i<n;i++)
using namespace std;
typedef vector<int> D;
int R[][6]={{0,3,1,4,2,5},{2,1,5,0,4,3},{4,0,2,3,5,1}};
void rot(D &d,int a){
	D r(6); rep(i,6)r[i]=d[R[a][i]]; d=r;
}
int main(){
	map<char,int> M; M['R']=0,M['Y']=1,M['B']=2,M['M']=3,M['G']=4,M['C']=5;
	int n;
	while(cin>>n,n){
		set<D> s,alld; char b[9];
		rep(ii,n){
			D d(6),t(6);
			alld.clear();
			rep(jj,6)cin>>b,d[jj]=M[b[0]];
			rep(i,4)rep(j,4)rep(k,4){
				t=d;
				rep(p,i)rot(t,0);rep(q,j)rot(t,1);rep(r,k)rot(t,2);
				alld.insert(t);
			}
			s.insert(*alld.begin());
		}
		cout<<n-s.size()<<endl;
	}
	return 0;
}