#include <bits/stdc++.h>
using namespace std;

#define ff first
#define ss second
#define pb push_back
#define pf push_front
#define ppb pop_back()
#define ppf pop_front()
#define all(vec) vec.begin(), vec.end()
#define fol(i,a,b) for(int i=a;i<b;i++)
#define loop(i,a,b) for(int i=a;i>=b;i--)
#define forr(x,arr) for(auto& x:arr)
#define mod 1000000007
#define INF 0x3f3f3f3f3f3f3f3f
#define EPS 1e-7
#define sz(x) ((lli)(x).size())

using   lli     =   long long;
using   lld     =   long double;
using   ulli    =   unsigned long long int;
using   pll     =   pair<lli, lli>;
using   ttt     =   pair<lli, pll>;
using   vttt    =   vector<ttt>;
using   vll     =   vector<pll>;
using   vl      =   vector<lli>;
using   vi      =   vector<int>;
using   vvi     =   vector<vector<int>>;
using   cd      =   complex<lld>;
const double PI = acos(-1);

#ifdef tejasp
#include "library/debugger.cpp"
#else
#define trace(...) {}
#define cotra(...) {}
#define end_routine() {}
#define localsys 0
#define endl '\n'
#endif

#define ca cord.first.first
#define cb cord.first.second
#define cc cord.second.first
#define cd cord.second.second

struct node
{
    pair<pll,pll> cord;
    node() = default;
    node(int a, int b, int c, int d): cord({{a,b},{c,d}}) {};
    bool operator== (node &other) { return cord==other.cord; }
    void operator= (const node &other) { cord=other.cord; }
};

bool operator< (const node &l, const node &r) { return l.cord<r.cord; }
bool operator> (const node &l, const node &r) { return l.cord>r.cord; }

node arr[410];
lli ans=0;
map<node,lli> mp;

void rotate(node &cur)
{
    lli temp=cur.ca;
    cur.ca=cur.cb;
    cur.cb=cur.cc;
    cur.cc=cur.cd;
    cur.cd=temp;
}

int calc(node &a, node &b)
{
    int ans=0;
    fol(i,0,4)
    {
        if(a==b) ans++;
        rotate(b);
    }
    return ans;
}

node reverse(node n)
{
    swap(n.cb,n.cd);
    return n;
}

void upd(node &l1, node &r1)
{
    node lef=reverse(l1), rig=r1;
    node uu(lef.ca,lef.cb,rig.cb,rig.ca);
    node dd(lef.cb,lef.cc,rig.cc,rig.cb);
    node ll(lef.cc,lef.cd,rig.cd,rig.cc);
    node rr(lef.cd,lef.ca,rig.ca,rig.cd);
    lli res1=mp[uu];
    lli res2=mp[dd];
    lli res3=mp[ll];
    lli res4=mp[rr];
    res1-=calc(uu,l1)+calc(uu,r1);
    res2-=calc(dd,l1)+calc(dd,r1)+calc(dd,uu);
    res3-=calc(ll,l1)+calc(ll,r1)+calc(ll,uu)+calc(ll,dd);
    res4-=calc(rr,l1)+calc(rr,r1)+calc(rr,uu)+calc(rr,dd)+calc(rr,ll);
    ans+=(res1*res2*res3*res4);
}

int tejas_919(int kkkk)
{
    lli n, m, k, q, u, v, temp=0;
    cin>>n;
    fol(i,0,n)
    {
        cin>>m>>k>>u>>v;
        arr[i]=node(m,k,u,v);
        fol(j,0,4)
        {
            mp[arr[i]]++;
            rotate(arr[i]);
        }
    }
    fol(i,0,n)
    {
        fol(j,i+1,n)
        {
            fol(k,0,4)
            {
                upd(arr[i],arr[j]);
                rotate(arr[j]);
            }
        }
    }
    ans/=3;
    cout<<ans<<endl;
    return 0;
}

signed main()
{
    #ifdef tejasp
            freopen("input.txt", "rt", stdin);
            freopen("output.txt", "wt", stdout);
    #endif
    if(!localsys) { ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL); }
    cout << fixed << setprecision(10);
    int t=1;
    //cin>>t;
    fol(i,0,t) { tejas_919(i+1); }
    end_routine();
    if(localsys) system("pause");
}

Measured memory_bytes: 100096