#include <iostream>
#include <map>
#define llint long long

using namespace std;

struct Tile{
	int c[4];
	Tile(){}
	Tile(int a, int b, int C, int d){
		c[0] = a, c[1] = b, c[2] = C, c[3] = d;
	}
	Tile(int a[]){
		for(int i = 0; i < 4; i++) c[i] = a[i];
	}
	Tile rot(){
		Tile tmp;
		for(int i = 0; i < 4; i++){
			tmp.c[i] = c[(i+1)%4];
		}
		return tmp;
	}
	bool equal(Tile &obj){
		for(int i = 0; i < 4; i++){
			if(c[i] != obj.c[i]) return false;
		}
		return true;
	}
	bool similar(Tile &obj)
	{
		Tile tmp = obj;
		for(int i = 0; i < 4; i++){
			if(equal(tmp)) return true;
			tmp = tmp.rot();
		}
		return false;
	}
	int sym()
	{
		int ret = 0;
		Tile tmp = *this;
		for(int i = 0; i < 4; i++){
			if(equal(tmp)) ret++;
			tmp = tmp.rot();
		}
		return ret;
	}
	bool operator<(const Tile& obj)const{
		for(int i = 0; i < 4; i++){
			if(c[i] < obj.c[i]) return true;
			if(c[i] > obj.c[i]) return false;
		}
		return false;
	}
		
	void reg(){
		int a[4];
		for(int i = 0; i < 4; i++) a[i] = c[i];
		Tile tmp = *this;
		for(int i = 0; i < 4; i++){
			for(int j = 0; j < 4; j++){
				if(a[j] < tmp.c[j]) break;
				if(a[j] > tmp.c[j]){
					for(int k = 0; k < 4; k++) a[k] = tmp.c[k];
					break;
				}
			}
			tmp = tmp.rot();
		}
		for(int i = 0; i < 4; i++) c[i] = a[i];
	}
	void print()
	{
		for(int i = 0; i < 4; i++) cout << c[i] << " ";
		cout << endl;
	}
};

int N;
Tile tile[405];
map<Tile, int> mp;

int parent[4];
void init(){
	for(int i = 0; i < 4; i++) parent[i] = i;
}
int root(int i)
{
	if(parent[i] == i) return i;
	return parent[i] = root(parent[i]);
}
void unite(int i, int j)
{
	int root_i = root(i), root_j = root(j);
	if(root_i == root_j) return;
	parent[root_i] = root_j;
}
bool same(int i, int j)
{
	return root(i) == root(j);
}

llint perm(llint n, llint k)
{
	llint ret = 1;
	for(int i = 0; i < k; i++){
		ret *= n-i;
	}
	return ret;
}

int main(void)
{
	cin >> N;
	int c[4];
	for(int i = 0; i < N; i++){
		for(int j = 0; j < 4; j++) cin >> c[j];
		tile[i] = Tile(c);
		tile[i].reg();
	}
	
	for(int i = 0; i < N; i++) mp[tile[i]]++;
	
	llint ans = 0;
	llint cnt[4];
	for(int i = 0; i < N; i++){
		mp[tile[i]]--;
		for(int j = 0; j < N; j++){
			if(i >= j) continue;
			
			Tile t = tile[j];
			for(int k = 0; k < 4; k++){
				
				Tile need[4];
				need[0] = Tile(tile[i].c[1], tile[i].c[0], t.c[1], t.c[0]);
				need[1] = Tile(tile[i].c[2], tile[i].c[1], t.c[0], t.c[3]);
				need[2] = Tile(tile[i].c[3], tile[i].c[2], t.c[3], t.c[2]);
				need[3] = Tile(tile[i].c[0], tile[i].c[3], t.c[2], t.c[1]);
				for(int l = 0; l < 4; l++) need[l].reg();
				
				llint cnt[4];
				for(int l = 0; l < 4; l++){
					cnt[l] = mp[need[l]];
					if(tile[j].similar(need[l])) cnt[l]--;
				}
				
				init();
				for(int l = 0; l < 4; l++){
					for(int m = 0; m < 4; m++){
						if(l >= m) continue;
						if(same(l, m)) continue;
						if(need[l].similar(need[m])) unite(l, m);
					}
				}
				
				llint cnum[4];
				for(int i = 0; i < 4; i++) cnum[i] = 0;
				for(int i = 0; i < 4; i++){
					cnum[root(i)]++;
				}
				llint tmp = 1;
				for(int i = 0; i < 4; i++){
					if(cnum[i]) tmp *= perm(cnt[i], cnum[i]);
				}
				for(int i = 0; i < 4; i++) tmp *= need[i].sym();
				ans += tmp;
				
				t = t.rot();
			}
		}
	}
	
	cout << ans << endl;
	return 0;
}

Measured memory_bytes: 80128