Problem:
 Score : 300 points    Problem Statement We will call a string obtained by arranging the characters contained in a string a in some order, an anagram of a .  For example, greenbin is an anagram of beginner . As seen here, when the same character occurs multiple times, that character must be used that number of times.  Given are N strings s_1, s_2, \ldots, s_N . Each of these strings has a length of 10 and consists of lowercase English characters. Additionally, all of these strings are distinct. Find the number of pairs of integers i, j  (1 \leq i < j \leq N) such that s_i is an anagram of s_j .      Constraints  2 \leq N \leq 10^5  s_i is a string of length 10 .  Each character in s_i is a lowercase English letter.  s_1, s_2, \ldots, s_N are all distinct.         Input Input is given from Standard Input in the following format:  N  s_1  s_2  :  s_N       Output Print the number of pairs of integers i, j  (1 \leq i < j \leq N) such that s_i is an anagram of s_j .        Sample Input 1 3
acornistnt
peanutbomb
constraint      Sample Output 1 1  s_1 =  acornistnt is an anagram of s_3 =  constraint . There are no other pairs i, j such that s_i is an anagram of s_j , so the answer is 1 .       Sample Input 2 2
oneplustwo
ninemodsix      Sample Output 2 0  If there is no pair i, j such that s_i is an anagram of s_j , print 0 .       Sample Input 3 5
abaaaaaaaa
oneplustwo
aaaaaaaaba
twoplusone
aaaabaaaaa      Sample Output 3 4  Note that the answer may not fit into a 32 -bit integer type, though we cannot put such a case here.

Solution (Python):

import bisect
import heapq
import math
import random
import sys
from collections import Counter, defaultdict, deque
from decimal import ROUND_CEILING, ROUND_HALF_UP, Decimal
from functools import lru_cache, reduce
from itertools import combinations, combinations_with_replacement, product, permutations
from operator import add, mul, sub

sys.setrecursionlimit(100000)
input = sys.stdin.readline


def read_int():
    return int(input())


def read_int_n():
    return list(map(int, input().split()))


def read_float():
    return float(input())


def read_float_n():
    return list(map(float, input().split()))


def read_str():
    return input().strip()


def read_str_n():
    return list(map(str, input().split()))


def error_print(*args):
    print(*args, file=sys.stderr)


def mt(f):
    import time

    def wrap(*args, **kwargs):
        s = time.time()
        ret = f(*args, **kwargs)
        e = time.time()

        error_print(e - s, 'sec')
        return ret

    return wrap


@mt
def slv(N, S):
    c = []
    d = Counter()
    for s in S:
        c = Counter(s)
        h = []
        for k in sorted(c.keys()):
            h.append(k + str(c[k]))
        d[''.join(h)] += 1

    ans = 0
    for v in d.values():
        if v ==1:
            pass
        else:
            ans += (v*(v-1))//2
    return ans


def main():
    N = read_int()
    S = [read_str() for _ in range(N)]
    print(slv(N, S))


if __name__ == '__main__':
    main()

Solution (Python):
from collections import defaultdict
N = int(input())
d = defaultdict(int)

for i in range(N):
    s = ''.join(sorted(input()))
    d[s] += 1

ans = 0
for c in d.values():
    if c >= 2:
        ans += c*(c-1)//2

print(ans)

Solution (Python):
from collections import Counter, defaultdict
import sys
sys.setrecursionlimit(10 ** 5 + 10)

from math import factorial
import heapq, bisect


from math import factorial

def combinations_count(n, r):
    return factorial(n) // (factorial(n - r) * factorial(r))

def main():
    num = int(input())
    data = [input() for i in range(num)]
    for i in range(num):
        data[i] = list(data[i])
        data[i].sort()
        data[i] = ''.join(data[i])
    data.sort()

    kari = 1
    pre = ''
    ans = 0
    
    for i in range(num):
        if pre == data[i]:
            kari += 1
        else:
            if kari > 1:
                ans += combinations_count(kari, 2)
            kari = 1
            pre = data[i]

    if kari > 1:
        ans += combinations_count(kari, 2)
    print(ans)




if __name__ == '__main__':
    main()

