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;
using ll = long long;
using pii = pair<int, int>;

struct Dice {
  int face[6];
  Dice() {}
  int& operator [] (int i) { return face[i]; }
  bool operator == (const Dice& other) {
    for (int i = 0; i < 6; i++) if (face[i] != other.face[i]) return false;
    return true;
  }
  bool operator != (const Dice& other) {
    return !(*this == other);
  }
  void roll(int a, int b, int c, int d) {
    int tmp = face[a];
    face[a] = face[b];
    face[b] = face[c];
    face[c] = face[d];
    face[d] = tmp;
  }
  void roll(char c) {
    switch (c) {
      case 'N' : roll(0, 1, 5, 4); break;
      case 'S' : roll(0, 4, 5, 1); break;
      case 'E' : roll(0, 3, 5, 2); break;
      case 'W' : roll(0, 2, 5, 3); break;
      case 'R' : roll(1, 2, 4, 3); break;
      case 'L' : roll(1, 3, 4, 2); break;
    }
  }
  bool identical(Dice other) {
    for (int i = 0; i < 6; i++) {
      other.roll(i & 1 ? 'E' : 'N');
      for (int j = 0; j < 4; j++) {
        other.roll('R');
        if (*this == other) return true;
      }
    }
    return false;
  }
};

vector<string> ord = {"Red", "Yellow", "Blue", "Magenta", "Green", "Cyan"};

int main() {
  cin.tie(0);
  ios_base::sync_with_stdio(false);
  cout << fixed << setprecision(10);
  
  int n;
  while (cin >> n, n) {
    vector<Dice> D(n);
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < 6; j++) {
        string s;
        cin >> s;
        D[i][j] = find(ord.begin(), ord.end(), s) - ord.begin();
      }
    }
    int ans = n;
    for (int i = 0; i < n; i++) {
      bool no = false;
      for (int j = 0; j < i; j++) {
        no |= D[i].identical(D[j]);
      }
      if (no) continue;
      ans--;
    }
    cout << ans << endl;
  }

  return 0;
}

C++: #include<iostream>
#include<algorithm>
#include<string>
#include<vector>
using namespace std;
class cube {
public:
	string color;
	void input() {
		string str;
		color = "";
		for (int i = 0; i < 6; ++i) {
			cin >> str;
			color += str[0];
		}
	}
};
int turn[3][4]{ {1,2,4,3},{0,1,5,4},{0,2,5,3} };
void turncube(cube&, int);
bool check(cube, cube);
int main() {
	int num;
	while (cin >> num&&num != 0) {
		vector<cube> line(num);
		for (int i = 0; i < num; ++i) {
			line[i].input();
		}
		int ans = 0;
		for (int i = 0; i < line.size() - 1; ++i) {
			for (int j = i+1; j < line.size(); ++j) {
				if (check(line[i], line[j])) {
					swap(line[j], line.back());
					line.pop_back();
					++ans;
					--j;
				}
			}
		}
		cout << ans << endl;
	}
	return 0;
}

void turncube(cube &a, int num) {
	for (int i = 0; i < 3; ++i) {
		swap(a.color[turn[num][i]], a.color[turn[num][i + 1]]);
	}
}

bool check(cube a, cube b) {
	int num[] = { 1,1,1,1,2,1,1,1,1 };
	int i = 0;
	while (a.color[0] != b.color[0]) {
		turncube(a, num[i++]);
	}
	for (int i = 0; i < 4; ++i) {
		bool flag = true;
		turncube(a, 0);
		for (int j = 0; j < 6; ++j) {
			if (a.color[j] != b.color[j]) {
				flag = false;
			}
		}
		if (flag)return true;
	}
	return false;
}

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

struct datum {
	char str[6];
};

datum data[30];

char now[6];
char temp[6];

void rotate() {
	char temp;
	temp = now[0];
	now[0] = now[2];
	now[2] = now[5];
	now[5] = now[3];
	now[3] = temp;
}

void spin () {
	char temp;
	temp = now[1];
	now[1] = now[2];
	now[2] = now[4];
	now[4] = now[3];
	now[3] = temp;
}

int compare ( const void * a, const void * b ) {
	const datum x = *((datum*)a);
	const datum y = *((datum*)b);

	for ( int i=0; i<6; i++ ) {
		if ( x.str[i] != y.str[i] )
			return x.str[i] - y.str[i];
	}
	return 0;
}


int main () {
	while ( true ) {
		int n;
		cin >> n;

		if ( n == 0 ) 
			break;

		string str;
		for ( int i=0; i<n; i++ ) {
			for ( int j=0; j<6; j++ ) {
				
				cin >> str;
				now[j] = str[0];
			}

			if ( now[1] == 'B' || now[4] == 'B' ) {
				spin();
			}
			while ( now[0] != 'B' ) {
					rotate();
			}

			if ( now[5] == 'Y' ) {
				while ( now[1] != 'C' ) {
					spin();
				}
			}
			else {
				while ( now[1] != 'Y' ) {
					spin();
				}
			}

			for ( int j=0; j<6; j++ ) {
				data[i].str[j] = now[j];
			}
		}

		qsort ( data, n, sizeof(datum), compare);

		int count = 0;

		for ( int i=0; i<n-1; i++ ) {
			bool hit = true;
			for ( int j=0; j<6; j++ ) {
				if ( data[i].str[j] != data[i+1].str[j] ) {
					hit = false;
					break;
				}
			}
			if ( hit ) 
				count ++;
		}

		cout << count << endl;
	}
}

C++: #include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
 
#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define FFOR(i,a,b) for(int i=(a);i<=(b);i++)
#define REP(i,b) FOR(i,0,b)
#define RREP(i,b) FFOR(i,1,b)
#define PB push_back
#define F first
#define S second
#define BE(c) c.begin(),c.end()
using namespace std;
typedef long long LL;
typedef LL ut;
typedef long double ld;
typedef pair<ut,ut> pr;
typedef vector<pr> Vpr;
typedef vector<ut> VI;
typedef pair<ut,pr> ppr;
typedef priority_queue<pr,Vpr, greater<pr> > PQ;
const int SIZE=5+3*1e+4;
const ut INF=1<<30;
const ld eps=1e-6;
const LL p=7+1e+9;

map<string, int> colors;
int main(){
	int n;
	colors["Red"] = 0;
	colors["Magenta"] = 1;
	colors["Blue"] = 2;
	colors["Green"] = 3;
	colors["Yellow"] = 4;
	colors["Cyan"] = 5;
	
	while(cin >> n && n){
		vector<Vpr> vec;
		int ans = 0;
		REP(i,n){
			string s[6];
			REP(j,6){
				cin >> s[j];
			}
			Vpr tmp;
			REP(j,3){
				tmp.PB(pr(min(colors[s[j]], colors[s[6 - j - 1]]), max(colors[s[j]], colors[s[6 - j - 1]])));
			}
			sort(BE(tmp));
			bool H = false;
			REP(j,vec.size()){
				bool ok = true;
				REP(k,3){
					if(!(vec[j][k].F == tmp[k].F && vec[j][k].S == tmp[k].S)){
						ok = false;
						break;
					}
				}
				if(ok){
					H = true;
					break;
				}
			}
			if(H){
				ans++;
			}
			else{
				vec.PB(tmp);
			}
		}
		cout << ans << endl;
	}
}