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++: #define _USE_MATH_DEFINES
#define INF 0x3f3f3f3f
#include <cstdio>
#include <iostream>
#include <sstream>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <limits>
#include <map>
#include <string>
#include <cstring>
#include <set>
#include <deque>
#include <bitset>
#include <list>
#include <cctype>
#include <utility>
#include <complex>
 
using namespace std;
 
typedef long long ll;
typedef pair <int,int> P;
typedef pair <int,P > PP;
 
int tx[] = {0,1,0,-1};
int ty[] = {-1,0,1,0};
 
static const double EPS = 1e-10;

enum dir {
  TOP,
  FRONT,
  REAR,
  BOTTOM,
  LEFT,
  RIGHT
};


map<string,int> dict;

class Dice {
public:
  int surface[6];

  Dice(const vector<string>& colors){
    surface[TOP] = dict[colors[0]];
    surface[FRONT] = dict[colors[3]];
    surface[BOTTOM] = dict[colors[5]];
    surface[REAR] = dict[colors[2]];
    surface[RIGHT] = dict[colors[1]];
    surface[LEFT] = dict[colors[4]];
  }

  bool is_visited(set<string>& visited){
    bool res = true;
    for(int i=0;i<6;i++){
      for(int j=0;j<6;j++){
	for(int k=0;k<6;k++){
	  int tmp[6];
	  memcpy(tmp,surface,sizeof(int)*6);
	  
	  pitch(i);
	  yaw(j);
	  roll(k);
	  if(visited.count(getkey()) == 0){
	    res = false;
	    visited.insert(getkey());
	  }
	  memcpy(surface,tmp,sizeof(int)*6);
	}
      }
    }

    return res;
  }
  
  void pitch(int num){
    //FRONT,BOTTOM,REAR,TOP
    for(int i=0;i<num;i++){
      int next[6];
      memcpy(next,surface,sizeof(int)*6);
      next[FRONT] = surface[BOTTOM];
      next[BOTTOM] = surface[REAR];
      next[REAR] = surface[TOP];
      next[TOP] = surface[FRONT];
      memcpy(surface,next,sizeof(int)*6);
    }
  }
  void yaw(int num){
    //LEFT,FRONT,RIGHT,REAR
    for(int i=0;i<num;i++){
      int next[6];
      memcpy(next,surface,sizeof(int)*6);
      next[LEFT] = surface[FRONT];
      next[FRONT] = surface[RIGHT];
      next[RIGHT] = surface[REAR];
      next[REAR] = surface[LEFT];
      memcpy(surface,next,sizeof(int)*6);
    }
  }
  void roll(int num){
    //TOP,LEFT,BOTTOM,RIGHT
    for(int i=0;i<num;i++){
      int next[6];
      memcpy(next,surface,sizeof(int)*6);
      next[TOP] = surface[LEFT];
      next[LEFT] = surface[BOTTOM];
      next[BOTTOM] = surface[RIGHT];
      next[RIGHT] = surface[TOP];
      memcpy(surface,next,sizeof(int)*6);
    }
  }

  string getkey(){
    string res = "";
    res.push_back('0' + surface[TOP]);
    res.push_back('0' + surface[FRONT]);
    res.push_back('0' + surface[BOTTOM]);
    res.push_back('0' + surface[REAR]);
    res.push_back('0' + surface[RIGHT]);
    res.push_back('0' + surface[LEFT]);

    return res;
  }
};

int main(){
  int n;
  dict["Red"] = 1;
  dict["Yellow"] = 2;
  dict["Blue"] = 3;
  dict["Magenta"] = 4;
  dict["Green"] = 5;
  dict["Cyan"] = 6;

  while(~scanf("%d",&n)){
    if(n == 0) break;
    set<string> visited;

    int count = 0;
    for(int i=0;i<n;i++){
      vector<string> colors;
      for(int j=0;j<6;j++){
	string color;
	cin >> color;
	colors.push_back(color);
      }
      Dice d(colors);
      if(!d.is_visited(visited)){
	count++;
      }
    }

    printf("%d\n",n - count);
  }
}

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

