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<vector>
#include<stack>
#include<set>
#include<map>
#include<queue>
#include<cstdio>
#include<climits>
#include<cmath>
#include<cstring>
#include<string>

#define f first
#define s second
#define mp make_pair

#define REP(i,n) for(int i=0; i<(int)(n); i++)
#define FOR(i,c) for(__typeof((c).begin()) i=(c).begin(); i!=(c).end(); i++)
#define ALL(c) (c).begin(), (c).end()

using namespace std;

typedef unsigned int uint;
typedef long long ll;

struct cube{
  int c[6];
  inline int &operator [] (int i){
    return c[i-1];
  }
};

void rotate2(cube &c){
  int tmp = c[1];
  c[1] = c[5];
  c[5] = c[6];
  c[6] = c[2];
  c[2] = tmp;
}
void rotate3(cube &c){
  int tmp = c[1];
  c[1] = c[4];
  c[4] = c[6];
  c[6] = c[3];
  c[3] = tmp;
}
void rotate4(cube &c){
  int tmp = c[1];
  c[1] = c[3];
  c[3] = c[6];
  c[6] = c[4];
  c[4] = tmp;
}
void rotate5(cube &c){
  int tmp = c[1];
  c[1] = c[2];
  c[2] = c[6];
  c[6] = c[5];
  c[5] = tmp;
}
void rotate23(cube &c){
  int tmp = c[2];
  c[2] = c[4];
  c[4] = c[5];
  c[5] = c[3];
  c[3] = tmp;
}
void rotate24(cube &c){
  int tmp = c[2];
  c[2] = c[3];
  c[3] = c[5];
  c[5] = c[4];
  c[4] = tmp;
}

inline bool operator < (const cube &a, const cube &b){
  REP(i,6){
    if(a.c[i] != b.c[i]) return a.c[i] < b.c[i];
  }
  return false;
}

int main(){
  map<string,int> m;
  m["Red"]=0; m["Yellow"]=1; m["Blue"]=2;
  m["Magenta"]=3; m["Green"]=4; m["Cyan"]=5;
  int n;
  while(cin>>n, n){
    set<cube> s;
    REP(i,n){
      cube c;
      REP(j,6){
	string tmp; cin>>tmp;
	c[j+1] = m[tmp];
      }
      if(c[2] == 0){
	rotate5(c);
      }else if(c[3] == 0){
	rotate4(c);
      }else if(c[4] == 0){
	rotate3(c);
      }else if(c[5] == 0){
	rotate2(c);
      }else if(c[6] == 0){
	rotate5(c);
	rotate5(c);
      }

      if(c[6] != 1){
	if(c[3] == 1){
	  rotate24(c);
	}else if(c[4] == 1){
	  rotate23(c);
	}else if(c[5] == 1){
	  rotate24(c);
	  rotate24(c);
	}
      }else{
	if(c[3] == 2){
	  rotate24(c);
	}else if(c[4] == 2){
	  rotate23(c);
	}else if(c[5] == 2){
	  rotate24(c);
	  rotate24(c);
	}
      }
      s.insert(c);
    }
    printf("%d\n",n-s.size());
  }
  return 0;
}

C++: #include<iostream>
#include<string>
using namespace std;
struct kyu_bu{
  string kyu[7];
  bool h;
};
kyu_bu p[30];
void North(int i){
  string mem;
  mem = p[i].kyu[1];
  p[i].kyu[1] = p[i].kyu[2];
  p[i].kyu[2] = p[i].kyu[6];
  p[i].kyu[6] = p[i].kyu[5];
  p[i].kyu[5] = mem;
}
void East(int i){
  string mem;
  mem = p[i].kyu[1];
  p[i].kyu[1] = p[i].kyu[4];
  p[i].kyu[4] = p[i].kyu[6];
  p[i].kyu[6] = p[i].kyu[3];
  p[i].kyu[3] = mem;
}
void Right(int i){
  string mem;
  mem = p[i].kyu[2];
  p[i].kyu[2] = p[i].kyu[3];
  p[i].kyu[3] = p[i].kyu[5];
  p[i].kyu[5] = p[i].kyu[4];
  p[i].kyu[4] = mem;
}
int main(){
  int n;
  int roop[7]={0,2,3,4,5,6,1};
  while(cin >> n){
    if(n==0) break;
    int count = 0;
    for(int i=0;i<n;i++){
      p[i].h = true;
      for(int j=1;j<=6;j++) cin >> p[i].kyu[j];
    }
    for(int i=0;i<n-1;i++){
      if(!p[i].h) continue;
      for(int j=0;j<=12;j++){
	if(j>=1&&j<=4) North(i);
	else if(j>=5&&j<=8) East(i);
	else if(j>=9&&j<=12)Right(i);
	if(j==0||j%4!=0){
	  for(int k=i+1;k<n;k++){
	    if(!p[k].h) continue;
	    for(int g=1;g<=6;g++){
	      if(p[i].kyu[1]==p[k].kyu[g]){
		int strat = roop[g];
		int cou = 1;
		int index = 2;
		while(cou!=6){
		  if(p[i].kyu[index]!=p[k].kyu[strat]) break;
		  cou++;
		  index++;
		  strat = roop[strat];   
		}
		if(cou==6){
		  count++;
		  p[k].h = false;
		}
	      }
	    }
	  }
	}
      }
    }
    cout << count << endl;
  }
  return 0;
}

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

