#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>

namespace IO {
    template <typename _T>
    inline bool read(_T& x) {
        x = 0;
        _T y = 1;
        char c = getchar();
        while ((c < '0' || '9' < c) && c != EOF) {
            if (c == '-')
                y = -1;
            c = getchar();
        }
        if (c == EOF)
            return false;
        while ('0' <= c && c <= '9')
            x = x * 10 + c - '0', c = getchar();
        x *= y;
        return true;
    }

    template <typename _T>
    inline _T input() {
        _T x = 0, y = 1;
        char c = getchar();
        while ((c < '0' || '9' < c) && c != EOF) {
            if (c == '-')
                y = -1;
            c = getchar();
        }
        if (c == EOF)
            return 0;
        while ('0' <= c && c <= '9')
            x = x * 10 + c - '0', c = getchar();
        x *= y;
        return x;
    }
};  // namespace IO
using namespace IO;

namespace modular {
    const int MOD = 1000000007;

    inline int add(int x, int y) { return (x += y) >= MOD ? x -= MOD : x; }

    inline void inc(int& x, int y) { (x += y) >= MOD ? x -= MOD : 0; }

    inline int mul(int x, int y) { return 1LL * x * y % MOD; }

    inline int qpow(int x, int y) {
        int ans = 1;
        for (; y; y >>= 1, x = mul(x, x))
            if (y & 1)
                ans = mul(ans, x);
        return ans;
    }
};  // namespace modular

#define MAX_N 407
#define reg register
#define FIN(s) freopen(s, "r", stdin)
#define FOUT(s) freopen(s, "w", stdout)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define rep(i, l, r) for (int i = l; i <= r; ++i)
#define lep(i, l, r) for (int i = l; i < r; ++i)
#define irep(i, r, l) for (int i = r; i >= l; --i)
#define ilep(i, r, l) for (int i = r; i > l; --i)
typedef long long ll;

int N;

struct node {
    int c[4];
    inline node nxt() {
        node a;
        lep(i, 0, 4) a.c[i] = c[(i + 1) & 3];
        return a;
    }
    bool operator<(const node& rhs) const {
        lep(i, 0, 4) if (c[i] != rhs.c[i]) return c[i] < rhs.c[i];
        return false;
    }
} a[MAX_N];
std::map<node, ll> mp;

inline void insert(node x, ll val) {
    for (int i = 0; i < 4; ++i, x = x.nxt())
        mp[x] += val;
}

inline void solve() {
    ll res = 0;
    rep(i, 1, N) {
        insert(a[i], -1);
        rep(j, i + 1, N) {
            insert(a[j], -1);
            lep(k, 0, 4) {
                node x1 = node{a[j].c[1], a[j].c[0], a[i].c[1], a[i].c[0]};
                node x2 = node{a[j].c[2], a[j].c[1], a[i].c[0], a[i].c[3]};
                node x3 = node{a[j].c[3], a[j].c[2], a[i].c[3], a[i].c[2]};
                node x4 = node{a[j].c[0], a[j].c[3], a[i].c[2], a[i].c[1]};
                // rep(i, 0, 0) x1 = x1.nxt(), x2 = x2.nxt(), x3 = x3.nxt(),
                //              x4 = x4.nxt();
                a[j] = a[j].nxt();
                if (!mp[x1] || !mp[x2] || !mp[x3] || !mp[x4])
                    continue;
                ll ans = 1;
                ans *= mp[x1], insert(x1, -1);
                ans *= mp[x2], insert(x2, -1);
                ans *= mp[x3], insert(x3, -1);
                ans *= mp[x4];
                res += ans;
                insert(x1, 1), insert(x2, 1), insert(x3, 1);
            }
            insert(a[j], 1);
        }
    }
    printf("%lld\n", res);
}

int main() {
#ifdef LOCAL
    FIN("in");
#endif
    read(N);
    rep(i, 1, N) {
        rep(j, 0, 3) read(a[i].c[j]);
        insert(a[i], 1);
    }
    solve();
    return 0;
}

Measured memory_bytes: 20352