Buggy python submission (verdict: Time Limit Exceeded):
from fractions import Fraction
n = int(input())
candidate = [sorted(list(input())) for _ in range(n)]
ans = 0
candidate.sort()

# 有理数型をインポート
# 組合せの総数


def comb(n, k):

    if n < 0 or k < 0:
        pdt = 0

    else:
        pdt = 1
        for s in range(1, k + 1):
            pdt *= Fraction(n - s + 1, s)

    # 戻り値をint型にするために分子を取り出す
    return pdt.numerator


cnt = []
num = 1
for i in range(1, n):
    if candidate[i] == candidate[i - 1]:
        num += 1
        if i == n - 1:
            cnt.append(num)
    else:
        cnt.append(num)
        num = 1
for i in cnt:
    ans += comb(i, 2)
print(ans)


Fixed submission:
from fractions import Fraction
import math
n = int(input())
candidate = [sorted(list(input())) for _ in range(n)]
ans = 0
candidate.sort()

# 有理数型をインポート
# 組合せの総数


def combinations_count(n, r):
    return math.factorial(n) // (math.factorial(n - r) * math.factorial(r))
# def comb(n, k):

#     if n < 0 or k < 0:
#         pdt = 0

#     else:
#         pdt = 1
#         for s in range(1, k + 1):
#             pdt *= Fraction(n - s + 1, s)

#     # 戻り値をint型にするために分子を取り出す
#     return pdt.numerator


cnt = []
num = 1
for i in range(1, n):
    if candidate[i] == candidate[i - 1]:
        num += 1
        if i == n - 1 and num > 1:
            cnt.append(num)
    else:
        if num > 1:
            cnt.append(num)
        num = 1
for i in cnt:
    if i > 1:
        ans += combinations_count(i, 2)
print(ans)

Buggy python submission (verdict: Time Limit Exceeded):
from fractions import Fraction
n = int(input())
candidate = [sorted(list(input())) for _ in range(n)]
ans = 0
candidate.sort()

# 有理数型をインポート
# 組合せの総数


def comb(n, k):

    if n < 0 or k < 0:
        pdt = 0

    else:
        pdt = 1
        for s in range(1, k + 1):
            pdt *= Fraction(n - s + 1, s)

    # 戻り値をint型にするために分子を取り出す
    return pdt.numerator


cnt = 1
for i in range(1, n):
    if candidate[i] != candidate[i - 1]:
        ans += comb(cnt, 2)
        cnt = 1
    else:
        cnt += 1
        if i == n - 1:
            ans += comb(cnt, 2)
print(ans)


Fixed submission:
from fractions import Fraction
import math
n = int(input())
candidate = [sorted(list(input())) for _ in range(n)]
ans = 0
candidate.sort()

# 有理数型をインポート
# 組合せの総数


def combinations_count(n, r):
    return math.factorial(n) // (math.factorial(n - r) * math.factorial(r))
# def comb(n, k):

#     if n < 0 or k < 0:
#         pdt = 0

#     else:
#         pdt = 1
#         for s in range(1, k + 1):
#             pdt *= Fraction(n - s + 1, s)

#     # 戻り値をint型にするために分子を取り出す
#     return pdt.numerator


cnt = []
num = 1
for i in range(1, n):
    if candidate[i] == candidate[i - 1]:
        num += 1
        if i == n - 1 and num > 1:
            cnt.append(num)
    else:
        if num > 1:
            cnt.append(num)
        num = 1
for i in cnt:
    if i > 1:
        ans += combinations_count(i, 2)
print(ans)

Buggy python submission (verdict: Time Limit Exceeded):
n = int(input())
candidate = [sorted(list(input())) for _ in range(n)]

ans = 0
for i in range(n - 1):
    for j in range(i + 1, n):
        if str(candidate[i]) == str(candidate[j]):
            ans += 1
print(ans)

Fixed submission:
from fractions import Fraction
import math
n = int(input())
candidate = [sorted(list(input())) for _ in range(n)]
ans = 0
candidate.sort()

# 有理数型をインポート
# 組合せの総数


def combinations_count(n, r):
    return math.factorial(n) // (math.factorial(n - r) * math.factorial(r))
# def comb(n, k):

#     if n < 0 or k < 0:
#         pdt = 0

#     else:
#         pdt = 1
#         for s in range(1, k + 1):
#             pdt *= Fraction(n - s + 1, s)

#     # 戻り値をint型にするために分子を取り出す
#     return pdt.numerator


cnt = []
num = 1
for i in range(1, n):
    if candidate[i] == candidate[i - 1]:
        num += 1
        if i == n - 1 and num > 1:
            cnt.append(num)
    else:
        if num > 1:
            cnt.append(num)
        num = 1
for i in cnt:
    if i > 1:
        ans += combinations_count(i, 2)
print(ans)