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 Dice[6][6] = { { 1,5,2,3,0,4 },{ 4,0,2,3,5,1 },{ 3,1,0,5,4,2 },{ 2,1,5,0,4,3 },{ 0,2,4,1,3,5 },{ 0,3,1,4,2,5 } }, power[6] = { 1,3,9,27,81,243 };
struct Saikoro { int x[6]; }; Saikoro T[30]; int n, vis[30]; char F[7] = "CYRMGB"; bool G[30][30];
bool bfs(int p, int q) {
	for (int i = 0; i < 729; i++) {
		int bit[6]; for (int j = 0; j < 6; j++) { bit[j] = (i / power[j]) % 3; }
		Saikoro U = T[p];
		for (int j = 0; j < 6; j++) {
			for (int k = 0; k <= bit[j]; k++) {
				Saikoro V = U; for (int l = 0; l < 6; l++)V.x[l] = U.x[Dice[j][l]]; U = V;
			}
		}
		bool OK = true; for (int j = 0; j < 6; j++) { if (T[q].x[j] != U.x[j])OK = false; }
		if (OK == true)return true;
	}
	return false;
}
int main() {
	while (true) {
		for (int i = 0; i < 30; i++) { for (int j = 0; j < 30; j++)G[i][j] = false; vis[i] = 0; }
		cin >> n; if (n == 0)break; for (int i = 0; i < n; i++) { for (int j = 0; j < 6; j++) { string S; cin >> S; for (int k = 0; k < 6; k++) { if (S[0] == F[k])T[i].x[j] = k; } } }
		for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { G[i][j] = bfs(i, j); G[j][i] = G[i][j]; } }
		int cnt = 0; for (int i = 0; i < n; i++) { if (vis[i] != 0)continue; cnt++; vis[i] = cnt; for (int j = 0; j < n; j++) { for (int k = 0; k < n; k++) { if (vis[k] != cnt)continue; for (int l = 0; l < n; l++) { if (G[k][l] == true)vis[l] = cnt; } } } }
		cout << n - cnt << endl;
	}
	return 0;
}

C++: #include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>

using namespace std;

vector<string> CubeInfo[30];
string StrTmp[6];
int N;
bool SameFlag[30];
//top front right left back bottom
int RotateBase[24][6] = {
	{ 0,1,2,3,4,5 },{},{},{},
	{ 1,5,2,3,0,4 },{},{},{},
	{ 2,1,5,0,4,3 },{},{},{},
	{ 3,1,0,5,4,2 },{},{},{},
	{ 4,0,2,3,5,1 },{},{},{},
	{ 5,4,2,3,1,0 },{},{},{},
};


void fullRotateBase() {
	int tmp[6], num;

	for (int i = 0; i < 21; i += 4) {
		for (int j = 0; j < 6; ++j) {
			tmp[j] = RotateBase[i][j];
		}
		for (int k = 1; k < 4; ++k) {
			num = tmp[1];
			tmp[1] = tmp[3];
			tmp[3] = tmp[4];
			tmp[4] = tmp[2];
			tmp[2] = num;
			for (int j = 0; j < 6; ++j) {
				RotateBase[i + k][j] = tmp[j];
			}
		}
	}
	/*for (int i = 0; i < 24; ++i) {
		for (int j = 0; j < 6; ++j) {
			cout << RotateBase[i][j] + 1 << " ";
		}
		cout << endl;
	}
	cout << endl;*/
}

bool judgeSame(int i, int j) {
	string tmp[6];
	bool flag;

	for (int id = 0; id < 24; ++id) {
		for (int k = 0; k < 6; ++k) {
			tmp[k] = CubeInfo[j][RotateBase[id][k]];
		}
		for (int k = 0; k < 6; ++k) {
			if (CubeInfo[i][k] != tmp[k]) {
				flag = false;
				break;
			}
			flag = true;
		}
		if (flag) {
			return true;
		}
	}
	return false;
}

int solve() {
	int cnt;

	cnt = 0;
	for (int i = 0; i < N; ++i) {
		if (SameFlag[i]) {
			continue;
		}
		for (int j = i + 1; j < N; ++j) {
			if (judgeSame(i, j)) {
				SameFlag[j] = true;
				++cnt;
			}
		}
	}
	return cnt;
}

int main() {
	string str;

	fullRotateBase();
	while (cin >> N, N) {
		memset(SameFlag, false, sizeof(SameFlag));
		for (int i = 0; i < N; ++i) {
			CubeInfo[i].clear();
			for (int j = 0; j < 6; ++j) {
				cin >> str;
				CubeInfo[i].push_back(str);
			}
		}
		cout << solve() << endl;
	}

	return 0;
}

C++: #include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <complex>
#include <cstring>
#include <cstdlib>
#include <string>
#include <cmath>
#include <queue>
using namespace std;

#define REP(i,n) for(int i=0;i<(int)n;++i)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()
const int INF = 1<<30;

enum FACE { TOP, BOTTOM, FRONT, BACK, LEFT, RIGHT };
template <class T>
class dice {
public:
  dice(T *v) {
    id[TOP] = 0; id[FRONT] = 1; id[LEFT] = 3;
    id[RIGHT] = 2; id[BACK] = 4; id[BOTTOM] = 5;
    REP(i,6)
      var[i] = v[i];
  }
  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(cin>>n,n) {
    vector<dice<string> > v;
    REP(i,n) {
      string s[6];
      REP(j,6)
        cin >> s[j];
      v.push_back(dice<string>(s));
    }
    vector<bool> f(n);
    int num = 0;
    REP(i,n) {
      if (f[i]) continue;
      num++;
      for(int j=i+1; j<n; ++j) {
        if (f[j]) continue;
        if (v[i].equivalent_to(v[j])) {
          f[j] = true;
        }
      }
    }
    cout << n-num << endl;
  }
}