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 <bits/stdc++.h>

using namespace std;

#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define REP(i,n) FOR(i,0,n)
#define ALL(v) (v).begin(),(v).end()
#define fi first
#define se second

template<typename A, typename B> inline bool chmax(A &a, B b) { if (a<b) { a=b; return 1; } return 0; }
template<typename A, typename B> inline bool chmin(A &a, B b) { if (a>b) { a=b; return 1; } return 0; }

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<int, pll> pip;
const ll INF = 1ll<<29;
const ll MOD = 1000000007;
const double EPS  = 1e-9;

struct Dice {
	int num[6]; // top, bottom, front, back, right, left;
	static const int rd[3][4]; //?????¢??????
	
	Dice(int top, int bottom, int front, int back, int right, int left) {
		num[0] = top;		num[1] = bottom;
		num[2] = front;	num[3] = back;
		num[4] = right;	num[5] = left;
	}
	Dice(const Dice &d) {
		copy(d.num, d.num + 6, num);
	}
	
	bool operator < (const Dice &d) const {
		REP(i, 6) if (num[i] != d.num[i]) {
			return num[i] < d.num[i];
		}
		return false;
	}
	
	void X() { rotate(0); }
	void Y() { rotate(1); }
	void Z() { rotate(2); }
	
	void rotate(int p) {
		int tmp = num[rd[p][0]];
		
		REP(i, 3) num[rd[p][i]] = num[rd[p][i + 1]];
		num[rd[p][3]] = tmp;
	}
	
	Dice unique() {
		Dice now = *this;
		
		Dice mi(*this);
		
		REP(i, 4) {
			REP(j, 4) {
				REP(k, 4) {
					if (now < mi) mi = now;
					now.X();
				}
				now.Y();
			}
			now.Z();
		}
		return mi;
	}
	
	void print() {
		REP(i, 6) printf("%d%c", num[i], i == 5 ? '\n' : ' ');
	}
};

const int Dice::rd[3][4] = {
	{2,1,3,0}, // x
	{2,4,3,5}, // y
	{0,5,1,4}, // z
};

int main() {
	char color[6][10] = { "Red", "Yellow", "Blue", "Magenta", "Green", "Cyan" };
	map<string, int> trans;
	REP(i, 6) trans[color[i]] = i;
	
	int n;
	while (cin >> n, n) {
		set<Dice> ss;
		
		REP(i, n) {
			int col[6] = {};
			REP(j, 6) {
				string str; cin >> str;
				col[j] = trans[str];
			}
			
			ss.insert(Dice(col[0], col[5], col[1], col[4], col[2], col[3]).unique());
		}
		
		cout << n - ss.size() << endl;
	}
	
	return 0;
}

C++: 
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string>
#include<queue>
#include<vector>
#include<functional>
#include<cmath>
#include<map>
#include<stack>
#include<set>
#include<numeric>
#include<limits>

#define all(x) (x).begin(),(x).end()
#define rall(x) (x).rbegin(),(x).rend()

using namespace std;
typedef long long ll;
typedef pair<int, int> pi;
typedef pair<ll, ll> pl;
typedef pair<ll, char> plc;

struct color {
	string c1, c2, c3, c4, c5, c6;
};

int main()
{
	int n; 
	while (cin >> n, n) {
		int check[40] = { 0 };
		vector<color> v(n);
		for (int i = 0; i < n; i++) {
			cin >> v[i].c1 >> v[i].c2 >> v[i].c3 >> v[i].c4 >> v[i].c5 >> v[i].c6;
		}

		int cnt = 0;
		for (int i = 0; i < n - 1; i++) {
			map<string, string> m;
			m[v[i].c1] = v[i].c6;
			m[v[i].c6] = v[i].c1;
			m[v[i].c2] = v[i].c5;
			m[v[i].c5] = v[i].c2;
			m[v[i].c3] = v[i].c4;
			m[v[i].c4] = v[i].c3;
			for (int j = i + 1; j < n; j++) {
				if (m[v[j].c1] == v[j].c6) {
					if (m[v[j].c2] == v[j].c5) {
						if (m[v[j].c3] == v[j].c4) {
							if (check[j] != 1) {
								cnt++;
								check[j] = 1;
							}
						}
					}
				}
			}
		}
		cout << cnt << endl;
	}
	return 0;
}

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

using namespace std;


class Dice{
private:
	int yoko;
	int tate;
	int round;

public:
	string face[3][4];

	string getFace(int i,int j)const{
		return face[i][j];
	}

	Dice(vector<string> &v){
		init();
		face[1][1]=v[0];
		face[2][1]=v[1];
		face[1][2]=v[2];
		face[1][0]=v[3];
		face[0][1]=v[4];
		face[1][3]=v[5];
	}

	void init(){
		for(int i = 0; i < 3; i++){
			for(int j = 0; j < 4; j++){
				face[i][j]="";
			}
		}
		yoko=0;
		tate=0;
		round=0;
	}

	void rotate(){
		if(round<4){
			string tmp = face[2][1];
			face[2][1]=face[1][2];
			face[1][2]=face[0][1];
			face[0][1]=face[1][0];
			face[1][0]=tmp;
			round++;
		}
		if(round>=4){
			round=0;
			// àÇÁÄ«½çA¡ÌXbgðñ]³¹é
			if(yoko<4){
				string tmp = face[1][3];
				for(int i = 2; i >= 0; i--){
					face[1][i+1]=face[1][i];
				}
				face[1][0]=tmp;
				yoko++;
			}
			// àÇÁÄ«½çAcÌXbgðñ]³¹é
			if(yoko>=4){
				if(tate<4){
					tate++;
					string tmp = face[1][3];
					face[1][3]=face[0][1];
					for(int i = 0; i < 2; i++){
						face[i][1]=face[i+1][1];
					}
					face[2][1]=tmp;
				}
				if(tate>=4){
					round=0;
					tate=0;
					yoko=0;
				}
			}
		}
	};
};

int main(){

	int n;
	while(cin>>n&&n!=0){
		vector<Dice> ds;
		for(int i = 0; i < n; i++){
			vector<string> v;
			for(int j = 0; j < 6; j++){
				string str;
				cin>>str;
				v.push_back(str);
			}
			ds.push_back(Dice(v));
		}

		vector<Dice> used;
		used.push_back(ds[0]);
		for(int i = 1; i < n; i++){
			bool t=false;
			// ÇêðÝé©
			bool f=false;
			for(int j = 0; j < used.size(); j++){
				// ÇÌûü©
				for(int k = 0; k < 28; k++){
					// ½ÄÆæ±
					for(int l = 0; l < 3; l++){
						for(int m = 0; m < 4; m++){
							if(used[j].face[l][m]!=ds[i].face[l][m]){
								t=true;
								break;
							}
						}
						if(t)
							break;
					}
					if(!t){
						f=true;
					}
					//if(k==3){
					//	cout<<endl;
					//}
					used[j].rotate();
					t=false;
				}
				// àµÇÌûüÅàêvµÈ©Á½çAXgÉÁ¦é
	/*			for(int l = 0; l < 3; l++){
					for(int k = 0; k < 4; k++){
						cout<<used[j].face[l][k]<<" ";
					}
					cout<<endl;
				}
				cout<<endl;*/

				if(f)
					break;
			}
			if(!f){
				used.push_back(ds[i]);
			}
		}
		cout<<n-used.size()<<endl;
	}

	return 0;
}