#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
#include <cmath>
#include <bitset>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <algorithm>
#include <complex>
#include <unordered_map>
#include <unordered_set>
#include <random>
#include <cassert>
using namespace std;
typedef long long int ll;
typedef pair<int, int> P;
int num[4][4]={{2, 5, 4, 3}, {0, 7, 6, 1}, {1, 6, 5, 2}, {3, 4, 7, 0}};
unordered_map<ll, ll> mp, mp2;
ll ans;
ll c2[8];
void dfs(int i){
	if(i==4){
		ll ans1=1;
		for(auto p:mp2){
			ll x=mp[p.first];
			for(ll l=0; l<p.second; l++) ans1*=(x-l);
		}
		ans+=ans1;
		return;
	}
	for(int j=0; j<4; j++){
		ll p=1, c=0;
		for(int k=0; k<4; k++){
			c+=c2[num[i][(j+k)%4]]*p;
			p*=1000;
		}
		if(mp.find(c)==mp.end()) continue;
		mp2[c]++;
		dfs(i+1);
		mp2[c]--;
	}
}
int main()
{
	int n;
	cin>>n;
	vector<ll> c;
	for(int i=0; i<n; i++){
		ll c1[4], cp[4];
		for(int j=0; j<4; j++) cin>>c1[j];
		for(int j=0; j<4; j++){
			ll p=1; cp[j]=0;
			for(int k=0; k<4; k++){
				cp[j]+=(c1[(j+k)%4]*p);
				p*=1000;
			}
		}
		sort(cp, cp+4);
		mp[cp[0]]++;
	}
	for(auto p:mp) c.push_back(p.first);
	for(int i=0; i<c.size(); i++){
		ll c1=c[i];
		for(int j=0; j<4; j++){
			c2[j]=c1%1000;
			c1/=1000;
		}
		for(int j=0; j<c.size(); j++){
			for(int k=0; k<4; k++){
				ll c3=c[j];
				for(int l=0; l<4; l++){
					c2[4+(k+l)%4]=c3%1000; c3/=1000;
				}
				mp2.clear(); mp2[c[i]]++; mp2[c[j]]++;
				dfs(0);
			}
		}
	}
	cout<<ans/6<<endl;
	return 0;
}