// {{{ by shik
#ifdef __GNUC__
#ifndef __clang__
#pragma GCC optimize("O3")
#endif
#endif
#include <bits/stdc++.h>
#include <unistd.h>
#define SZ(x) ((int)(x).size())
#define ALL(x) begin(x),end(x)
#define REP(i,n) for ( int i=0; i<int(n); i++ )
#define REP1(i,a,b) for ( int i=(a); i<=int(b); i++ )
#define FOR(it,c) for ( auto it=(c).begin(); it!=(c).end(); it++ )
#define MP make_pair
#define PB push_back
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
typedef vector<int> VI;
 
#ifdef SHIK
template<typename T>
void _dump( const char* s, T&& head ) { cerr<<s<<"="<<head<<endl; }
 
template<typename T, typename... Args>
void _dump( const char* s, T&& head, Args&&... tail ) {
    int c=0;
    while ( *s!=',' || c!=0 ) {
        if ( *s=='(' || *s=='[' || *s=='{' ) c++;
        if ( *s==')' || *s==']' || *s=='}' ) c--;
        cerr<<*s++;
    }
    cerr<<"="<<head<<", ";
    _dump(s+1,tail...);
}
 
#define dump(...) do { \
    fprintf(stderr, "%s:%d - ", __PRETTY_FUNCTION__, __LINE__); \
    _dump(#__VA_ARGS__, __VA_ARGS__); \
} while (0)
 
template<typename Iter>
ostream& _out( ostream &s, Iter b, Iter e ) {
    s<<"[";
    for ( auto it=b; it!=e; it++ ) s<<(it==b?"":" ")<<*it;
    s<<"]";
    return s;
}
 
template<typename A, typename B>
ostream& operator <<( ostream &s, const pair<A,B> &p ) { return s<<"("<<p.first<<","<<p.second<<")"; }
template<typename T>
ostream& operator <<( ostream &s, const vector<T> &c ) { return _out(s,ALL(c)); }
template<typename T, size_t N>
ostream& operator <<( ostream &s, const array<T,N> &c ) { return _out(s,ALL(c)); }
template<typename T>
ostream& operator <<( ostream &s, const set<T> &c ) { return _out(s,ALL(c)); }
template<typename A, typename B>
ostream& operator <<( ostream &s, const map<A,B> &c ) { return _out(s,ALL(c)); }
#else
#define dump(...)
#endif
 
template<typename T>
void _R( T &x ) { cin>>x; }
void _R( int &x ) { scanf("%d",&x); }
void _R( long long &x ) { scanf("%" PRId64,&x); }
void _R( double &x ) { scanf("%lf",&x); }
void _R( char &x ) { scanf(" %c",&x); }
void _R( char *x ) { scanf("%s",x); }
 
void R() {}
template<typename T, typename... U>
void R( T& head, U&... tail ) {
    _R(head);
    R(tail...);
}
 
template<typename T>
void _W( const T &x ) { cout<<x; }
void _W( const int &x ) { printf("%d",x); }
template<typename T>
void _W( const vector<T> &x ) {
    for ( auto i=x.cbegin(); i!=x.cend(); i++ ) {
        if ( i!=x.cbegin() ) putchar(' ');
        _W(*i);
    }
}
 
void W() {}
template<typename T, typename... U>
void W( const T& head, const U&... tail ) {
    _W(head);
    putchar(sizeof...(tail)?' ':'\n');
    W(tail...);
}
 
#ifdef SHIK
#define FILEIO(...)
#else
#define FILEIO(name) do {\
    freopen(name ".in","r",stdin); \
    freopen(name ".out","w",stdout); \
} while (0)
#endif
 
// }}}
 
const int N=404;
 
inline LL f( LL a, LL b, LL c, LL d ) {
    return (a<<30)|(b<<20)|(c<<10)|d;
}
 
inline LL rot( LL x ) {
    const LL msk=(1LL<<40)-1;
    return ((x>>30)|(x<<10))&msk;
}
 
inline LL norm( LL x ) {
    return min(x,min(rot(x),min(rot(rot(x)),rot(rot(rot(x))))));
}
 
inline int bit( int x, int i ) {
    return (x>>i)&1;
}
 
int n,a[N][4],rc[16];
LL b[N],dp[16];
 
LL solve( int ti, int bi, int bd ) {
    int cc[8];
    REP(i,4) cc[i]=a[ti][i];
    REP(i,4) cc[i+4]=a[bi][(bd-i+4)%4];
 
    LL c[4][4];
    c[0][0]=f(cc[1],cc[0],cc[4],cc[5]);
    c[1][0]=f(cc[2],cc[1],cc[5],cc[6]);
    c[2][0]=f(cc[3],cc[2],cc[6],cc[7]);
    c[3][0]=f(cc[0],cc[3],cc[7],cc[4]);
    REP(i,4) REP(j,3) c[i][j+1]=rot(c[i][j]);
    int lc[4]={1,1,1,1};
    REP(i,4) while ( lc[i]<4 && c[i][lc[i]]!=c[i][0] ) lc[i]++;
    REP(i,4) rc[i]=4/lc[i];
    REP(i,4) sort(c[i],c[i]+lc[i]);
    memset(dp,0,sizeof(dp));
    dp[0]=1;
    REP1(i,ti+1,n) if ( i!=bi ) {
#define F(j,k) if ( !((j>>k)&1) && b[i]==c[k][0] ) dp[j|(1<<k)]+=rc[k]*dp[j]
        F(14,0); F(14,1); F(14,2); F(14,3);
        F(13,0); F(13,1); F(13,2); F(13,3);
        F(12,0); F(12,1); F(12,2); F(12,3);
        F(11,0); F(11,1); F(11,2); F(11,3);
        F(10,0); F(10,1); F(10,2); F(10,3);
        F(9,0); F(9,1); F(9,2); F(9,3);
        F(8,0); F(8,1); F(8,2); F(8,3);
        F(7,0); F(7,1); F(7,2); F(7,3);
        F(6,0); F(6,1); F(6,2); F(6,3);
        F(5,0); F(5,1); F(5,2); F(5,3);
        F(4,0); F(4,1); F(4,2); F(4,3);
        F(3,0); F(3,1); F(3,2); F(3,3);
        F(2,0); F(2,1); F(2,2); F(2,3);
        F(1,0); F(1,1); F(1,2); F(1,3);
        F(0,0); F(0,1); F(0,2); F(0,3);
        // for ( int j=14; j>=0; j-- ) REP(k,4) if ( !bit(j,k) && b[i]==c[k][0] ) {
            // dp[j|(1<<k)]+=rc[k]*dp[j];
        // }
    }
    // dump(ti,bi,bd,vector<LL>(dp,dp+16));
    return dp[15];
}
 
int main() {
    R(n);
    REP1(i,1,n) REP(j,4) R(a[i][j]);
    // n=400;
    REP1(i,1,n) b[i]=norm(f(a[i][0],a[i][1],a[i][2],a[i][3]));
    LL ans=0;
    REP1(i,1,n) REP1(j,i+1,n) REP(k,4) ans+=solve(i,j,k);
    W(ans);
    return 0;
}


Measured memory_bytes: 256