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 <vector>
#include <algorithm>
using namespace std;

typedef vector<int> V;
typedef vector<V> VV;

int N;
VV cubes;
int front[6] = {5, 4, 3, 2, 1, 0};
int sides[6][4] = {
  {1, 3, 4, 2},
  {0, 2, 5, 3},
  {0, 4, 5, 1},
  {0, 1, 5, 4},
  {0, 3, 5, 2},
  {1, 2, 4, 3}
};

int str2id(string s) {
  if (s == "Red") {
    return 0;
  } else if (s == "Yellow") {
    return 1;
  } else if (s == "Blue") {
    return 2;
  } else if (s == "Magenta") {
    return 3;
  } else if (s == "Green") {
    return 4;
  } else if (s == "Cyan") {
    return 5;
  } else {
    return -1;
  }
}

bool input() {
  cin >> N;
  if (!N) {
    return false;
  }
  cubes.resize(N);
  
  for (int i = 0; i < N; ++i) {
    cubes[i].resize(6);
    for (int j = 0; j < 6; ++j) {
      string s;
      cin >> s;
      cubes[i][j] = str2id(s);
    }
  }

  return true;
}

void align(V &v) {
  int tmp[6];
  int z = -1;
  for (int i = 0; i < 6; ++i) {
    if (v[i] == 0) {
      z = i;
    }
  }
  tmp[0] = 0;
  tmp[1] = v[front[z]];
  int x = 6;
  int y = -1;
  for (int i = 0; i < 4; ++i) {
    if (x > v[sides[z][i]]) {
      x = v[sides[z][i]];
      y = i;
    }
  }
  for (int i = 0; i < 4; ++i) {
    tmp[i + 2] = v[sides[z][(y + i) % 4]];
  }
  for (int i = 0; i < 6; ++i) {
    v[i] = tmp[i];
  }
}

int solve() {
  for (int i = 0; i < N; ++i) {
    align(cubes[i]);
  }
  sort(cubes.begin(), cubes.end());
  VV::iterator it = unique(cubes.begin(), cubes.end());
  int num_uniq = it - cubes.begin();
  return N - num_uniq;
}

int main() {
  while (input()) {
    int ans = solve();
    cout << ans << endl;
  }
  return 0;
}

C++: #include<iostream>
#include<vector>
#include<complex>
#include<algorithm>
#include<set>
#include<map>
#define rep(i,n) for(int i = 0;i < n ; ++i)

using namespace std;

using ll = long long;

struct die{
    int u,d,l,r,b,f;
    die(vector<int> a){
        f=a[0];
        u=a[1];
        l=a[2];
        r=a[3];
        d=a[4];
        b=a[5];

        if(b==0){
            swap(b,f);
            swap(l,r);
        }
        if(d==0){
            int tmp = d;
            d = b; b = u; u = f; f = tmp;
        } 
        if(u==0){
            int tmp = u;
            u = b; b = d; d = f; f = tmp;
        }
        if(l==0){
            int tmp = l;
            l = b; b = r; r = f; f = tmp;
        }
        if(r==0){
            int tmp = r;
            r = b; b = l; l = f; f = tmp;
        }
        int mi = min({u,d,l,r});
        while(u!=mi){
           int tmp = r;
            r = u; u = l; l = d; d = tmp; 
        }
    }
    bool operator==(const die rhs)const{
        return (f==rhs.f&&b==rhs.b&&u==rhs.u&&d==rhs.d&&l==rhs.l&&r==rhs.r);
    }
};

map<string, int> mp;
void solve(int n){
    vector<die> d;
    rep(i,n){
        vector<int> a(6);
        rep(j,6){
            string s;cin>>s;
            a[j]=mp[s];
        }
        die di(a);
        d.push_back(di);
    }
    vector<int> used(n);
    int ans = 0;
    rep(i,n){
        if(used[i]){
            ++ans;
            continue;
        }
        for(int j = i+1;j<n;j++){
            if(d[i]==d[j])used[j]=true;
        }
    }
    cout<<ans<<endl;
}
int main(){
     mp["Cyan"]=0;
     mp["Yellow"]=1;
     mp["Red"]=2;
     mp["Magenta"]=3;
     mp["Green"]=4;
     mp["Blue"]=5;
     int n;
     while(cin>>n,n!=0)solve(n);
}

