### BUGGY CODE ###

from collections import defaultdict
N, = map(int, input().split())
dd = defaultdict(int)
cc = defaultdict(int)
ss = []
for _ in range(N):
    a, b, c, d = map(int, input().split())
    dd[(a,b,c,d)] += 1
    dd[(b,c,d,a)] += 1
    dd[(c,d,a,b)] += 1
    dd[(d,a,b,c)] += 1
    if a == c and b == d:
        if a == b:
            cc[(a,b,c,d)] = 4
        else:
            cc[(a,b,c,d)] = 2
            cc[(b,c,d,a)] = 2
    else:
        cc[(a,b,c,d)] = 1
        cc[(b,c,d,a)] = 1
        cc[(c,d,a,b)] = 1
        cc[(d,a,b,c)] = 1
    ss.append((a,b,c,d))
def icr(x):
    a, b, c, d = x
    for faf in [(b,c,d,a), (c,d,a,b), (d,a,b,c), (a,b,c,d)]:
        dd[faf] += 1
def dcr(x):
    a, b, c, d = x
    for faf in [(b,c,d,a), (c,d,a,b), (d,a,b,c), (a,b,c,d)]:
        dd[faf] -= 1

def f(a, b, c, d, e, f, g, h):
    e, f, g, h = e, h, g, f
    tl = [(a,e,f,b), (b,f,g,c), (c,g,h,d), (d,h,e,a)]
    r = 1
    coun = 0
    for cp in tl:
        coun += 1
#        if (a,b,c,d) == (1, 1, 1, 1) and (e,f,g,h) == (0,0,0,0):
#        if (a,b,c,d) == (1, 0, 1, 0) and (e,f,g,h) == (1,0,1,0):
#            print(coun, dd, dd[cp])
        #print(coun, dd, dd[cp])
        r *= dd[cp]
        dcr(cp)
    for cp in tl:
        icr(cp)
    #print((a,b,c,d), (e,f,g,h), r)
    return r

r = 0
for i in range(N):
    a,b,c,d = ss[i]
    ff = [a,b,c,d]
    dcr(tuple(ff))
    for j in range(N):
        if i == j:
            continue
        x, y, z, w = ss[j]
        sl = [[x,y,z,w], [y,z,w,x], [z,w,x,y], [w,x,y,z]]
        for s in sl:
            dcr(tuple(s))
            r += f(*(ff+s))
            icr(tuple(s))
    icr(tuple(ff))
print(r//6)


### FIXED CODE ###

from collections import defaultdict
N, = map(int, input().split())

def normal(xs):
    mnx = min(xs)
    xi = xs.index(mnx)
    if xs[(xi+3)%4] == mnx:
        if xs[(xi+2)%4] == mnx:
            xi = (xi+2)%4
        else:
            xi = (xi+3)%4
    if xs[(xi+1)%4] > xs[(xi+3)%4]:
        xi = (xi+2)%4
    return (xs[xi%4], xs[(xi+1)%4], xs[(xi+2)%4], xs[(xi+3)%4])
#x = (0,2,2,0)
#print(normal(x))

dd = defaultdict(int)
ss = []
for _ in range(N):
    a, b, c, d = map(int, input().split())
    x = normal([a,b,c,d])
    n=1
    if x[0] == x[2] and x[1] == x[3]:
        n *= 2
        if x[0] == x[1]:
            n *= 2
    dd[x] += n
    ss.append(x)

def icr(x):
    n = 1
    if x[0] == x[2] and x[1] == x[3]:
        n *= 2
        if x[0] == x[1]:
            n *= 2
    dd[x] += n

def dcr(x):
    n = 1
    if x[0] == x[2] and x[1] == x[3]:
        n *= 2
        if x[0] == x[1]:
            n *= 2
    dd[x] -= n

def f(ff, gg):
    #print(dd)
    a,b,c,d=ff
    e,h,g,f=gg
    tl = list(map(normal, [(a,e,f,b), (b,f,g,c), (c,g,h,d), (d,h,e,a)]))
    r = 1
    for cp in tl:
        if cp not in dd:
            r = 0
            break
        r *= dd[cp]
        dcr(cp)
    for cp in tl:
        if cp not in dd:
            break
        icr(cp)
    return r

r = 0
for i in range(N):
    ff = ss[i]
    dcr(ff)
    for j in range(i+1, N):
        sl = ss[j]
        dcr(sl)
        x, y, z, w = sl
        sls = [(x,y,z,w), (y,z,w,x), (z,w,x,y), (w,x,y,z)]
        for s in sls:
            r += f(ff, s)
        icr(sl)
    icr(ff)
print(r//3)