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 <vector>
#include <algorithm>
#include <string>
#include <set>
#include <utility>

using die = std::pair<char, std::string>;

die get_die() {
  char a, b, c, d, e, f;
  scanf(" %c%*s %c%*s %c%*s %c%*s %c%*s %c%*s",
        &a, &b, &c, &d, &e, &f);

  char bot;
  std::string side;
  if (a == 'R') {
    bot = f;
    side += b;
    side += c;
    side += e;
    side += d;
  } else if (b == 'R') {
    bot = e;
    side += c;
    side += a;
    side += d;
    side += f;
  } else if (c == 'R') {
    bot = d;
    side += f;
    side += e;
    side += a;
    side += b;
  } else if (d == 'R') {
    bot = c;
    side += a;
    side += e;
    side += f;
    side += b;
  } else if (e == 'R') {
    bot = b;
    side += d;
    side += a;
    side += c;
    side += f;
  } else if (f == 'R') {
    bot = a;
    side += b;
    side += d;
    side += e;
    side += c;
  }

  std::string mside = side;
  for (int i = 1; i < 4; ++i) {
    std::rotate(side.begin(), side.begin()+1, side.end());
    mside = std::min(mside, side);
  }

  return {bot, mside};
}

int testcase_ends() {
  size_t n;
  scanf("%zu", &n);
  if (n == 0) return 1;

  std::set<die> d;
  for (size_t i = 0; i < n; ++i) {
    d.insert(get_die());
  }
  printf("%zu\n", n-d.size());
  return 0;
}

int main() {
  while (!testcase_ends()) {}
}

C++: #include <stdio.h>

int translate(char Head){
	switch(Head){
	case 'R':return 0;
	case 'Y':return 1;
	case 'B':return 2;
	case 'M':return 3;
	case 'G':return 4;
	case 'C':return 5;
	}
	return -1; //must not reach here
}

class Dice{
public:
	Dice(){
		num_of_data = 0;
	};

	void roll(char dst){
		switch(dst){
		case 'E':
			setNumber(number[3],number[1],number[0],number[5],number[4],number[2]);
			break;
		case 'N':
			setNumber(number[1],number[5],number[2],number[3],number[0],number[4]);
			break;
		case 'S':
			setNumber(number[4],number[0],number[2],number[3],number[5],number[1]);
			break;
		case 'W':
			setNumber(number[2],number[1],number[5],number[0],number[4],number[3]);
			break;
		}
	};

	bool isNewPattern(int inputed[]){
		char order[25] = "NNNNWNNNWNNNENNNENNNWNNN";

		for(int i = 0; i < num_of_data; i++){
			for(int k = 0; k < 6; k++)number[k] = data_bank[i][k];
			for(int k = 0; k < 24; k++){
				roll(order[k]);
				for(int j = 0; j < 6; j++){
					if(inputed[j] != number[j])
						break;
					if(j == 5)
						return false;
				}
			}
		}
		return true;
	}

	void init(){
		num_of_data = 0;
	}

	int getNumOfData(){
		return num_of_data;
	}

	void addData(int table[6]){
		data_bank[num_of_data][0] = table[0];
		data_bank[num_of_data][1] = table[1];
		data_bank[num_of_data][2] = table[2];
		data_bank[num_of_data][3] = table[3];
		data_bank[num_of_data][4] = table[4];
		data_bank[num_of_data][5] = table[5];
		num_of_data++;
	}

private:

	void setNumber(int n0,int n1,int n2,int n3,int n4,int n5){
		number[0] = n0;
		number[1] = n1;
		number[2] = n2;
		number[3] = n3;
		number[4] = n4;
		number[5] = n5;
	}
private:
	int number[6];
	int data_bank[30][6];
	int num_of_data;
};

int main(){
	int n,tmp[6];
	char c1[10],c2[10],c3[10],c4[10],c5[10],c6[10];
	Dice dice;

	while(true){
		scanf("%d",&n);
		if(n == 0)break;

		dice.init();

		for(int i = 0; i < n; i++){
			scanf("%s %s %s %s %s %s",c1,c2,c3,c4,c5,c6);
			tmp[0] = translate(c1[0]);
			tmp[1] = translate(c2[0]);
			tmp[2] = translate(c3[0]);
			tmp[3] = translate(c4[0]);
			tmp[4] = translate(c5[0]);
			tmp[5] = translate(c6[0]);

			if(dice.isNewPattern(tmp)){
				dice.addData(tmp);
			}
		}
		printf("%d\n",n-dice.getNumOfData());

	}
}

C++: #define _CRT_SECURE_NO_WARNINGS
#include<cstdio>
#include<cmath>
#include<sstream>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<utility>
#include<iomanip>
#include<vector>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include<list>
#include<set>
#include<stdlib.h>
#include<time.h>
#define rep(i,n) for(int i=0;i<(int)n;i++)
#define repp(i,k,n) for(int i=k;i<(int)n;i++)
using namespace std;
const int dx[4] = { 0, 1, 0, -1 }, dy[4] = { 1, 0, -1, 0 };
const int dX[8] = { 0, 1, 1, 1, 0, -1, -1, -1 }, dY[8] = { 1, 1, 0, -1, -1, -1, 0, 1 };
struct XY
{
	int x;
	int y;
};
vector<long long> Prime;
void SieveOfEratosthenes(long long e) //setup vector<long long>Prime(~x)
{
	bool *x=new bool[e];
	for (long long i = 0; i <= e; i++)x[i] = false;
	for (long long i = 2; i <= e; i++)
	{
		if (x[i]);
		else
		{
			Prime.push_back(i);
			for (long long l = i; l <= e; l += i)x[l] = true;
		}
	}
	return;
}
int StringToInt(string a)
{
	stringstream ss;
	int x;
	ss << a;
	ss >> x;
	return x;
}
string IntToString(int a)
{
	stringstream ss;
	string x;
	ss << a;
	ss >> x;
	return x;
}
int GetRandom(int MIN, int MAX)
{
	static int flag=0;
	if (flag == 0)
	{
		srand((unsigned int)time(NULL));
		flag = 1;
	}
	return MIN + (int)(rand()*(MAX - MIN + 1.0) / (1.0 + RAND_MAX));
}
int in()
{
	int x;
	cin >> x;
	return x;
}
void outl(string a)
{
	cout << a << endl;
	return;
}
void outl(int a)
{
	cout << a << endl;
	return;
}
void out(string a)
{
	cout << a;
	return;
}
void out(int a)
{
	cout << a;
	return;
}
/*
(char)'1' - (int)48 = (int)1;
???1111181
 (char)A=(int)65
 (char)a=(int)97
*/
////////////////////////////////////////////////////

int main()
{
	int n;
	while (cin >> n&&n)
	{
		int ans = 0;
		map<string, int> z;
		for (int l = 0; l < n; l++){
			string a[6];
			rep(i, 6)cin >> a[i];
			string q, w, e;
			q = a[0] + a[5]; sort(q.begin(), q.end());
			w = a[1] + a[4]; sort(w.begin(), w.end());
			e = a[2] + a[3]; sort(e.begin(), e.end());
			string s[6];
			s[0] = q + w + e;
			s[1] = q + e + w;
			s[2] = w + q + e;
			s[3] = w + e + q;
			s[4] = e + q + w;
			s[5] = e + w + q;
			for (int i = 0; i < 6; i++)
			{
				if (z[s[i]] == 1)
				{
					break;
				}
				else
				{
					z[s[i]] = 1;
				}
				if (i == 5)ans++;
			}
		}
		cout << n - ans << endl;
	}
}