enum { U, B, L, F, R, D };
struct Dice {               //   .    .  U(2)   .
    int face[6];            // B(5) L(4) F(0) R(1)
    Dice() {                //   .    .  D(3)   .
        face[F] = 0; face[R] = 1; face[U] = 2;
        face[B] = 5; face[L] = 4; face[D] = 3;
    }
    int find_face(int f) {
        for (int i = 0; i < 6; i++) if (face[i] == f) return i;
        return -1;
    }
    void turn(int dir) {
        switch (dir) {
            case R: rotate(U, R, D, L); break;
            case B: rotate(U, B, D, F); break;
            case L: rotate(U, L, D, R); break;
            case F: rotate(U, F, D, B); break;
            case U: rotate(F, R, B, L); break;  // 上から見て反時計回り
            case D: rotate(F, L, B, R); break;  // 下から見て反時計回り
        }
    }
    int& operator[](int n) { return face[n]; }
    const int& operator[](int n) const { return face[n]; }
    vector<Dice> all_rolls() {              // 24 通り
        vector<Dice> res;
        for (int k = 0; k < 6; k++) {
            for (int i = 0; i < 4; i++) {
                res.push_back(*this);
                turn(R);
            }
            turn(k % 2 == 1 ? U : F);
        }
        return res;
    }
    void rotate(int a, int b, int c, int d) {
        int t = face[d]; face[d] = face[c]; face[c] = face[b];
        face[b] = face[a]; face[a] = t;
    }
    friend ostream& operator<<(ostream& os, const Dice d) {
        os << "[";                          // U, B, L, F, R, D
        for (int i = 0; i < 6; i++) os << d[i] << " ]"[i == 5];
        return os;
    }
};

int main() {
    Dice dice;
    vector<Dice> all_rolls = dice.all_rolls();
    int n;
    while (cin >> n, n) {
        int cnt = 0;
        set<string> s;
        while (n--) {
            string cur, t;
            for (int i = 0; i < 6; i++) cin >> t, cur += t[0];
            swap(cur[3], cur[4]);
            if (s.count(cur)) {
                cnt++;
            } else {
                swap(cur[3], cur[4]);
                for (Dice &dice: all_rolls) {
                    string t;
                    for (int i = 0; i < 6; i++) t += cur[dice[i]];
                    s.emplace(t);
                }
            }
        }
        cout << cnt << endl;
    }
    return 0;
}

C++: #include<bits/stdc++.h>
using namespace std;
main(){
  int n;
  string saikoro[50];
  int ans=0;
  while(1){
    ans=0;
    cin>>n;
    if(n==0)break;
    string s;
    for(int i=0;i<n;i++){
      saikoro[i]="";
      for(int j=0;j<6;j++){
	cin>>s;
	string c;
	c=s[0];
	saikoro[i]+=c;
      }
    }
    for(int i=0;i<n;i++){
      for(int j=i+1;j<n;j++){
	//cout<<saikoro[i]<<" "<<saikoro[j]<<endl;
	int cnt=0;
	for(int k=0;k<3;k++){
	  for(int l=0;l<3;l++){
	    //cout<<saikoro[i][k]<<saikoro[i][6-k-1]<<" "<<saikoro[j][l]<<saikoro[j][6-l-1]<<endl;
	    if((saikoro[i][k]==saikoro[j][l]&&saikoro[i][6-k-1]==saikoro[j][6-l-1])||(saikoro[i][k]==saikoro[j][6-l-1]&&saikoro[i][6-k-1]==saikoro[j][l])){
	      cnt++;
	    }
	  }
	}
	//cout<<cnt<<endl;
	if(cnt==3){
	  ans++;
	}
      }
    }
    cout<<ans<<endl;
  }
}