Solution (Python):
n = int(input())
strs = sorted([''.join(sorted(input().strip())) for _ in range(n)])

i, j = 0, 1
lcnt = 1
res = 0
while j < n:
    if strs[i] == strs[j]:
        lcnt += 1
        j += 1
    else:
        res += lcnt * (lcnt - 1) // 2
        i = j
        j = i + 1
        lcnt = 1
res += lcnt * (lcnt - 1) // 2

print(res)

Solution (Python):


import sys
from collections import Counter

def input(): return sys.stdin.readline().strip()
def list2d(a, b, c): return [[c] * b for i in range(a)]
def list3d(a, b, c, d): return [[[d] * c for j in range(b)] for i in range(a)]
def ceil(x, y=1): return int(-(-x // y))
def INT(): return int(input())
def MAP(): return map(int, input().split())
def LIST(): return list(map(int, input().split()))
def Yes(): print('Yes')
def No(): print('No')
def YES(): print('YES')
def NO(): print('NO')
sys.setrecursionlimit(10 ** 9)
INF = float('inf')
MOD = 10 ** 9 + 7

N = INT()
A = Counter()
for i in range(N):
    A[''.join(sorted(input()))] += 1

ans = 0
for k, v in A.items():
    ans += v*(v-1) // 2
print(ans)

Solution (Python):
import sys
input = sys.stdin.readline
sys.setrecursionlimit(100000)

def getN():
    return int(input())
def getList():
    return list(map(int, input().split()))
import math
from collections import defaultdict

n = getN()
dc = defaultdict(int)
for i in range(n):
    s = input().strip()
    dc["".join(sorted(list(s)))] += 1

ans = 0
for v in list(dc.values()):
    ans += (v * (v - 1)) // 2

print(ans)

Solution (Python):
from collections import defaultdict
N = int(input())
S = [input() for _ in range(N)]
L = defaultdict(list)
for i, s in enumerate(S):
    s = "".join(sorted(s))
    L[s].append(i)
num = 0
for x in L.values():
    num += sum(range(len(x)))
print(num)

Solution (Python):
import sys
input = sys.stdin.readline

def main():
    N = int( input())
    S = [ list(input()) for _ in range(N)]
    for i in range(N):
        S[i] = "".join(sorted(S[i][:10]))
    S.sort()
    cnt = 1
    ans = 0
    now = S[0]
    for i in range(1, N):
        if now == S[i]:
            cnt += 1
            continue
        ans += cnt*(cnt-1)//2
        cnt = 1
        now = S[i]
    ans += cnt*(cnt-1)//2
    print(ans)
    
if __name__ == '__main__':
    main()

Solution (Python):

import sys
import collections


def solve(N: int, S: "List[str]"):

    dic = collections.defaultdict(int)
    for s in S:
        s = "".join(sorted(s))
        dic[s] += 1

    res = 0
    for k,v in dic.items():
        if v > 1:
            res += v*(v-1)/2

    print(int(res))




def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    N = int(next(tokens))  
    s = [ next(tokens) for _ in range(N) ]  
    solve(N, s)

if __name__ == '__main__':
    main()

Solution (Python):
N = int(input())

S = []
for i in range(N):
    string = input()
    string = list(string)
    string.sort()
    string = ''.join(string)
    S.append(string)

S.sort()

ans = 0
cnt = 1
for i in range(1, N):
    if S[i] == S[i-1]:
        cnt += 1
    else:
        ans += cnt*(cnt-1) // 2
        cnt = 1

ans += cnt*(cnt-1) // 2
print(ans)

Solution (Python):
import sys
from collections import defaultdict

import numpy as np

n = int(input())
appeared = defaultdict(lambda: 0)
ans = 0
for s in sys.stdin:
    p = tuple(np.bincount([ord(c) - 97 for c in s.strip()], minlength=26))
    ans += appeared[p]
    appeared[p] += 1
print(ans)

Solution (Python):
N = int(input())
char_map = {}
answer = 0
for i in range(N):
    s = "".join(sorted(input()))
    if(s in char_map):
        answer += char_map[s]
        char_map[s] += 1
    else:
        char_map[s] = 1
print(answer)

Solution (Python):


from itertools import accumulate
from bisect import bisect, bisect_left
from collections import Counter, deque
from functools import reduce
from itertools import accumulate
from operator import itemgetter, xor
from string import ascii_lowercase as abc

from sys import setrecursionlimit
setrecursionlimit(10**9)
 
import sys

from collections import Counter
def inpl(): return list(map(int, input().split()))

N = int(input())
C = Counter()

for i in range(N):
    S = Counter(input())
    K = [0]*26
    for i in range(26):
        K[i] = S[abc[i]]
    C[tuple(K)] += 1

def cal(x):
    return x*(x-1)//2

ans = 0
for v in C.values():
    ans += cal(v)

print(ans)

Solution (Python):
n=int(input())
dic={}
for i in range(n):
    s=input()
    l=[]
    for a in s:
        l.append(a)
    l.sort()
    s="".join(l)
    if s in dic:
        dic[s]+=1
    else:
        dic[s]=1
total=0
for f in dic:
    total+=int((dic[f]*(dic[f]-1))/2)
print(total)

Solution (Python):
n = int(input())
can = []
for i in range(n):
  raw = input()
  now = []
  for j in range(len(raw)):
    now.append(raw[j])
  now.sort()
  can.append(now)
can.sort()
cnt = 0
ans = 0
for i in range(1,n):
  if can[i-1] == can[i]:
    cnt += 1
    ans += cnt
  else:
    cnt = 0
print(ans)

Solution (Python):
from collections import defaultdict

N = int(input())
words = defaultdict(int)
for i in range(N):
    s = list(input())
    s.sort()
    words[''.join(s)] += 1

ans = 0
for n in words.values():
    if n == 1:
        continue
    ans += n * (n - 1) // 2
print(ans)

Solution (Python):
import collections
from functools import reduce
from operator import mul

N = int(input())
Hs = []


def cmb(n, r):
    try:
        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
    except:
        return 0


for line in range(N):
    l = list(input())
    l.sort()
    Hs.append(','.join(l).replace(',', ''))

c = collections.Counter(Hs)

su = 0
for v in c.values():
    su += cmb(v, 2)

print(su)

Solution (Python):
def decoder(s):
    ret = [0] * 26
    for c in s:
        ret[ord(c) - ord('a')] += 1
    return str(ret)
n = int(input())
dic = {}
for _ in range(n):
    s = input()
    count = decoder(s)
    if count in dic:
        dic[count] += 1
    else:
        dic[count] = 1
ans = 0
for i, c in dic.items():
    ans += c * (c-1) // 2
print(ans)

Solution (Python):
from collections import defaultdict, deque
import sys
import math

sys.setrecursionlimit(100000)

MIN = -10 ** 9
MAX = 10 ** 9 + 7


def main():
    N = int(input())
    
    s = sorted([
        "".join(sorted(input()))
        for _ in range(N)
    ])

    c = 0
    last = ""
    res = 0
    for si in s:
        if last == si:
            c += 1
            continue
        else:
            last = si
            res += (c + 1) * c // 2
            c = 0
            continue

    res += c * (c + 1) // 2
    print(res)

    


if __name__ == '__main__':
    main()

Solution (Python):
import itertools
N = int(input())
s = []
def str_sort(x, s = False):
    y = sorted(x, reverse = s)
    return ''.join(y)

for i in range(N):
    si = str_sort(input())
    s.append(si)
s.sort()

ans = 0
gr = itertools.groupby(s)
for key, group in gr:
    n = len(list(group))

    ans += n*(n-1)//2

print(ans)

Solution (Python):
import math

def cc(n, r):
    return math.factorial(n) // (math.factorial(n - r) * math.factorial(r))



N = int(input())

dic = {}

for i in range(N):

    s = input()

    slis = list(s)
    slis.sort()

    strs = "".join(slis)

    if strs not in dic:
        dic[strs] = 1
    else:
        dic[strs] += 1


ans = 0

for i in dic:

    if dic[i] >= 2:
        ans += cc(dic[i],2)

print (ans)

Solution (Python):
import sys, math
from collections import deque
from collections import Counter

readline = sys.stdin.readline

N = int(readline())
S = [readline().rstrip() for i in range(N)]

S = [''.join(sorted(s)) for s in S]

c = Counter(S)

count = 0
for x in c.values():
    count += x * (x - 1) // 2

print(count)

Solution (Python):

from collections import defaultdict, deque
import math
from math import factorial
import fractions
import re
import bisect

BIGNUM = 10 ** 9 + 7

def main():
    
    N = int(input())
    

    Ss = []
    for i in range(N):
        Ss.append(input().strip())

    counter = defaultdict(int)
    for s in Ss:
        key = "".join(sorted(s))
        counter[key] += 1

    count = 0
    for key in counter:
        num = counter[key]
        if num > 1:
            count += int(num * (num - 1) / 2)

    print(count)

if __name__ == '__main__':
    main()

Solution (Python):




 
from collections import* 
from fractions import gcd
from functools import* 
from itertools import* 
from operator import mul,itemgetter
from bisect import* 
from heapq import* 
from math import factorial,pi
from copy import deepcopy
import sys
sys.setrecursionlimit(10**8)


from math import factorial
def cmb(n, r):
    return factorial(n) // factorial(r) // factorial(n - r)


def main():
    n=int(input())
    l=[cmb(i,2) for i in Counter(["".join(sorted(input()))for i in range(n)]).values() if i>1]
    print(sum(l))
                    
        
if __name__ == '__main__':
    main()

Solution (Python):









import sys
inf = float("inf")





mod,MOD=1000000007,998244353










def get_array(): return list(map(int , sys.stdin.readline().strip().split()))
def get_ints(): return map(int, sys.stdin.readline().strip().split())
def input(): return sys.stdin.readline().strip()

n=int(input())
mydict=dict()
for i in range(n):
    string=list(input())
    string.sort()
    string=''.join(string)
    if string not in mydict:
        mydict[string]=1
    else:
        mydict[string]+=1
total=0
for i in mydict:
    total+=((mydict[i])*(mydict[i]-1))//2
print(total)

Solution (Python):
from functools import reduce
N = int(input())
s_list = [input() for i in range(N)]

s_list = [ sorted(s) for s in s_list]
s_list = [ reduce(lambda x, y: x+y, s) for s in s_list]

s_map = {}
for s in s_list:
    if s in s_map:
        s_map[s] += 1
    else:
        s_map[s] = 1

ans = 0
for k, v in s_map.items():
    if v > 1:
        ans += v*(v-1)/2
print(int(ans))

Solution (Python):
D = {}
N = int(input())
for n in range(N):
    S = list(input())
    S.sort()
    T = tuple(S)
    D[T] = D.setdefault(T, 0) + 1

res = 0
for v in D.values():
    res += v * (v - 1) // 2

print(res)

Solution (Python):
n=int(input())
S = [input() for i in range(n)]

al_nu = lambda c: ord(c) - ord('A')
S2 = [[] for i in range(n)]
for i in range(n):
    for j in range(10):
        S2[i].append(al_nu(S[i][j]))
for i in range(n):
    S2[i] = sorted(S2[i])

S2.sort()


ans = 0
co = 0
for i in range(n-1):
    if S2[i] == S2[i+1]:
        co += 1
        
    else:
        ans += co*(co+1)/2
        co = 0
ans += co*(co+1)/2
print(int(ans))

Solution (Python):
N = int(input())
D = dict([])
ans = 0
for k in range(N):
    s = sorted([str(x) for x in input()])
    a = ""
    for e in s:
        a += e
    if a in D:
        ans += D[a]
        D[a] += 1
    else:
        D[a] = 1
print(ans)

Solution (Python):
n = int(input())

d = {}


class mod_comb_perm:
    def __init__(self,n,mod):
        self.mod = mod
        self.fact = [1 for i in range(n)]
        for i in range(2,n+1):
            self.fact[i-1] = (self.fact[i-2]*i)%mod

    def expo(self,x,n):
        if n == 2:
            return (x * x) % self.mod
        elif n % 2 == 1:
            return (self.expo(x, n - 1) * x) % self.mod
        else:
            temp = self.expo(x, n // 2) % self.mod
            return (temp * temp) % self.mod
    def comb(self,n,k):
        a = (self.fact[n]*self.expo(self.fact[k],self.mod-2))%self.mod
        return (a*self.expo(self.fact[n-k],self.mod-2))%self.mod
    def invm(self,x):
        return (self.expo(self.fact[x],self.mod-2))%self.mod
    def perm(self,n,k):
        return (self.fact[n]*self.expo(self.fact[n-k],self.mod-2))%self.mod



d = {}
for i in range(n):
    temp = [0 for i in range(26)]
    s = input()
    for c in s:
        t = ord(c)-97
        temp[t]+=1
    for i in range(26):
        temp[i] = str(temp[i])
    txt = ",".join(temp)
    if txt not in d:
        d[txt] = 1
    else:
        d[txt] += 1
ans = 0

for k in d:
    if d[k] != 1:
        ans += d[k]*(d[k]-1)/2
print(int(ans))

Solution (Python):
n=int(input())
s=[]
for i in range(n):
    p=input()
    l=list(p)
    l.sort()
    p="".join(l)
    s.append(p)
s.sort()
q=""
ans=0
qq=1
for i in range(n):
    if i!=n-1:
        if q==s[i]:
            qq+=1
        else:
            q=s[i]
            ans+=qq*(qq-1)//2
            qq=1
    else:
        if q==s[i]:
            qq+=1
        ans+=qq*(qq-1)//2
print(ans)

Solution (Python):
import math
from collections import Counter

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

N = int(input())
counter = Counter([''.join(sorted(input())) for i in range(N)])
ans = 0
for k, v in counter.items():
    if v == 1:
        continue
    ans += combinations_count(v, 2)
print(ans)

Solution (Python):
from collections import Counter

N = int(input().strip())

counter = Counter()

for i in range(N):
  s = input().strip()
  counter[''.join(sorted(s))] += 1

total = 0
for k, v in counter.items():
  total += v * (v - 1) // 2

print(total)

Solution (Python):
N = int(input())
s_list = [input() for _ in range(N)]
from collections import defaultdict
def combination(n, r):
    """
    :param n: the count of different items
    :param r: the number of select
    :return: combination
    n! / (r! * (n - r)!)
    """
    r = min(n - r, r)
    result = 1
    for i in range(n, n - r, -1):
        result *= i
    for i in range(1, r + 1):
        result //= i
    return result

di = defaultdict(int)
for S in s_list:

    tmp = defaultdict(int)
    for s in S:
        tmp[s] += 1
    T = ""
    tmp = sorted(tmp.items())
    for t, t2 in tmp:
        T += t+ str(t2)
    di[T] += 1
ans = 0
for k, v in di.items():
    if v > 1:
        ans += combination(v, 2)
print(ans)

Solution (Python):
n = int(input())
sn = sorted([''.join(sorted(input())) for _ in range(n)])

ans = 0
cnt = 1
for i in range(n-1):
    
    if sn[i] == sn[i+1]:
        cnt += 1
    else:
        ans += cnt * (cnt -1) //2
        cnt = 1
ans += cnt * (cnt -1) //2
print(ans)

Solution (Python):
N = int(input())

s_list = []
for i in range(N):
	s_list.append(input().strip())

ss_list = sorted(["".join(sorted(s)) for s in s_list])

total = 0
count = 1
start = 0
prev = None
for i in range(N):
	s = ss_list[i]
	if prev == s:
		count += 1
	else:
		if count > 1:
			total += count * (count - 1) // 2
		count = 1
	prev = s

if count > 1:
	total += count * (count - 1) // 2

print(total)

Solution (Python):
import sys
input = sys.stdin.readline
import collections
n=int(input())
S=[]
append=S.append
for i in range(n):
  s=input()
  ss=0
  for j in range(10):
    ss+=11**(ord(s[j])-97)
  append(ss)
SS=collections.Counter(S).values()
ans=0
for ss in SS:
  if ss>1:
    ans+=(ss-1)*ss//2
print(ans)

Solution (Python):
n=int(input())
d={}

for i in range(n):
    w=list(input())
    w.sort()
    s="".join(w)
    if s in d:
        d[s]+=1
    else:
        d[s]=1
ans=0
for i in d:
    ans+=d[i]*(d[i]-1)//2
print(ans)

Solution (Python):

from collections import defaultdict
from collections import deque
from heapq import heappush, heappop
from functools import reduce
import sys
import math
import bisect
import random
def I(): return int(sys.stdin.readline())
def F(): return float(sys.stdin.readline())
def S(): return input()
def LI(): return list(map(int, sys.stdin.readline().split()))
def LI_(): return [int(x)-1 for x in sys.stdin.readline().split()]
def LF(): return list(map(float, sys.stdin.readline().split()))
def LS():return sys.stdin.readline().split()
def SR(n): return [sys.stdin.readline()[:-1] for i in range(n)]
def IR(n): return [int(sys.stdin.readline()) for i in range(n)]
def LIR(n): return [list(map(int, sys.stdin.readline().split())) for i in range(n)]
def LSR(n): return [list(map(list, sys.stdin.readline().split())) for i in range(n)]
_gcd = lambda x, y: _gcd(y, x%y) if (x%y) else y
_lcm = lambda x, y: x*y // _gcd(x, y)
def gcd(*numbers):
    return reduce(_gcd, numbers)
def lcm(*numbers):
    return reduce(_lcm, numbers)
sys.setrecursionlimit(1000000)
INF = float('inf')
mod = 1000000007
dire4 = [(1,0), (0,1), (-1,0), (0,-1)]
dire8 = [(1, 0), (1, 1), (0, 1), (-1, 1), (-1, 0), (-1, -1), (0, -1), (1, -1)]

d = defaultdict(int)

N = I()
S = SR(N)

for s in S:
    d[str(sorted(s))] += 1

ans = 0
for key in d.keys():
    value = d[key]
    if value >= 2 :
        ans += value*(value-1)//2
    
print(ans)

Solution (Python):
N = int(input())

def hash(S) :
    ret = 0
    for s in S :
        ret *= 26
        ret += ord(s)-97
    return ret
        
s = [hash(sorted(input())) for _ in range(N)]

s.sort()
s.append(-1)

count = 1
ret = 0
for i in range(1, N+1) :
    if s[i] == s[i-1] :
        count += 1
    else :
        if count >= 2 :
            ret += count * (count-1) // 2
        count = 1
        
print(ret)

Solution (Python):
N = int(input())
s = list(list(input()) for i in range(N))
for i in range(N):
    s[i].sort()
s.sort()
ans = 0
same = 1
for i in range(1,N):
    if s[i] == s[i-1]:
        ans += same
        same += 1
    else:
        same = 1
print(ans)

Solution (Python):

from collections import defaultdict
N=int(input())
d=defaultdict(lambda: 0)
for _ in range(N):
    s="".join(sorted(list(input())))
    d[s]+=1
ans=0
for _, num in d.items():
    ans+=(num*(num-1))
print(ans//2)

Solution (Python):
import math
def comb(n, r):
    return math.factorial(n) // (math.factorial(n - r) * math.factorial(r))
n = int(input())
index=0
hashMap={}
while index < n:
    listS = list(input())
    listS.sort()
    key = "".join(listS)
    if key in hashMap:
        hashMap[key]+=1
    else:
        hashMap[key]=1
    index+=1
answer = 0
for key in hashMap:
    if hashMap[key] > 1:
        answer+=comb(hashMap[key], 2)
print(answer)

Solution (Python):
N = int(input())
S = []
for i in range(N):
    s = ''.join(sorted(input()))
    S.append(s)

from collections import Counter
c = Counter()
for s in S:
    c[s] += 1

ans = 0

def h(n):
    return (n * (n - 1))//2
for k,v in c.items():
    ans += h(v)

print(ans)

Solution (Python):
N = int(input())
S = [0] * N
from collections import Counter
counter = Counter()
for i in range(N):
    k = "".join(sorted(input().strip()))
    counter[k] += 1


answer = 0
for k, c in counter.items():
    f = 1
    if c == 1:
        continue
    answer += (c * (c-1)) // 2
print(answer)

Solution (Python):
N = int(input())
S = [input() for _ in range(N)]
S_ = [''.join(sorted(list(s))) for s in S]

from collections import Counter
c = Counter(S_)

ans = 0
for k,v in c.items():
  
  ans += v*(v-1)//2

  
print(ans)

Solution (Python):
n = int(input())
d = {}
for i in range(n):
    a = list(input())
    a.sort()
    a = str(a)
    if a in d:
        d[a] += 1
    else:
        d[a] = 1
ans = 0
for i in d:
    ans += d[i]*(d[i]-1)//2
print(ans)

Solution (Python):
N=int(input())
S=[input() for i in range(N)]
from collections import defaultdict
d=defaultdict(int)
for s in S:
    s=''.join(sorted([c for c in s]))
    d[s]+=1
a=0
for v in d.values():
    if v>1:
        a+=v*(v-1)//2
print(a)

Solution (Python):
from collections import Counter,defaultdict
t=int(raw_input())
f=defaultdict(int)
while(t!=0):
    t=t-1
    s=(raw_input())
    s=sorted(list(s))
    f["".join(s)]+=1
ans=0
for i in f:
    p=f[i]
    ans+=((p)*(p-1))/2
print ans

Solution (Python):
n = int(input())
ss = []
dic = dict()
for i in range(n):
    s = input().rstrip()
    t = "".join(sorted(s))
    if t in dic:
        dic[t] += 1
    else:
        dic[t] = 1
ans = 0
for key in dic.keys():
    ans += (dic[key] * (dic[key]-1)) // 2

print(ans)

Solution (Python):
N = int(input())

S = [input() for i in range(N)]

C = [[0]*26 for i in range(N)]

for i in range(N):
    for j in range(len(S[i])):
        C[i][ord(S[i][j])-97]+=1

from collections import defaultdict as dd

dic=dd(int)

for i in range(N):
    dic[" ".join(map(str,C[i]))]+=1

ans = 0

for key in dic:
    ans+=dic[key]*(dic[key]-1)//2

print(ans)

Solution (Python):
n = int(input())
s = [input() for _ in range(n)]

for i in range(n):
    s[i] = [s[i][j] for j in range(len(s[i]))]
    s[i].sort()
    s[i] = ''.join(s[i])

s.sort()
s.append("x")
ans = 0
x = 0
y = "x"
for i in range(len(s)):
    if s[i] == y:
        x += 1
    else:
        ans += x * (x-1) // 2
        y = s[i]
        x = 1

print(ans)

Solution (Python):
n = int(input())
s = [input() for _ in range(n)]

import collections
a = []
for i in range(n):
    xx = list(s[i])
    xx.sort()

    a.append(''.join(xx))

c = collections.Counter(a)

ans = 0
for k in c.keys():
    v = c[k]
    ans += v * (v - 1) // 2

print(ans)

Solution (Python):
n=int(input())
s={}
for _ in range(n):
  b=tuple(sorted([i for i in input()]))
  if b in s:
    s[b]+=1
  else:
    s[b]=1
k=0
for i in s:
  j=s[i]
  k+=j*(j-1)//2
print(k)

Solution (Python):
from collections import defaultdict

n = int(input())
dct = defaultdict(int)

for i in range(n):
    s = input()
    sorted_s = "".join(sorted(s))
    dct[sorted_s] += 1

ans = 0
for k, v in dct.items():
    ans += v * (v - 1) // 2

print(ans)

Solution (Python):

import sys
from collections import Counter
INF = float("inf")


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

    numer = [n - r + k + 1 for k in range(r)]
    denom = [k + 1 for k in range(r)]

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

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

    return result


def solve(N: int, s: "List[str]"):
    for i in range(N):
        buf = list(s[i])
        buf.sort()
        s[i] = "".join(buf)
    s.sort()
    
    c = Counter(s)
    
    tot = 0
    for k in c:
        if c[k] >= 2:
            tot += cmb(c[k], 2)
    print(tot)

    return


def main():

    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    N = int(next(tokens))  
    s = [next(tokens) for _ in range(N)]  
    solve(N, s)


if __name__ == '__main__':
    main()

Solution (Python):
import collections
n=int(input())
l=[list(input()) for i in range(n)]
for i in range(n):
  l[i].sort()
  l[i]=''.join(l[i])
l=collections.Counter(l)
m=list(l.values())
ct=0
for i in range(len(m)):
  ct+=int(m[i]*(m[i]-1)//2)
print(ct)

Solution (Python):
N = int(input())

lst = []
for _ in range(N):
    tmp = list(input())
    tmp.sort()
    lst.append(tmp)
lst.sort()
tmp = lst[0]
count = 1
ans = 0
for i in range(1, N):
    if tmp == lst[i]:
        count += 1
    else:
        ans = ans + (count * (count - 1))//2
        count = 1
        tmp = lst[i]
ans = ans + (count * (count - 1))//2
print (ans)

Solution (Python):
from collections import defaultdict
N = int(input())
S = [''.join(sorted(input())) for _ in range(N)]
d = defaultdict(lambda:0)
for s in S:
    d[s] += 1
ans = 0
for s in d:
    n = d[s]
    ans += n*(n-1)//2

print(ans)

Solution (Python):

import sys
sys.setrecursionlimit(300000)


def solve(N: int, S: "List[str]"):
    p = []
    count = {}
    for i, s in enumerate(S):
        s = list(s)
        s.sort()
        s = ''.join(s)
        if s in count:
            count[s] += 1
        else:
            count[s] = 1
        p.append(s)
    ret = 0
    
    
    
    for c in count.values():
        ret += c * (c - 1) // 2
    print(ret)
    return


def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    N = int(next(tokens))  
    s = [ next(tokens) for _ in range(N) ]  
    solve(N, s)

if __name__ == '__main__':
    main()

Solution (Python):
from collections import Counter

n = int(input())
s = [''.join(sorted(input())) for _ in range(n)]
c = Counter(s)
ans = 0
for x in c.values():
    if x >= 2:
        ans += x*(x-1)//2

print(ans)

Solution (Python):
import sys
stdin = sys.stdin

sys.setrecursionlimit(10 ** 7)

def li(): return map(int, stdin.readline().split())
def li_(): return map(lambda x: int(x) - 1, stdin.readline().split())
def lf(): return map(float, stdin.readline().split())
def ls(): return stdin.readline().split()
def ns(): return stdin.readline().rstrip()
def lc(): return list(ns())
def ni(): return int(stdin.readline())
def nf(): return float(stdin.readline())


from collections import defaultdict

n = ni()
dic = defaultdict(int)

for _ in range(n):
    s = ns()
    cnts = [0]*26
    for si in s:
        cnts[ord(si)-ord('a')] += 1

    dic[tuple(cnts)] += 1

ans = 0
for _, v in dic.items():
    ans += v*(v-1) // 2

print(ans)

Solution (Python):


import itertools
from collections import Counter
from collections import defaultdict
from collections import deque
import bisect
from heapq import heappush, heappop

def main():
    n = int(input())
    sl = []
    for _ in range(n):
        s = list(input())
        s.sort()

        sl.append(''.join(s))

    counter = Counter(sl)
    ans = 0
    for s, c in counter.items():
        if c > 1:
            ptn = c * (c-1) // 2
            ans += ptn
    print(ans)

if __name__ == '__main__':
    main()

Solution (Python):
from collections import defaultdict
def choose2(n):
    return n * (n-1) // 2

n = int(input())
counts = defaultdict(int)

for i in range(n):
    norm = ''.join(sorted(input()))
    counts[norm] += 1

pairs = 0
for c in counts.values():
    if c >= 2:
        pairs += choose2(c)
print(pairs)

Solution (Python):
n=int(input())
from collections import Counter
ans=0
s=Counter(["".join(sorted(input())) for _ in [0]*n]).values()
for i in s:
    ans+=i*(i-1)//2
print(ans)

Solution (Python):
n = int(input())
d = dict()
for i in range(n):
    s = input()
    t = sorted(s)
    t = "".join(t)
    try:
        d[t] += 1
    except:
        d[t] = 1
ans = 0
for i in d.keys():
    ans += (d[i] * (d[i]-1))//2
print(ans)

Solution (Python):
from collections import Counter
N = int(input())
C = Counter()

for _ in range(N):
    C[sum(1<<(4*(ord(i)-97)) for i in input().strip())] += 1

ans = 0
for cv in C.values():
    ans += cv*(cv-1)//2
print(ans)