using namespace std;

bool func(string s1[7], string s2[7])
{
	bool f = true, fs[7];
	string s3[7];
	fill(fs, fs+7, true);
	
	for(int i = 1; i <= 3 && f; i++){
		for(int j = 1; j <= 6 && f; j++){
			if(s1[i] == s2[j]){
				if(!fs[j]){
					f = false;
				} else {
					fs[j] = fs[7-j] = false;
					s3[i] = s2[j];
					s3[7-i] = s2[7-j];
				}
				break;
			}
		}
	}
	/*
	cout << endl;
	cout << "s1 : ";
	for(int i = 1; i <= 6; i++){
		cout << s1[i] << " ";
	}
	cout << endl;
	cout << "s2 : ";
	for(int i = 1; i <= 6; i++){
		cout << s2[i] << " ";
	}
	cout << endl;
	cout << "s3 : ";
	for(int i = 1; i <= 6; i++){
		if(s3[i].size() == 0){
			cout << "NONE" << " ";
			continue;
		}
		cout << s3[i] << " ";
	}
	cout << endl;
	*/
	for(int i = 1; i <= 6 && f; i++){
		if(s1[i] != s3[i]){
			f = false;
		}
	}
	/*
	if(f){
		cout << "matching" << endl;
	} else {
		cout << "not matching" << endl;
	}
	cout << endl;
	*/
	return !f;
}

int main()
{
	int n, c;
	string s[31][7];
	bool f[31];
	
	while(cin>>n&&n){
		for(int i = 0; i < n; i++){
			for(int j = 1; j <= 6; j++){
				cin >> s[i][j];
			}
		}
		c = 0;
		fill(f, f+31, true);
		
		for(int i = 0; i < n; i++){
			for(int j = i+1; j < n; j++){
				f[j] = func(s[i], s[j]) & f[j];
			}
		}
		
		for(int i = 0; i < n; i++){
			if(f[i]){
				c++;
			}
		}
		
		cout << (n-c) << endl;
	}
	
	return 0;
}

C++: #include<iostream>
#include<string>
using namespace std;
int Dice[6][6] = { { 1,5,2,3,0,4 },{ 4,0,2,3,5,1 },{ 3,1,0,5,4,2 },{ 2,1,5,0,4,3 },{ 0,2,4,1,3,5 },{ 0,3,1,4,2,5 } }, power[6] = { 1,3,9,27,81,243 };
struct Saikoro { int x[6]; }; Saikoro T[30]; int n, vis[30]; char F[7] = "CYRMGB"; bool G[30][30];
bool bfs(int p, int q) {
	for (int i = 0; i < 729; i++) {
		int bit[6]; for (int j = 0; j < 6; j++) { bit[j] = (i / power[j]) % 3; }
		Saikoro U = T[p];
		for (int j = 0; j < 6; j++) {
			for (int k = 0; k <= bit[j]; k++) {
				Saikoro V = U; for (int l = 0; l < 6; l++)V.x[l] = U.x[Dice[j][l]]; U = V;
			}
		}
		bool OK = true; for (int j = 0; j < 6; j++) { if (T[q].x[j] != U.x[j])OK = false; }
		if (OK == true)return true;
	}
	return false;
}
int main() {
	while (true) {
		for (int i = 0; i < 30; i++) { for (int j = 0; j < 30; j++)G[i][j] = false; vis[i] = 0; }
		cin >> n; if (n == 0)break; for (int i = 0; i < n; i++) { for (int j = 0; j < 6; j++) { string S; cin >> S; for (int k = 0; k < 6; k++) { if (S[0] == F[k])T[i].x[j] = k; } } }
		for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (i == j)continue; G[i][j] = bfs(i, j); } }
		int cnt = 0; for (int i = 0; i < n; i++) { if (vis[i] != 0)continue; cnt++; vis[i] = cnt; for (int j = 0; j < n; j++) { for (int k = 0; k < n; k++) { if (vis[k] != cnt)continue; for (int l = 0; l < n; l++) { if (G[k][l] == true)vis[l] = cnt; } } } }
		cout << n - cnt << endl;
	}
	return 0;
}