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
#include <iostream>
#include <complex>
#include <algorithm>
#include <vector>
#include <stack>
#include <string>
#include <queue>
#include <cmath>
#include <math.h>
#include <numeric>
#include <list>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <climits>
#include <set>
#include <memory.h>
#include <memory>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cassert>
#include <map>
#include <cassert>
#include <time.h>
#include <ctime>

using namespace std;

typedef complex<double> xy_t;
typedef pair<xy_t, xy_t> line;
typedef long long ll;
typedef pair<int, int> P;
typedef pair<int , P> PP;
typedef pair<int, string> Ps;
typedef vector<int> vec;
typedef vector<vec> mat;
const int INF = 1 << 27;
const double EPS = 1e-9;
const double PI = 3.1415926535897932384626433832795;
const int CLK = CLOCKS_PER_SEC;

#define rep(i, n) for(int i = 0; i < n; i++)
#define rep2(i, m, n) for(int i = m; i < n; i++)

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

map<vector<string>, bool> used;


int main(){
	vector<string> vs(6, "");
	vector<string> cs(6, "");
	int n, res;
	while(cin >> n && n ){
		res = 0;
		used.clear();
		rep(i, n){
			rep(j, 6) cin >> cs[j];
			rep(j, 24){
				rep(k, 6){
					vs[k] = cs[dice[j][k]];
				}
				if(used[vs]) res++;
				used[vs] = true;
			}
		}
		cout << res / 24 << endl;
	}
	return 0;
}

C++: #include <bits/stdc++.h>

#define fst(t) std::get<0>(t)
#define snd(t) std::get<1>(t)
#define thd(t) std::get<2>(t)
#define unless(p) if(!(p))
#define until(p) while(!(p))

using ll = std::int64_t;
using P = std::tuple<int,int>;

struct Perm{
    std::vector<int> perm;

    Perm(std::initializer_list<int> p) : perm(p.begin(), p.end()) { }

    static Perm identity(){
        return {0, 1, 2, 3, 4, 5};
    }

    Perm& operator*=(const Perm &rhs){
        std::vector<int> p(6);
        for(int i=0;i<6;++i){
            p[i] = perm[rhs.perm[i]];
        }

        perm = std::move(p);

        return *this;
    }
};

const Perm r1 = {5, 3, 4, 1, 2, 0}, // 表裏をひっくり返す
    r2 = {0, 3, 1, 4, 2, 5}, // 水平面に垂直な軸に関して回転
    r3 = {2, 0, 1, 4, 5, 3}; // 見えている面を変えない回転
std::vector<Perm> perms;

struct Cube{
    std::vector<std::string> surface;

    Cube() = default;
    Cube(std::vector<std::string> v) : surface(std::move(v)) { }

    friend bool operator==(const Cube &lhs, const Cube &rhs){
        for(auto &p : perms){
            bool eq = true;

            for(int i=0;i<6;++i){
                if(lhs.surface[i] != rhs.surface[p.perm[i]]){
                    eq = false;
                    break;
                }
            }

            if(eq){
                return true;
            }
        }

        return false;
    }
};

int main(){
    std::cin.tie(nullptr);
    std::ios::sync_with_stdio(false);

    std::queue<Perm> que;
    que.emplace(Perm::identity());
    que.emplace(r1);
    
    for(int i=0;i<2;++i){
        Perm p = que.front();
        que.pop();

        for(int j=0;j<4;++j){
            que.emplace(p);
            p *= r2;
        }
    }

    for(int i=0;i<8;++i){
        Perm p = que.front();
        que.pop();

        for(int j=0;j<3;++j){
            que.emplace(p);
            p *= r3;
        }
    }

    until(que.empty()){
        perms.emplace_back(que.front());
        que.pop();
    }

    while(true){
        int N;
        std::cin >> N;

        if(N == 0){
            break;
        }

        std::vector<Cube> cubes(N);
    
        for(int i=0;i<N;++i){
            std::vector<std::string> v(6);

            for(int j=0;j<6;++j){
                std::cin >> v[j];
            }

            cubes[i] = std::move(Cube(v));
        }

        ll used = 0;
        int cnt = 0;
        
        for(int i=0;i<N;++i){
            if(used >> i & 1){
                continue;
            }

            cnt += 1;

            for(int j=i+1;j<N;++j){
                if(cubes[j] == cubes[i]){
                    used |= 1ll << j;
                }
            }
        }

        int left = N - cnt;
        std::cout << left << std::endl;
    }
}

C++: #include<cstdio>
#include<algorithm>
#include<iostream>
#include<vector>
#include<set>
#include<queue>

using namespace std;

#define rep(i,n) for(int i=0;i<int(n);i++)
#define reps(i,n) for(int i=1;i<=int(n);i++)

#define f first
#define s second

int main(){
	while(1){
		int n;
		cin>>n;
		
		if(n==0)break;
		
		set<vector<int> > ch;
		
		rep(pp,n){
			vector<int> a;
			rep(j,6){
				string sa;
				cin>>sa;
				switch(sa[0]){
					case 'C':a.push_back(0);break;
					case 'Y':a.push_back(1);break;
					case 'R':a.push_back(2);break;
					case 'M':a.push_back(3);break;
					case 'G':a.push_back(4);break;
					case 'B':a.push_back(5);break;
				}
			}
			
			rep(i,4){
				int temp=a[0];
				a[0]=a[4];
				a[4]=a[5];
				a[5]=a[1];
				a[1]=temp;
				
				rep(j,4){
					temp=a[0];
					a[0]=a[2];
					a[2]=a[5];
					a[5]=a[3];
					a[3]=temp;
					
					rep(k,4){
						temp=a[1];
						a[1]=a[2];
						a[2]=a[4];
						a[4]=a[3];
						a[3]=temp;
						
						ch.insert(a);
					}
				}
			}
			
		}
		
		printf("%d\n",(n-ch.size()/24));
	}
}