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<bits/stdc++.h>
using namespace std;

//#define int long long

typedef pair<int,int>pint;
typedef vector<int>vint;
#define pb push_back
#define mp make_pair
#define rep(i,n) for(int i=0;i<(n);i++)
template<class T,class U>void chmin(T &t,U f){if(t>f)t=f;}
template<class T,class U>void chmax(T &t,U f){if(t<f)t=f;}

enum FACE { TOP, BOTTOM, FRONT, BACK, LEFT, RIGHT };
template <class T>
class dice {
public:
  dice() {
    id[TOP] = 0; id[FRONT] = 1; id[LEFT] = 2;
    id[RIGHT] = 3; id[BACK] = 4; id[BOTTOM] = 5;
  }
  T& operator[] (FACE f) { return var[id[f]]; }
  const T& operator[] (FACE f) const { return var[id[f]]; }
  bool operator==(const dice<T>& b) const {
    const dice<T> &a = *this;
    return a[TOP] == b[TOP] && a[BOTTOM] == b[BOTTOM] &&
           a[FRONT] == b[FRONT] && a[BACK] == b[BACK] &&
           a[LEFT] == b[LEFT] && a[RIGHT] == b[RIGHT];
  }
  void roll_x() { roll(TOP, BACK, BOTTOM, FRONT); }
  void roll_y() { roll(TOP, LEFT, BOTTOM, RIGHT); }
  void roll_z() { roll(FRONT, RIGHT, BACK, LEFT); }
  vector<dice> all_rolls() {
    vector<dice> ret;
    for (int k = 0; k < 6; (k&1?roll_y():roll_x()),++k)
      for (int i = 0; i < 4; roll_z(), ++i)
        ret.push_back(*this);
    return ret;
  }
  bool equivalent_to(const dice& di) {
    for (int k = 0; k < 6; (k&1?roll_y():roll_x()),++k)
      for (int i = 0; i < 4; roll_z(), ++i)
        if (*this == di) return true;
    return false;
  }
private:
  void roll(FACE a, FACE b, FACE c, FACE d) {
    int tmp = id[a];
    id[a] = id[b]; id[b] = id[c];
    id[c] = id[d]; id[d] = tmp;
  }
  T var[6];
  int id[6];
};


int main(){
    int N;
    while(scanf("%d",&N),N){
        vector<dice<string> >vec;
        int cnt=0;
        while(N--){
            dice<string> b;
            cin>>b[TOP];
            cin>>b[FRONT];
            cin>>b[RIGHT];
            cin>>b[LEFT];
            cin>>b[BACK];
            cin>>b[BOTTOM];
            bool ok=true;
            rep(i,vec.size())if(vec[i].equivalent_to(b))ok=false;
            if(ok)vec.pb(b);
            else cnt++;
        }
        cout<<cnt<<endl;
    }
    return 0;
}

C++: #include <bits/stdc++.h>
using namespace std;

typedef long long ll;
#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
#define each(itr,c) for(__typeof(c.begin()) itr=c.begin(); itr!=c.end(); ++itr)
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define fi first
#define se second

typedef vector<int> vi;

inline vi rotate(const vi &t)
{
    int idx=0;
    while(idx<6 && t[idx]!=0) ++idx;

    vi a;
    if(idx==0) a=vi({0,1,2,3,4,5});
    else if(idx==1) a=vi({1,5,2,3,0,4});
    else if(idx==2) a=vi({2,1,5,0,4,3});
    else if(idx==3) a=vi({3,1,0,5,4,2});
    else if(idx==4) a=vi({4,0,2,3,5,1});
    else if(idx==5) a=vi({5,4,2,3,1,0});

    vi ret(6);
    rep(i,6) ret[i]=t[a[i]];
    return ret;
}

inline vi normalize(const vi &t)
{
    vi side({t[1],t[2],t[4],t[3]});

    vector<vi> s;
    rep(i,4)
    {
        vi a(4);
        rep(j,4) a[j]=side[(j+i)%4];
        s.pb(a);
    }
    sort(all(s));
    return s[0];
}

int main()
{
    int n;
    while(cin >>n,n)
    {
        vector<vi> d(n);
        rep(i,n)
        {
            vi t(6);
            rep(j,6)
            {
                string s;
                cin >>s;
                if(s=="Red") t[j]=0;
                else if(s=="Yellow") t[j]=1;
                else if(s=="Blue") t[j]=2;
                else if(s=="Magenta") t[j]=3;
                else if(s=="Green") t[j]=4;
                else if(s=="Cyan") t[j]=5;
            }
            d[i]=rotate(t);
        }

        set<vi> s[6];
        rep(i,n) s[d[i][5]].insert(normalize(d[i]));

        int diff=0;
        rep(i,6) diff+=s[i].size();
        cout << n-diff << endl;
    }
    return 0;
}