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;

int n;
string str[31][6];

bool roll(int x,int y){
	bool flag2=false;
	for(int i=0;i<4;i++){
		string st=str[y][1];
		str[y][1]=str[y][2];
		str[y][2]=str[y][4];
		str[y][4]=str[y][3];
		str[y][3]=st;
		bool flag=true;
		for(int j=0;j<6;j++){
			if(str[y][j]!=str[x][j])flag=false;
		}
		if(flag)flag2=true;
	}
	return flag2;
}

bool check(int x,int y){
	bool flag=true;
	if(roll(x,y))flag=false;
	for(int i=0;i<4;i++){
		string st=str[y][0];
		str[y][0]=str[y][2];
		str[y][2]=str[y][5];
		str[y][5]=str[y][3];
		str[y][3]=st;
		if(roll(x,y))flag=false;
	}
	swap(str[y][0],str[y][5]);
	swap(str[y][1],str[y][4]);
	if(roll(x,y))flag=false;
	for(int i=0;i<4;i++){
		string st=str[y][0];
		str[y][0]=str[y][2];
		str[y][2]=str[y][5];
		str[y][5]=str[y][3];
		str[y][3]=st;
		if(roll(x,y))flag=false;
	}
	swap(str[y][0],str[y][5]);
	swap(str[y][1],str[y][4]);
	swap(str[y][0],str[y][5]);
	swap(str[y][2],str[y][3]);
	if(roll(x,y))flag=false;
	for(int i=0;i<4;i++){
		string st=str[y][0];
		str[y][0]=str[y][2];
		str[y][2]=str[y][5];
		str[y][5]=str[y][3];
		str[y][3]=st;
		if(roll(x,y))flag=false;
	}
	swap(str[y][0],str[y][5]);
	swap(str[y][2],str[y][3]);
	return flag;
}

int main(void){
	while(1){
		scanf("%d",&n);
		if(n==0)break;
		for(int i=0;i<n;i++){
			for(int j=0;j<6;j++){
				cin >> str[i][j];
			}
		}
		int cnt=0;
		for(int i=0;i<n;i++){
			bool flag=true;
			for(int j=0;j<i;j++){
				if(!check(i,j))flag=false;
			}
			if(flag)cnt++;
		}
		printf("%d\n",n-cnt);
	}
	return 0;
}

C++: #include <iostream>
#include <string>
#include <string.h>
using namespace std;

int g[24][3] = { {0, 1, 2}, {0, 2, 4}, {0, 4, 3}, {0, 3, 1}, {1, 5, 2},
				{1, 2, 0}, {1, 0, 3}, {1, 3, 5}, {2, 0, 1}, {2, 1, 5},
				{2, 5, 4}, {2, 4, 0}, {3, 1, 0}, {3, 0, 4}, {3, 4, 5},
				{3, 5, 1}, {4, 0, 2}, {4, 2, 5}, {4, 5, 3}, {4, 3, 0},
				{5, 2, 1}, {5, 1, 3}, {5, 3, 4}, {5, 4, 2} };

bool ck(string* a, string* b) {
	int k = 0;
	while (b[k] != a[0])
		k++;

	if (b[5 - k] == a[5]) {
		int l = 0;
		while (b[l] != a[1])
			l++;

		if (b[5 - l] == a[4]) {
			int u = 0;
			while (b[u] != a[2])
				u++;

			for(int i = 0; i < 24; i++)
				if (g[i][0] == k && g[i][1] == l && g[i][2] == u)
					return 1;
		}
	}

	return 0;
}

int main()
{	
	int n;

	cin >> n;

	while (n > 0) {
		string c[30][6];
		for (int i = 0; i < n; i++)
			for (int j = 0; j < 6; j++)
				cin >> c[i][j];

		bool f[30];
		memset(f, 0, sizeof(f));

		for (int i = 0; i < n - 1; i++) {
			for (int j = i + 1; j < n; j++) {
				if (ck(c[i], c[j]))
					f[j] = 1;
			}
		}

		int m = 0;
		for (int i = 0; i < n; i++)
			if (f[i])
				m++;

		cout << m << endl;

		cin >> n;
	}
	
	return 0;
}

C++: #include <iostream>
#include <vector>
#include <map>
#include <set>
using namespace std;

typedef vector <int> VI;

VI roll_y( VI& box )
{
	VI work = box;
	work[0] = box[2];
	work[2] = box[5];
	work[5] = box[3];
	work[3] = box[0];
	return work;
}

VI roll_x( VI& box )
{
	VI work = box;
	work[5] = box[1];
	work[1] = box[0];
	work[0] = box[4];
	work[4] = box[5];
	return work;
}

VI roll_z( VI& box )
{
	VI work = box;
	work[3] = box[4];
	work[4] = box[2];
	work[2] = box[1];
	work[1] = box[3];
	return work;
}

void register_box( VI& box, set <VI>& V )
{
	V.insert( box );

	VI work;
	
	work = box;
	for ( int i = 0; i < 3; i++ )
	{
		work = roll_y( work );
		V.insert( work );
	}

	work = box;
	for ( int j = 0; j < 3; j++ )
	{
		work = roll_x( work );
		for ( int i = 0; i < 3; i++ )
		{
			work = roll_y( work );
			V.insert( work );
		}
		work = roll_y( work );
	}

	work = box;
	for ( int j = 0; j < 3; j++ )
	{
		work = roll_z( work );
		for ( int i = 0; i < 3; i++ )
		{
			work = roll_y( work );
			V.insert( work );
		}
		work = roll_y( work );
	}

}

int main( void )
{
	// Redツ、Yellowツ、Blueツ、Magentaツ、Greenツ、Cyan
	map <string, int> hash_table;
	hash_table["Red"]		= 1;
	hash_table["Yellow"]	= 2;
	hash_table["Blue"]		= 3;
	hash_table["Magenta"]	= 4;
	hash_table["Green"]		= 5;
	hash_table["Cyan"]		= 6;

	int n;
	while ( cin >> n && n )
	{
		int cnt = 0;
		set < VI > V;
		VI box(6);
		string color;

		for ( int i = 0; i < n; i++ )
		{
			for ( int j = 0; j < 6; j++ )
			{
				cin >> color;
				box[j] = hash_table[color];
			}

			if ( V.find( box ) != V.end() )
				cnt ++;

			register_box( box, V );
		}

		cout << cnt << endl;
	}

	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);
  }
};

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;
}
void RolL(BOX& B) {
  string temp = B.left;
  B.left = B.top;
  B.top = B.right;
  B.right = 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);
      for(int m = 0; m < 4; m++) {
        RolL(a);
        if(a == b) return(true);
      }
    }
  }
  return(false);
}

int main()
{
  int n;
  vector< BOX > boxes;
  while(cin >> n, n) {
    boxes.resize(n);
    for(int i = 0; i < n; i++) {
      BOX &b = boxes[i];
      cin >> b.top >> b.head >> b.right >> b.back >> b.left >> b.buttom;
    }
    int ret = 0;
    for(int i = 0; i < n; i++) {
      for(int j = i + 1; j < n; j++) {
        if(Myon(boxes[i], boxes[j])) {
          ++ret;
          break;
        }
      }
    }
    cout << ret << endl;
  }
}