// Original C++ solution (slower):
#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>

using namespace __gnu_pbds;

using namespace std;



typedef long long ll;

typedef pair<int, int> pii;

typedef pair<int, pii> pipii;

typedef pair<pii, int> piipi;

typedef pair<pii, pii> piipii;



#define mp make_pair

#define fi first

#define se second

#define all(a) (a).begin(), (a).end()

#define sz(a) (int)(a).size()

#define eb emplace_back



piipii c[405];

piipii rotate(piipii x){

    return mp(mp(x.se.se, x.fi.fi), mp(x.fi.se, x.se.fi));

}



ll get_idx(piipii x){

    return x.fi.fi*1ll*1000*1000*1000 + x.fi.se*1ll*1000*1000 + x.se.fi*1ll*1000 + x.se.se;

}

gp_hash_table<ll, int> dp;



void add(piipii p){

    for(int k=0;k<4;k++){

        dp[get_idx(p)]++;

        p = rotate(p);

    }   

}

void del(piipii p){

    for(int k=0;k<4;k++){

        dp[get_idx(p)]--;

        p = rotate(p);

    }

}





int main(){

    int n;

    scanf("%d", &n);   

    for(int i=1;i<=n;i++){

        scanf("%d%d%d%d", &c[i].fi.fi, &c[i].fi.se, &c[i].se.fi, &c[i].se.se);

        add(c[i]);

    }

    double ans = 0;

    for(int i=1;i<=n;i++){

        for(int j=1;j<=n;j++){

            if(i == j) continue;

            piipii p1 = c[i];

            for(int k=0;k<4;k++){

                del(p1);

                piipii p2 = c[j];

                for(int l=0;l<4;l++){

                    del(p2);



                    double res = 1;

                    piipii tmp1 = mp(mp(p1.fi.se, p1.fi.fi), mp(p2.fi.se, p2.fi.fi));

                    piipii tmp2 = mp(mp(p1.fi.se, p2.fi.fi), mp(p2.se.se, p1.se.fi));

                    piipii tmp3 = mp(mp(p1.se.se, p1.se.fi), mp(p2.se.se, p2.se.fi));

                    piipii tmp4 = mp(mp(p2.fi.se, p1.fi.fi), mp(p1.se.se, p2.se.fi));

                    if(dp.find(get_idx(tmp1)) != dp.end()){

                        res *= dp[get_idx(tmp1)];

                        del(tmp1);

                    }

                    else res = 0;

                    if(dp.find(get_idx(tmp2)) != dp.end()){

                        res *= dp[get_idx(tmp2)];

                        del(tmp2);

                    }

                    else res = 0;

                    if(dp.find(get_idx(tmp3)) != dp.end()){

                        res *= dp[get_idx(tmp3)];

                        del(tmp3);

                    }

                    else res = 0;

                    if(dp.find(get_idx(tmp4)) != dp.end()){

                        res *= dp[get_idx(tmp4)];

                        del(tmp4);

                    }

                    else res = 0;



                    ans += res;



                    if(dp.find(get_idx(tmp1)) != dp.end()){

                        add(tmp1);

                    }

                    if(dp.find(get_idx(tmp2)) != dp.end()){

                        add(tmp2);

                    }

                    if(dp.find(get_idx(tmp3)) != dp.end()){

                        add(tmp3);

                    }

                    if(dp.find(get_idx(tmp4)) != dp.end()){

                        add(tmp4);

                    }

                    

                    add(p2);

                    p2 = rotate(p2);

                }



                add(p1);

                p1 = rotate(p1);

            }

        }

    }

    printf("%.0lf\n", ans/24);

}

// Optimized solution to the same problem (faster):
#include<bits/stdc++.h>

#define inf 0x7fffffff

#define RG register

#define inf 0x7fffffff

#define mkp make_pair

#define maxn 100205

typedef unsigned int U;

using namespace std;

typedef long long ll;

const ll mod = 998244353;

const  double eps = 1e-8;

const double pi = acos(-1);

inline ll read(){

    ll x = 0, f = 1;

    char ch = getchar();

    while(ch > '9' || ch < '0') {if(ch == '-') f = -1;ch = getchar();}

    while(ch >= '0' && ch <= '9'){x = x *10 + ch -'0';ch = getchar();}

    return x * f;

}

int n,m,inde[100005],tot;

struct p{

	int c[4];

	bool operator < (const p & a)const{

		if(c[0]!=a.c[0]) return c[0]<a.c[0];

		if(c[1]!=a.c[1]) return c[1]<a.c[1];

		if(c[2]!=a.c[2]) return c[2]<a.c[2];

		return c[3]<a.c[3];

	}

}col[405];

map<p,int> mp;

void add(p x,int val){

	p now=x,nxt;

	mp[now]+=val;

	for(int j=1;j<=3;j++){

		for(int i=0;i<=3;i++) nxt.c[i]=now.c[(i+1)%4];

		now=nxt;

		mp[now]+=val;

	}

}

int main(){

	int i,j,u,v,e,w;

	//freopen("a.out","r",stdin);

	//freopen("a.ans","w",stdout);

	n=read();

	for(i=1;i<=n;i++)

		col[i].c[0]=read(),col[i].c[1]=read(),col[i].c[2]=read(),col[i].c[3]=read();

	for(i=1;i<=n;i++) 

		add(col[i],1);

	ll ans=0,S;

	for(i=1;i<=n-5;i++){

		add(col[i],-1);

		for(j=i+1;j<=n;j++){

			add(col[j],-1);

			p now,nxt=col[j],pj;

			for(e=1;e<=4;e++){

				now=nxt;

				S=1;

				for(w=0;w<=3;w++) nxt.c[w]=now.c[(w+1)%4];

				for(w=0;w<=3;w++){

					pj=(p){col[i].c[(w+1)%4],col[i].c[w],now.c[3-w],now.c[3-(w+1)%4]};

					S*=mp[pj];

					if(!mp[pj]) break;

					else add(pj,-1);

				}

				w--;

				for(;w>=0;w--){

					pj=(p){col[i].c[(w+1)%4],col[i].c[w],now.c[3-w],now.c[3-(w+1)%4]};

					add(pj,1);

				}

				ans+=S;

			}

			add(col[j],1);

		}

	}

	printf("%lld\n",ans);

	return 0;

}

/*

8

0 0 0 0

0 0 1 1

0 1 0 1

0 1 1 0

1 0 0 1

1 0 1 0

1 1 0 0

1 1 1 1

*/

// Fastest known solution for this problem: