// Original C++ solution (slower):
//

/*==========================================================*/

/*    Template ver 2017-0720    |    Created by JollyBee    */

/* DOMINUS pascit me, et nihil mihi deerit (Psalmorum 23:1) */

/*==========================================================*/

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

typedef unsigned long long ull;

typedef vector<int> vi;

typedef pair<int,int> pii;

typedef pair<ll,ll> pll;

typedef vector<pii> vii;

const double EPS=(double)1e-9;

const double PI=(double)acos(-1.0);

#define fi first

#define se second

#define mp make_pair

#define pb push_back

#define pob pop_back

#define pf push_front

#define pof pop_front

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

#define REPP(i,l,r,c) for(int i=l;i<=r;i+=c)

#define REP(i,l,r) REPP(i,l,r,1)

#define FORD(i,n) for(int i=n-1;i>=0;i--)

#define REVV(i,l,r,c) for(int i=l;i>=r;i-=c)

#define REV(i,l,r) REVV(i,l,r,1)

//random

int irand(int lo, int hi){

    return (((double)rand())/(RAND_MAX+1.0)) * (hi-lo+1) + lo;

}

//ll to string

string toString(ll x) {

    stringstream ss;

    ss << x;

    return ss.str();

}

//string to ll

ll toNumber(string S) {

    ll ret;

    sscanf(S.c_str(),"%lld",&ret);

    return ret;

}

// std::fill(start, end, value);

// for(auto it: DS){}



const int INF=(int)2e9;

const ll MOD=(ll)1e9+7;

/*==========================================================*/

/*                     END OF TEMPLATE                      */

/* DOMINUS pascit me, et nihil mihi deerit (Psalmorum 23:1) */

/*==========================================================*/



typedef pair<pii,pii> square;



square rotate(square a){

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

}

square normalize(square a){

    square res = a;

    FOR(i,4) res = min(res, a=rotate(a));

    return res;

}

int cnt_rotate(square a){

    int res = 0; square b = a;

    FOR(i,4) res += (a == (b=rotate(b)));

    return res;

}



vector<square> get_list(square a, square b){

    vector<square> res; res.clear();

    res.pb(normalize(mp(mp(a.fi.fi,b.fi.se), mp(b.fi.fi,a.fi.se))));

    res.pb(normalize(mp(mp(a.fi.se,b.fi.fi), mp(b.se.se,a.se.fi))));

    res.pb(normalize(mp(mp(a.se.fi,b.se.se), mp(b.se.fi,a.se.se))));

    res.pb(normalize(mp(mp(a.se.se,b.se.fi), mp(b.fi.se,a.fi.fi))));

    return res;

}



square dat[405];

map<square,int> cnt;



int main(){

    cnt.clear();

    //

    int n; scanf("%d", &n);

    REP(i,1,n){

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

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

        dat[i] = normalize(dat[i]);

        //

        if(cnt.find(dat[i]) == cnt.end()) cnt[dat[i]] = 0;

        cnt[dat[i]] += 1;

    }

    //

    ll res = 0;

    REP(i,1,n) REP(j,1,n) if(i != j){

        square a = dat[i], b = dat[j];

        //

        cnt[a] -= 1; cnt[b] -= 1;

        FOR(i,4){

            vector<square> datt = get_list(a, b=rotate(b));

            // count

            ll ret = 1;

            for(square x: datt){

                ret *= (ll)cnt_rotate(x) * (ll)max(0, cnt[x]);

                cnt[x] -= 1;

            }

            for(square x: datt) cnt[x] += 1;

            //

            res += ret;

        }

        assert(b == dat[j]);

        cnt[a] += 1; cnt[b] += 1;

    }

    //

    printf("%lld\n", res / (ll)6);

    return 0;

}


// 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: