// Slower C++ solution:
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

#define rep(i, n) for(int i = 0; i < (n); i++)

#define rep1(i, n) for(int i = 1; i <= (n); i++)

#define co(x) cout << (x) << "\n"

#define cosp(x) cout << (x) << " "

#define ce(x) cerr << (x) << "\n"

#define cesp(x) cerr << (x) << " "

#define pb push_back

#define mp make_pair

#define Would

#define you

#define please



typedef tuple<int, int, int, int> TP;

TP narabi(int a, int b, int c, int d) {

	TP kari[4];

	kari[0] = tie(a, b, c, d);

	kari[1] = tie(b, c, d, a);

	kari[2] = tie(c, d, a, b);

	kari[3] = tie(d, a, b, c);

	sort(kari, kari + 4);

	return kari[0];

}



int main() {

	cin.tie(0);

	ios::sync_with_stdio(false);





	int N;

	cin >> N;

	TP C[400];

	map<TP, int> MP;

	rep(i, N) {

		int a, b, c, d;

		cin >> a >> b >> c >> d;

		C[i] = narabi(a, b, c, d);

		MP[C[i]]++;

	}



	ll kotae = 0;

	rep(i, N) rep(j, N) if (i != j) {

		MP[C[i]]--;

		MP[C[j]]--;



		int a, b, c, d, e, f, g, h;

		a = get<0>(C[i]);

		b = get<1>(C[i]);

		c = get<2>(C[i]);

		d = get<3>(C[i]);

		e = get<0>(C[j]);

		f = get<1>(C[j]);

		g = get<2>(C[j]);

		h = get<3>(C[j]);



		rep(x, 4) {

			TP D[4];

			D[0] = narabi(a, d, f, e);

			D[1] = narabi(a, e, h, b);

			D[2] = narabi(b, h, g, c);

			D[3] = narabi(c, g, f, d);

			ll kari = 1;

			rep(k, 4) {

				kari *= MP[D[k]]--;

				if (get<0>(D[k]) == get<2>(D[k]) && get<1>(D[k]) == get<3>(D[k])) {

					kari *= 2;

					if (get<1>(D[k]) == get<2>(D[k])) kari *= 2;

				}

				if (kari < 0) kari = 0;

			}

			rep(k, 4) MP[D[k]]++;

			kotae += kari;



			int tmp = e;

			e = f;

			f = g;

			g = h;

			h = tmp;

		}



		MP[C[i]]++;

		MP[C[j]]++;

	}

	co(kotae / 6);



	Would you please return 0;

}

// Faster C++ solution for the same problem (measured speedup: 1.1051286436423309x):
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

#define rep(i, n) for(int i = 0; i < (n); i++)

#define rep1(i, n) for(int i = 1; i <= (n); i++)

#define co(x) cout << (x) << "\n"

#define cosp(x) cout << (x) << " "

#define ce(x) cerr << (x) << "\n"

#define cesp(x) cerr << (x) << " "

#define pb push_back

#define mp make_pair

#define Would

#define you

#define please



typedef tuple<int, int, int, int> TP;

TP narabi(int a, int b, int c, int d) {

	TP kari[4];

	kari[0] = tie(a, b, c, d);

	kari[1] = tie(b, c, d, a);

	kari[2] = tie(c, d, a, b);

	kari[3] = tie(d, a, b, c);

	return *min_element(kari, kari + 4);

}



int main() {

	cin.tie(0);

	ios::sync_with_stdio(false);





	int N;

	cin >> N;

	TP C[400];

	rep(i, N) {

		int a, b, c, d;

		cin >> a >> b >> c >> d;

		C[i] = narabi(a, b, c, d);

	}



	sort(C, C + N);

	int kazu[400] = {};

	rep(i, N) {

		int k = i;

		while (k + 1 < N && C[k + 1] == C[i]) k++;

		kazu[i] = k - i + 1;

		i = k;

	}



	ll kotae = 0;

	rep(i, N) rep(j, N) if (i != j) {

		int inum = lower_bound(C, C + N, C[i]) - C;

		int jnum = lower_bound(C, C + N, C[j]) - C;



		kazu[inum]--;

		kazu[jnum]--;



		int a, b, c, d, e, f, g, h;

		a = get<0>(C[i]);

		b = get<1>(C[i]);

		c = get<2>(C[i]);

		d = get<3>(C[i]);

		e = get<0>(C[j]);

		f = get<1>(C[j]);

		g = get<2>(C[j]);

		h = get<3>(C[j]);



		rep(x, 4) {

			TP D[4];

			D[0] = narabi(a, d, f, e);

			D[1] = narabi(a, e, h, b);

			D[2] = narabi(b, h, g, c);

			D[3] = narabi(c, g, f, d);

			TP* itr[4];

			rep(k, 4) itr[k] = lower_bound(C, C + N, D[k]);

			ll kari = 1;

			rep(k, 4) {

				if (itr[k] != C + N && *(itr[k]) == D[k]) {

					kari *= kazu[itr[k] - C]--;

					if (get<0>(D[k]) == get<2>(D[k]) && get<1>(D[k]) == get<3>(D[k])) {

						kari *= 2;

						if (get<1>(D[k]) == get<2>(D[k])) kari *= 2;

					}

				}

				else {

					kari = 0;

					break;

				}

			}

			rep(k, 4) {

				if (itr[k] != C + N && *itr[k] == D[k]) {

					kazu[itr[k] - C]++;

				}

				else break;

			}

			kotae += kari;



			int tmp = e;

			e = f;

			f = g;

			g = h;

			h = tmp;

		}

		kazu[inum]++;

		kazu[jnum]++;

	}

	co(kotae / 6);



	Would you please return 0;

}