C++: #include<iostream>
#include<cstdio>
#include<string.h>
using namespace std;
int main() {
	int a, b[101][101],kotaneet=0,ruio=0;
	char str[101];
	while (1) {
		cin >> a;
		if (a == 0)return 0;
		ruio = a;
		for (int i = 1; i <= a; i++) {
			for (int j = 1; j <= 6; j++) {
				scanf("%s", str);
				if (strstr(str, "Red") != NULL) {
					b[i][j] = 1;
				}
				if (strstr(str, "Yellow") != NULL) {
					b[i][j] = 2;
				}
				if (strstr(str, "Blue") != NULL) {
					b[i][j] = 3;
				}
				if (strstr(str, "Magenta") != NULL) {
					b[i][j] = 4;
				}
				if (strstr(str, "Green") != NULL) {
					b[i][j] = 5;
				}
				if (strstr(str, "Cyan") != NULL) {
					b[i][j] = 6;
				}
			}
		}
		kotaneet = 0;
		int tatuo = 0;
		for (int i = 1; i <= a; i++) {
			for (int j = 1; j <= a; j++) {
				if (j != i && b[j][1] != -1 &&b[i][1]!=-1) {
					//cout << "tatuya0" << endl;
					if (b[i][1] + b[i][6] == b[j][1] + b[j][6]) {
						//cout << "tatuya1" << endl;
						if (b[i][3] + b[i][4] == b[j][3] + b[j][4]) {
							//cout << "tatuya2" << endl;
							if (b[i][2] + b[i][5] == b[j][2] + b[j][5]) {
								//cout << "tatuya3" << endl;
								b[i][1] = -1;
								ruio--;
								tatuo++;
							}
							if (tatuo > 0)break;
						}
						if (tatuo > 0)break;
					}
					if (tatuo > 0) break;
				}
				if (tatuo > 0) {
					tatuo = 0;
					break;
				}
			}
		}
		cout << a-ruio << endl;
	}
}

C++: //http://qiita.com/Nabetani/items/f3cca410428f90333e28
//http://nabetani.sakura.ne.jp/hena/ord12rotdice/
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <set>
using namespace std;

int make_hash(vector<int> &cube)
{
    int ret;
     
    ret = 0;
    for (int i = 0; i < 6; i++){
        ret = ret * 6 + cube[i];
    }
     
    return (ret);
}

// http://www.prefield.com/algorithm/misc/dice.html
enum FACE { TOP, LEFT, FRONT, BACK, RIGHT, BOTTOM };
class dice {
public:
  dice(vector<int>&v):id(v) {}
  void roll_x() { roll(TOP, BACK, BOTTOM, FRONT); }
  void roll_x2() { roll(TOP, FRONT, BOTTOM, BACK); }
  void roll_y() { roll(TOP, LEFT, BOTTOM, RIGHT); }
  void roll_y2() { roll(TOP, RIGHT, BOTTOM, LEFT); }
  void roll_z() { roll(FRONT, RIGHT, BACK, LEFT); }
  void roll_z2() { roll(FRONT, LEFT, BACK, RIGHT); }
  void all_rolls(set<int>&s){
    for (int k = 0; k < 6; (k&1?roll_y():roll_x()),++k)
      for (int i = 0; i < 4; roll_z(), ++i)
        s.insert(make_hash(id));
  }
  vector<int> id;
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;
  }
};



int main(){
	map<char,int>m;
	m['R']=0,m['Y']=1,m['B']=2,m['M']=3,m['G']=4,m['C']=5;
	string str;
	int n,i,j,r,x;
	for(;cin>>n,n;){
		set<int>s;
		for(r=i=0;i<n;i++){
			vector<int>v;
			for(j=0;j<6;j++)cin>>str,v.push_back(m[str[0]]);
			x=make_hash(v);
			//cout<<"---"<<x<<endl;
			if(s.find(x)!=s.end())r++;
			else{
				dice d(v);
				d.all_rolls(s);
			}
//set<int>::iterator it=s.begin();
//for(;it!=s.end();it++,cout<<endl)cout<<(*it);
		}
		cout<<r<<endl;
	}
}