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 <string>
using namespace std;

int data[30][6];

bool judge(int);

main(){
  string in;
  int n;
  while(1){
    cin >> n;
    if(n==0) break;
    int count=0;
    for(int i=0;i<n;i++){
      for(int j=0;j<6;j++){
	cin >> in;
	if(in=="Red") data[i][j]=1;
	if(in=="Yellow") data[i][j]=2;
	if(in=="Blue") data[i][j]=3;
	if(in=="Magenta") data[i][j]=4;
	if(in=="Green") data[i][j]=5;
	if(in=="Cyan") data[i][j]=6;
      }
      if(judge(i)) count++;
    }
    int ans=n-count;
    if(ans<0) ans=0;
    cout << ans << endl;
  }
  return 0;
}

bool judge(int n){
  if(n==0) return true;
  int tmp[6];
  for(int i=0;i<6;i++){
    tmp[i]=data[n][i];
  }
  for(int i=0;i<n;i++){
    for(int j=0;j<4;j++){
      for(int k=0;k<4;k++){
	for(int a=0;a<4;a++){
	  if(tmp[0]==data[i][0] && tmp[1]==data[i][1] && tmp[2]==data[i][2] && tmp[3]==data[i][3] && tmp[4]==data[i][4] && tmp[5]==data[i][5]) return false;
	  int ttt[6];
	  for(int b=0;b<6;b++){
	    ttt[b]=tmp[b];
	  }
	  ttt[0]=tmp[0];
	  ttt[1]=tmp[2];
	  ttt[2]=tmp[4];
	  ttt[3]=tmp[1];
	  ttt[4]=tmp[3];
	  ttt[5]=tmp[5];
	  for(int b=0;b<6;b++){
	    tmp[b]=ttt[b];
	  }
	}
	int tt[6];
	for(int l=0;l<6;l++){
	  tt[l]=tmp[l];
	}
	tt[0]=tmp[1];
	tt[1]=tmp[5];
	tt[2]=tmp[2];
	tt[3]=tmp[3];
	tt[4]=tmp[0];
	tt[5]=tmp[4];
	for(int l=0;l<6;l++){
	  tmp[l]=tt[l];
	}
      }
      int t[6];
      for(int k=0;k<6;k++){
	t[k]=tmp[k];
      }
      t[0]=tmp[3];
      t[1]=tmp[1];
      t[2]=tmp[0];
      t[3]=tmp[5];
      t[4]=tmp[4];
      t[5]=tmp[2];
      for(int k=0;k<6;k++){
	tmp[k]=t[k];
      }
    }
  }
  return true;
}

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

void roll_x(vector<int> &v) {
  vector<int> res = v;
  
  res[0] = v[4];
  res[1] = v[0];
  res[5] = v[1];
  res[4] = v[5];
  v = res;
}

void roll_y(vector<int> &v) {
  vector<int> res = v;
  res[0] = v[3];
  res[2] = v[0];
  res[5] = v[2];
  res[3] = v[5];
  v = res;
}

void roll_z(vector<int> &v) {
  vector<int> res = v;
  res[1] = v[2];
  res[2] = v[4];
  res[4] = v[3];
  res[3] = v[1];
  v = res;
}

void allpattern(vector<int> v, vector<vector<int> > &out) {
  out.clear();  
  for(int i = 0; i < 6; i++) {
    if( i & 1 ) roll_x(v);
    else roll_y(v);
    for(int j = 0; j < 4; j++) {
      roll_z(v);
      out.push_back(v);
    }
  }
  
}

bool same(vector<int> a, vector<int> b) {
  vector<vector<int> > aa, bb;
  
  allpattern(b, bb);

  for(int i = 0; i < bb.size(); i++) 
    if( bb[i] == a ) return true;
  return false;
}

bool dup(vector< vector<int> > have, vector<int> b) {
  for(int i = 0; i < (int)have.size(); i++) {
    if( same( have[i], b ) ) return true;
  }
  return false;
}

int main() {
  for(int N; cin >> N, N; ) {

    vector<int> dice[N];

    for(int n = 0; n < N; n++) {
      for(int i = 0; i < 6; i++) {
        string s; cin >> s;
        dice[n].push_back( s[0] - 'A' );
      }
    }
    
    vector< vector<int> > uni;
    for(int i = 0; i < N; i++) {
      if( ! dup(uni, dice[i]) ) {
        uni.push_back( dice[i] );
      }
    }

    cout << N - (int)uni.size() << endl;
    
  }
}

C++: #include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

enum FACE { TOP, BOTTOM, FRONT, BACK, LEFT, RIGHT };
FACE ck[6]={TOP,BOTTOM,FRONT,BACK,LEFT,RIGHT};

class UnionFind
{
public:
	vector<int> data;
	UnionFind(int size):data(size, -1){}
	
	bool unionSet(int x, int y)
	{
		x = root(x); y=root(y);
		if(x != y)
		{
			if(data[y] < data[x]) swap(x, y);
			data[x] += data[y]; data[y] = x;
		}
		return x != y;
	}
	
	int root(int x)
	{
		return data[x] < 0 ? x:data[x]=root(data[x]);
	}
};

class Dice
{
public:
	Dice(string m[6])
	{
		f[TOP]=0; f[FRONT]=1; f[LEFT]=2;
		f[RIGHT]=3; f[BACK]=4; f[BOTTOM]=5;
		
		for(int i=0; i<6; i++)
			val[i]=m[i];
	}
	
	void rotated(FACE a, FACE b, FACE c, FACE d)
	{
		int tmp = f[a];
		f[a]=f[b];
		f[b]=f[c];
		f[c]=f[d];
		f[d]=tmp;
	}
	
	vector<Dice> all_rotate()
	{
		vector<Dice> t;
		for(int i=0; i<6; (i&1?rotateY():rotateX()), i++)
		for(int j=0; j<4; rotateZ(), j++)
			t.push_back(*this);
			
		return t;
	}
	
	void rotateX() { rotated(TOP, BACK, BOTTOM, FRONT); }
	void rotateY() { rotated(TOP, LEFT, BOTTOM, RIGHT); }
	void rotateZ() { rotated(FRONT, RIGHT, BACK, LEFT); }
	
	string GetVal(FACE fe) { return val[f[fe]]; }

	
	int f[6];
	string val[6];
};

bool isequal(vector<Dice>& a, vector<Dice>& b)
{
	for(int k=0; k<a.size(); k++) 
	for(int j=0; j<b.size(); j++)
	{
		bool g=true;
		for(int i=0; i<6; i++)
		{
			if(a[k].GetVal(ck[i])!=b[j].GetVal(ck[i]))
			{
				g=false;
				break;
			}
		}
		if(g) return true;
	}
	
	return false;
}

int main()
{
	int N;
	while(cin >> N, N)
	{
		vector<Dice> d;
		for(int i=0; i<N; i++)
		{
			string s[6];
			for(int j=0; j<6; j++)
				cin >> s[j];
				
			d.push_back(s);
		}
		
		vector<vector<Dice> > face;
		for(int i=0; i<d.size(); i++)
			face.push_back(d[i].all_rotate());
		
		int ans=0;
		UnionFind uf(N);
		
		for(int i=0; i<N; i++)
		for(int j=i+1; j<N; j++)
		{
			if(i==j) continue;
			if(isequal(face[j], face[i]))
			{
				if(uf.unionSet(i,j))
					ans++;
			}
		}
		
		cout << ans << endl;
	}
}