#include <bits/stdc++.h>
using namespace std;
template <class T>
void swap(T &a, T &b) {
  T tmp = a;
  a = b;
  b = a;
}
static void rotate(vector<vector<int> > &v) {
  int a = v[0][0], b = v[0][1], c = v[1][0], d = v[1][1];
  v[0][0] = b;
  v[0][1] = d;
  v[1][1] = c;
  v[1][0] = a;
}
static bool equals(const vector<vector<int> > &a,
                   const vector<vector<int> > &b) {
  for (size_t i = 0; i < 2; i++)
    for (size_t j = 0; j < 2; j++)
      if (a[i][j] != b[i][j]) return false;
  return true;
}
static map<size_t, bool> T;
static void setSetDomino(vector<vector<int> > &a) {
  for (size_t i = 0; i < 5; i++) {
    size_t key = a[0][0] + 10 * a[0][1] + 100 * a[1][1] + 1000 * a[1][0];
    T[key] = true;
    rotate(a);
  }
}
static bool isSetDomino(vector<vector<int> > &a) {
  for (size_t i = 0; i < 5; i++) {
    size_t key = a[0][0] + 10 * a[0][1] + 100 * a[1][1] + 1000 * a[1][0];
    map<size_t, bool>::const_iterator it = T.find(key);
    if (it != T.end()) return true;
    rotate(a);
  }
  return false;
}
int main(int argc, char *argv[]) {
  size_t N;
  cin >> N;
  vector<vector<vector<int> > > V;
  for (size_t i = 0; i < N; i++) {
    vector<vector<int> > tmp(2);
    for (size_t j = 0; j < 2; j++) {
      int a;
      cin >> a;
      tmp[j].push_back(a / 10);
      tmp[j].push_back(a % 10);
    }
    V.push_back(tmp);
    if (i + 1 < N) {
      string line;
      cin >> line;
    }
  }
  size_t ret = 0;
  for (size_t i = 0; i < N; i++) {
    vector<vector<int> > &a = V[i];
    if (isSetDomino(a)) continue;
    bool haveOne = false;
    for (size_t j = i + 1; j < N && !haveOne; j++) {
      vector<vector<int> > &b = V[j];
      for (size_t k = 0; k < 5; k++) {
        if (equals(a, b)) {
          ret++;
          setSetDomino(a);
          haveOne = true;
          break;
        }
        rotate(b);
      }
    }
    if (!haveOne) {
      setSetDomino(a);
      ret++;
    }
  }
  cout << ret << endl;
  return 0;
}
