Buggy python submission (verdict: Time Limit Exceeded):
from collections import Counter

from operator import mul
from functools import reduce

def cmb(n,r):
    r = min(n-r,r)
    if r == 0: return 1
    over = reduce(mul, range(n, n - r, -1))
    under = reduce(mul, range(1,r + 1))
    return over // under


N = int(input())
matched = [False] * N
s = [None] * N
for i in range(N):
    s[i] = input()



ans = 0
i = 0
j = 1
cnt = 0
while i < N:
    cnt = 0

    if matched[i] == True:
        if i >= N-1:
            break
        
        i += 1
        j = i+1
        continue

    si = Counter(s[i])
    while j <= N-1:

        if matched[j] == True:
            j += 1

            continue


        sj = Counter(s[j])
        if si == sj:
            matched[i] = True
            matched[j] = True
            cnt += 1
        j += 1
    
    if cnt != 0:
        ans += cmb(cnt+1,2)

    if i == N-2:
        break

    i += 1
    j = i+1
    
print(ans)



Fixed submission:
from collections import Counter

from operator import mul
from functools import reduce

def cmb(n,r):
    r = min(n-r,r)
    if r == 0: return 1
    over = reduce(mul, range(n, n - r, -1))
    under = reduce(mul, range(1,r + 1))
    return over // under


N = int(input())
matched = [False] * N
s = [None] * N
for i in range(N):
    moji = list(input())
    moji.sort()
    tmp = "".join(moji)
    s[i]= tmp

s.sort()
#print(s)
ans = 0
i = 0
j = 1
while i < N-1:
    cnt = 0
    #print("ss",i,j)
    if j == N:
        break
    while j <= N-1:
        #print("aa",i,j)
        if s[i] == s[j]:
            cnt += 1
            j += 1
            continue
        else:

            i = j
            j = i+1
            break
    if cnt >= 1:
        ans += cmb(cnt+1,2)
    

print(ans)

Buggy python submission (verdict: Time Limit Exceeded):
from collections import Counter

def cmb(n, r):
    if n - r < r: r = n - r
    if r == 0: return 1
    if r == 1: return n

    numerator = [n - r + k + 1 for k in range(r)]
    denominator = [k + 1 for k in range(r)]

    for p in range(2,r+1):
        pivot = denominator[p - 1]
        if pivot > 1:
            offset = (n - r) % p
            for k in range(p-1,r,p):
                numerator[k - offset] /= pivot
                denominator[k] /= pivot

    result = 1
    for k in range(r):
        if numerator[k] > 1:
            result *= int(numerator[k])

    return result

N = int(input())
matched = [False] * N
s = [None] * N
for i in range(N):
    s[i] = input()



ans = 0
i = 0
j = 1
cnt = 0
while i < N:
    cnt = 0

    if matched[i] == True:
        if i >= N-1:
            break
        
        i += 1
        j = i+1
        continue

    si = Counter(s[i])
    while j <= N-1:

        if matched[j] == True:
            j += 1

            continue


        sj = Counter(s[j])
        if si == sj:
            matched[i] = True
            matched[j] = True
            cnt += 1
        j += 1
    
    if cnt != 0:
        ans += cmb(cnt+1,2)

    if i == N-2:
        break

    i += 1
    j = i+1
    
print(ans)



Fixed submission:
from collections import Counter

from operator import mul
from functools import reduce

def cmb(n,r):
    r = min(n-r,r)
    if r == 0: return 1
    over = reduce(mul, range(n, n - r, -1))
    under = reduce(mul, range(1,r + 1))
    return over // under


N = int(input())
matched = [False] * N
s = [None] * N
for i in range(N):
    moji = list(input())
    moji.sort()
    tmp = "".join(moji)
    s[i]= tmp

s.sort()
#print(s)
ans = 0
i = 0
j = 1
while i < N-1:
    cnt = 0
    #print("ss",i,j)
    if j == N:
        break
    while j <= N-1:
        #print("aa",i,j)
        if s[i] == s[j]:
            cnt += 1
            j += 1
            continue
        else:

            i = j
            j = i+1
            break
    if cnt >= 1:
        ans += cmb(cnt+1,2)
    

print(ans)

Buggy python submission (verdict: Time Limit Exceeded):
from collections import Counter

def cmb(n, r):
    if n - r < r: r = n - r
    if r == 0: return 1
    if r == 1: return n

    numerator = [n - r + k + 1 for k in range(r)]
    denominator = [k + 1 for k in range(r)]

    for p in range(2,r+1):
        pivot = denominator[p - 1]
        if pivot > 1:
            offset = (n - r) % p
            for k in range(p-1,r,p):
                numerator[k - offset] /= pivot
                denominator[k] /= pivot

    result = 1
    for k in range(r):
        if numerator[k] > 1:
            result *= int(numerator[k])

    return result

N = int(input())
matched = [False] * N
s = [None] * N
for i in range(N):
    s[i] = input()



ans = 0
i = 0
j = 1
cnt = 0
while i < N:
    cnt = 0

    if matched[i] == True:
        if i >= N-1:
            break
        
        i += 1
        j = i+1
        continue

    si = Counter(s[i])
    while j <= N-1:

        if matched[j] == True:
            j += 1

            continue


        sj = Counter(s[j])
        if si == sj:
            matched[i] = True
            matched[j] = True
            cnt += 1
        j += 1
    
    if cnt != 0:
        ans += cmb(cnt+1,2)

    if i == N-2:
        break

    i += 1
    j = i+1
    
print(ans)



Fixed submission:
from collections import Counter

from operator import mul
from functools import reduce

def cmb(n,r):
    r = min(n-r,r)
    if r == 0: return 1
    over = reduce(mul, range(n, n - r, -1))
    under = reduce(mul, range(1,r + 1))
    return over // under


N = int(input())
matched = [False] * N
s = [None] * N
for i in range(N):
    moji = list(input())
    moji.sort()
    tmp = "".join(moji)
    s[i]= tmp

s.sort()
#print(s)
ans = 0
i = 0
j = 1
while i < N-1:
    cnt = 0
    #print("ss",i,j)
    if j == N:
        break
    while j <= N-1:
        #print("aa",i,j)
        if s[i] == s[j]:
            cnt += 1
            j += 1
            continue
        else:

            i = j
            j = i+1
            break
    if cnt >= 1:
        ans += cmb(cnt+1,2)
    

print(ans)