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 collections

N = int(input())
s_list = ["".join(sorted(input())) for i in range(N)]
s_list = sorted(s_list)

count = 0

c = collections.Counter(s_list)

for item in c:
  for pair in range(c[item]):
    count += pair
        
print(count)

Solution (Python):
def main():
    n=int(input())
    res = {}
    ans = 0
    for i in range(n):
        c = str(sorted(input()))
        if c not in res.keys():
            res[c] = 1
        else:
            res[c] += 1
    for i in res.values():
        ans += int(i*(i-1)/2)
    print(ans)


if __name__ == '__main__':
    main()

Solution (Python):
from collections import Counter
n = int(input())
ct_ls = []
for i in range(n):
    ct_ls.append("".join(sorted(input())))
ct = Counter(ct_ls)
_ct = 0
for n in ct.values():
    if n >= 2:
        _ct += n * (n - 1) / 2
print(int(_ct))

Solution (Python):


import math
import sys
import itertools
import numpy as np


n =int(input())


s = [list(input()) for i in range(n)] 
t = [0]*n

for i in range(n):
    a = sorted([s[i][ii] for ii in range(10)])
    for j in range(10):
        t[i] = t[i] * 26 + ord(a[j]) - ord('a')
t = sorted(t)
same = 1
mae = -1
answer = 0

for i in range(n):
    if t[i]==mae:
        same += 1
    else:
        answer += same * (same-1) // 2
        same = 1
        mae = t[i]
answer += same * (same-1) // 2
print(answer)

Solution (Python):
def c_green_bin(N, S):
    s = sorted([''.join(sorted(word)) for word in S])
    right = 1
    ans = 0
    for left in range(N):
        while right < N and s[left] == s[right]:
            right += 1
        ans += right - 1 - left
        if left + 1 == right:
            right += 1
    return ans

N = int(input())
S = [input() for _ in range(N)]
print(c_green_bin(N, S))

Solution (Python):
import sys
from collections import defaultdict

sys.setrecursionlimit(10**7)
INF = 10 ** 18
MOD = 10 ** 9 + 7
def LI(): return list(map(int, sys.stdin.readline().split()))
def II(): return int(sys.stdin.readline())
def LS(): return list(map(list, sys.stdin.readline().split()))
def S(): return list(sys.stdin.readline())[:-1]

def main():
    n = II()
    c = defaultdict(int)
    for i in range(n):
        c["".join(sorted(S()))] += 1
    ans = 0
    for k, v in c.items():
        ans += int(v * (v - 1) /2)
    print(ans)
if __name__ == '__main__':
    main()

Solution (Python):
import sys
sys.setrecursionlimit(10**7)
def LI(): return [int(x) for x in sys.stdin.readline().split()]
def LI_(): return [int(x) - 1 for x in sys.stdin.readline().split()]
def LF(): return [float(x) for x in sys.stdin.readline().split()]
def LS(): return sys.stdin.readline().split()
def II(): return int(sys.stdin.readline())
def SI(): return sys.stdin.readline().strip()
INF = 10 ** 18
MOD = 10 ** 9 + 7

debug = True
debug = False

def dprint(*objects):
    if debug == True:
        print(*objects)

def solve():
    N = II()
    s_list = []
    for i in range(N):
        s = SI()
        s = sorted(s)
        s_list.append(''.join(s))

    s_list = sorted(s_list)
    dprint(s_list)

    cnt_list = []
    cnt = 0
    current = ''
    for s in s_list:
        if current != s:
            cnt_list.append(cnt+1)
            current = s
            cnt = 0
        else:
            cnt += 1
    cnt_list.append(cnt+1)
    dprint(cnt_list)


    ans = 0
    for cnt in cnt_list:
        ans += cnt*(cnt-1)//2

    print(ans)

solve()

Solution (Python):
from collections import defaultdict
        

obj = defaultdict(lambda: 1)

N=int(input())
ANA=[]
L=set([])
for i in range(N):
    k="".join(sorted([x for x in input()]))
    if k in L:
        obj[k]+=1
    else:
        L.add(k)

result=0
for i in obj.values():
    if i and i-1:
        result+=i*(i-1)/2
    
print(int(result))

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

S = {}
for i in range(N):
  s = [0 for _ in range(26)]
  tmp = input()
  for j in range(10):
    s[ord(tmp[j]) - ord("a")] += 1
  
  s = ",".join(map(str, s))
  if s in S:
    S[s] += 1
  else:
    S[s] = 1

ans = 0
for v in S.values():
  if v > 1:
    for i in range(1, v):
      ans += i

print(ans)

Solution (Python):
import collections

n = int(input())

s_sorted = []
for i in range(n):
    s_sorted.append(''.join(sorted(list(input()))))
    



c = collections.Counter(s_sorted)


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

print(int(ans))

Solution (Python):
def c2(n):
    return (n*(n-1)) // 2

n = int(input())

d = {}
for _ in range(n):
    si = input()
    l = [0 for i in range(26)]
    for c in si:
        l[ord(c) - ord('a')] += 1

    if str(l) in d:
        d[str(l)] += 1
    else:
        d[str(l)] = 1

num = 0
for v in d.values():
    num += c2(v)

print(num)

Solution (Python):
n = int(input())
ss = {}
for _ in range(n):
  s = ''.join(sorted(input()))
  ss[s] = ss.setdefault(s, 0) + 1
count = sum([
  c*(c-1)//2
  for c in ss.values()
  if c > 1
] or [0])
print(count)

Solution (Python):
def comb(a,b):
    x = 1
    for i in range(a-b+1,a+1):x*=i
    for i in range(1,b+1):x//=i
    return(x)

n = int(input())

dict_num = {}

for _ in range(n):
    s = ''.join(sorted(list(input())))
    if(s in dict_num):dict_num[s]+=1
    else:dict_num[s] = 1

c=0
for k,v in dict_num.items():
    if(v>=2):c += comb(v,2)
print(c)

Solution (Python):
n = int(input())
sl = []
for _ in range(n):
    sl.append(sorted(input()))
sl.sort()
ans = 0
k = 1
prev = []
for s in sl:
    if s == prev:
        ans += k
        k += 1
    else:
        k = 1
        prev = s
print(ans)

Solution (Python):
inp = input()
n = int(inp)
inp_dictionary = {}
total_count = 0
for _ in range(n):
    inp = input()
    inp = sorted(inp)
    inp_str = ""
    for i in inp:
        inp_str += i
    if inp_str in inp_dictionary:
        total_count += inp_dictionary[inp_str]
        inp_dictionary[inp_str] = inp_dictionary[inp_str] + 1

    else:
        inp_dictionary[inp_str] = 1

print(total_count)

Solution (Python):
from collections import Counter
from sys import stdin

def main():
    N = int(input())
    S = stdin.read().splitlines()

    S = [''.join(sorted(s)) for s in S]
    cnt = Counter(S)
    ans = 0
    for s in S:
        ans += cnt[s] - 1
        cnt[s] -= 1
    print(ans)

input = lambda: stdin.readline().rstrip()
main()

Solution (Python):
from collections import defaultdict
from math import factorial
N = int(input())
dic = defaultdict(int)

for i in range(N):
    sort_str = "".join(sorted(input()))
    dic[sort_str] += 1

count = 0
for key, val in dic.items():
    if val >= 2:
        count += factorial(val) // (factorial(2) * factorial(val - 2))
print(count)

Solution (Python):
import math

num = int(input())

dic = {}
manykey = []


for i in range(num):
  s = input()
  s = "".join(sorted(s))
  
  if s in dic.keys():
    if dic[s] == 1:
      manykey.append(s)
    dic[s] += 1
  else:
    dic[s] = 1

ans = 0
for key in manykey:
  c = dic[key]
  ans += math.factorial(c)//math.factorial(c-2)//math.factorial(2)
    
print(ans)

Solution (Python):
from collections import deque,defaultdict,Counter
from itertools import accumulate
import bisect
from heapq import heappop,heappush
from fractions import gcd
from copy import deepcopy
import math
Mod = 1000000007



def main(): 
    N = int(input())
    s = [input() for i in range(N)]
    S = [[j for j in i] for i in s]
    p = []
    for i in range(N):
        S[i].sort()
        S[i] = "".join(S[i])
    S.sort()
    cnt = 0
    keep = "start"
    S.append("A")
    for i in S:
        if keep == "start":
            keep = i
            cnt += 1
        elif keep == i:
            cnt += 1
            keep = i
        else:
            p.append(cnt*(cnt-1)//2)
            cnt = 1
            keep = i
    print(sum(p))
        
if __name__ == "__main__":
    main() 




def sieve_of_eratosthenes(n):
    if not isinstance(n,int):
        raise TypeError("n is not int")
    if n<2:
        raise ValueError("n < 2 is not effective")
    prime = [1]*(n+1)
    for i in range(2,int(math.sqrt(n))):
        if prime[i] == 1:
            for j in range(2*i,n):
                if j%i == 0:
                    prime[j] = 0
    res = []
    for i in range(2,n):
        if prime[i] == 1:
            res.append(i)
    return res

class UnionFind:
    def __init__(self,n):
        self.parent = [i for i in range(n+1)]
        self.rank = [0 for i in range(n+1)]
    
    def findroot(self,x):
        if x == self.parent[x]:
            return x
        else:
            y = self.parent[x]
            y = self.findroot(self.parent[x])
            return y
    
    def union(self,x,y):
        px = self.findroot(x)
        py = self.findroot(y)
        if px < py:
            self.parent[py] = px
        else:
            self.parent[px] = py

    def same_group_or_no(self,x,y):
        return self.findroot(x) == self.findroot(y)

Solution (Python):
import sys

n= int(sys.stdin.readline())

d = dict()
for _ in range(n):
    s= sys.stdin.readline().strip()
    a= [ c for c in s ]
    a.sort()
    s= "".join(a)
    d[s]= d.get(s,0) + 1

c= 0
for m in d.values(): c += (m*(m-1))//2
print( c )

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

CL = []
for _ in range(N):
    s = [c for c in input()]
    s.sort()
    CL.append(''.join(s))

CL.sort()

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

print(ans)

Solution (Python):
from collections import Counter


N = int(input())
c = Counter()
for _ in range(N):
    si = "".join(sorted(input()))
    c[si] += 1

ans = sum([n*(n - 1) // 2 for n in c.values()])
print(ans)

Solution (Python):
N = int(input())
S = [None] * N
for i in range(N):
    S[i] = input()
nums = [None] * N
for i, s in enumerate(S):
    tmp = [0] * 26
    for c in s:
        tmp[ord(c)-97] += 1
    nums[i] = ' '.join(map(str, tmp))

ans = 0
checker = dict()

for s in reversed(nums):
    
    if s in checker:
        ans += checker[s]
        checker[s] += 1
    else:
        checker[s] = 1
print(ans)

Solution (Python):
from collections import Counter

n = int(input())
ss = [''.join(sorted(input())) for i in range(n)]
cs = Counter(ss)
ans = 0
for c in cs.most_common():
    if c[1] > 1:
        ans += c[1] * (c[1] - 1) // 2
print(ans)

Solution (Python):

import sys
import math
input = sys.stdin.readline
sys.setrecursionlimit(10**6)

n = int(input())
s = dict()
for _ in range(n):
    t = tuple(sorted(input()))
    if (s.get(t) == None):
        s[t] = 1
    else:
        s[t] += 1
c = 0
for i in s.values():
    if(i>1):
        c += math.factorial(i) // (math.factorial(i - 2) * math.factorial(2))
print(c)

Solution (Python):
import collections
n = int(input())
s = []
for _ in range(n):
    si = list(input())
    si.sort()
    s.append(''.join(si))
    
con = collections.Counter(s).most_common()
cnt = 0
for sc in con:
    if sc[1] == 1:
        break
    else:
        cnt += (sc[1] * (sc[1]-1))//2
print(cnt)

Solution (Python):
import collections
a = int(input())
b = ["".join(sorted(list(input()))) for _ in range(a)]
b = collections.Counter(b)
total = 0
for i in b.values():
    for j in range(1, i):
        total += j
print(total)

Solution (Python):



def solve(N, ss):
    d = dict()
    for s in ss:
        s = ''.join(sorted(s))
        if s in d:
            d[s] += 1
        else:
            d[s] = 1

    ans = 0
    for s, num in d.items():
        if num >= 2:
            ans += (num * (num-1)) // 2

    return ans


if __name__ == '__main__':
    N = int(input())
    ss = [input() for _ in range(N)]

    ans = solve(N, ss)

    print(ans)

Solution (Python):
from collections import Counter

n = int(input())
s = [list(input()) for _ in range(n)]


for i in range(n):
    s[i].sort()
    s[i] = "".join(s[i])

c = Counter(s)

ans = 0

for v in c.values():
    ans += v * (v - 1) // 2
print(ans)

Solution (Python):
import sys
def input(): return sys.stdin.readline().strip()
n=int(input())
ss=[]
for _ in range(n):
    ss.append(''.join(sorted(input())))
import itertools
import math
c = 0
for _, g in itertools.groupby(sorted(ss)):
    lg = len(list(g))
    if lg > 1:
        c += lg * (lg-1) // 2
print(c)

Solution (Python):
import math
from functools import reduce
from collections import deque
import sys
sys.setrecursionlimit(10**7)

def s(generator, splitter, mapper):
    return [ mapper(s) for s in generator().split(splitter) ]


def get_nums_l():
    return [ int(s) for s in input().split(" ")]


def get_nums_n(n):
    return [ int(input()) for _ in range(n)]

n = int(input())
sss = [ input() for _ in range(n) ]
sss = sorted(map("".join, map(sorted, sss)))

ans = 0
left = 0
while left<n-1:
    for right in range(left+1, n):
        if sss[left] != sss[right]:
            dis = right - left -1
            ans += dis * (dis+1) // 2
            left = right
            break
    if right == n-1:
        break


dis = right - left
ans += dis * (dis+1) // 2


print(ans)

Solution (Python):
import math

N = int(input())
s = {}
ans = 0

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

x = math.factorial(2)
for n in s.values():
  	if n > 1:
	    ans += math.factorial(n) // (math.factorial(n-2) * x)
print(ans)

Solution (Python):



def main():
    from collections import Counter

    n = int(input())
    c = Counter()
    ans = 0

    for i in range(n):
        si = sorted(input())
        c[''.join(map(str, si))] += 1

    for idx, ci in c.items():
        ans += ci * (ci - 1) // 2

    print(ans)


if __name__ == '__main__':
    main()

Solution (Python):
N = int(input())
s = sorted([sorted(list(input())) for i in [0]*N])

p = 1
i = 0
j = 1
ans = 0
while(j < N):
	if s[i]==s[j]:
		p += 1
		j = j + 1
	else:
		ans += p*(p-1)//2
		p = 1
		i = j
		j = j + 1
ans += p*(p-1)//2
print(ans)

Solution (Python):
import collections


def solve():
    n = int(input())
    s = list(input() for _ in range(n))
    sets = [''.join(sorted(e)) for e in s]
    co = collections.Counter(sets)
    ans = 0
    for v in co.values():
        ans += v * (v - 1) // 2
    return ans


if __name__ == "__main__":
    print(solve())

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

strs = {}

for i in range(n):
  tmp = sorted(input())
  tmp = ''.join(tmp)
  if tmp in strs:
    strs[tmp] += 1
  else:
    strs[tmp] = 1
    
count = 0
for v in strs.values():
  if v > 1 :
    count += v * (v-1) // 2

print(count)

Solution (Python):
n=int(input())
a=sorted(([sorted(list(input()))for i in range(n)]))+["1"]
d=0
e,r=1,""
for i in a:
    if r!=i:
        r=i
        d+=(e*(e-1))//2
        e=1
    else:
        e+=1
print(d)

Solution (Python):
N=int(input())
s_list=[]
for i in range(N):
    s_list.append(input())
s_list2=["".join(sorted(x)) for x in s_list]

dic={}
for s in s_list2:
    if s not in dic.keys():
        dic[s]=1
    else:
        dic[s]+=1
    
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

c=0
for x in dic.items():
    if x[1]>=2:
        c+=cmb(x[1],2)
print(c)

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

inputlist = [sorted(input()) for _ in range(N)]

inputlist.sort()

ans = 0
continued = 1

last = []
for l in inputlist:
    if last == l:
        continued += 1
    else:
        ans += continued * (continued - 1) // 2
        continued = 1
    last = l

ans += continued * (continued - 1) // 2
continued = 0

print(ans)

Solution (Python):
n=int(input())
strli=[]
for i in range(n):
    li=list(input())
    strli.append(li)

strs=[]
for i in range (n):
    strli[i].sort()
    strs.append("".join(strli[i]))

cnt = {}
for i in range(n):
    if strs[i] in cnt:
        cnt[strs[i]] += 1
    else:
        cnt[strs[i]] = 1
ans = 0
for i in cnt:
    if cnt[i] >= 2:
        ans += int(cnt[i] * (cnt[i] -1) /2)

print(ans)

Solution (Python):



def f(s):
    x = [0]*26
    base = ord('a')
    
    for c in s:
        x[ord(c) - base] += 1

    return x


def main():
    N = int(input())
    Q = {}

    for i in range(N):
        S = input()
        k = tuple(f(S))

        if k in Q:
            Q[k] += 1
        else:
            Q[k] = 1

    print(sum(map(lambda n: n*(n-1)//2, Q.values())))




if __name__ == '__main__':
    main()

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

Solution (Python):
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

def main():
    
    N = int(input())
    ana = {}
    for _ in range(N):
        key = ''.join(sorted(input()))
        if key in ana:
            ana[key] += 1
        else:
            ana[key] = 1

    counter = 0
    for key in ana:
        if ana[key] == 1:
            continue
        counter += cmb(ana[key], 2)
    print(counter)

if __name__ == "__main__":
    main()

Solution (Python):
n = int(input())
d={}
for i in range(n):
    s=str(sorted(input()))
    try:
        d[s]+=1
    except:
        d[s]=1
ans=0

for i in d.values():
        ans+=i*(i-1)//2
print(ans)

Solution (Python):
N = int(input())
A = {}
cnt = 0
for i in range(N):
    x = sorted(list(input()))
    if str(x) in A.keys():
        A[str(x)] += 1
    else:
        A[str(x)] = 1
for i in A.values():
    cnt += sum(list(range(i)))
print(cnt)

Solution (Python):
n = int(input())
s = ['' for _ in range(n)]
for i in range(n):
    s[i] = list(input())
    s[i].sort()
    s[i] = ''.join(s[i])
s.sort()
s.append('
res = 0
cnt = 1
for i in range(n):
    if s[i] != s[i+1]:
        res += cnt *(cnt-1)//2
        cnt = 1
    else:
        cnt += 1
print(res)

Solution (Python):
N = int(input())
S = []
for i in range(N):
    S.append(list(input()))
    S[i].sort()
S.sort()

c = 0
oldi = 0
for i in range(N):
    if S[oldi] == S[i]:
        pass
    else:
        c += (i-oldi)*(i-oldi-1)//2
        oldi = i
c += (N-oldi)*(N-oldi-1)//2
print(c)

Solution (Python):
import math

N = int(raw_input())
S = [raw_input() for _ in range(N)]
D = {}
for s in S:
    k = "".join(sorted(s))
    if k not in D:
        D[k] = []
    D[k].append(s)

ans = 0
for k,v in D.items():
    n = len(v)
    if n > 1:
        ans += math.factorial(n) / (2 * math.factorial(n-2))
print ans

Solution (Python):
from collections import Counter

N = int(input())
S = [str(sorted(input())) for _ in range(N)]
ans = 0
for v in Counter(S).values():
    ans += v*(v-1) // 2

print(ans)

Solution (Python):

import sys

def nPr(n, r):
   """
   Calculate the number of permutation (nPr = n!/(n-r)!).
   The parameters need to meet conditions of n >= r >= 0.
   It returns 1 if r == 0, which means there is one pattern
   to choice 0 items out of the number of n.
   """
   num = 1
   for i in range(n, n-r, -1):
       num *= i
   return num

def nCr(n, r):
    """
    Calculate the number of combination (nCr = nPr/r!).
    The parameters need to meet the condition of n >= r >= 0.
    It returns 1 if r == 0, which means there is one pattern
    to choice 0 items out of the number of n.
    """

    
    r = min(r, n-r)

    
    numerator = 1
    for i in range(n, n-r, -1):
        numerator *= i

    
    denominator = 1
    for i in range(r, 1, -1):
        denominator *= i

    return numerator // denominator


def solve(N: int, s: "List[str]"):
    for i in range(N):
        l = list(s[i])
        l.sort()
        s[i] = ''.join(l)

    from collections import Counter

    c = Counter(s)
    ans = 0
    
    for k, v in c.most_common():
        if( v >= 2):
            ans += nCr(v,2)

    print(ans)
    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 operator import mul
from functools import reduce

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

n=int(input())
l=[input() for i in range(n)]
for i in range(n):
	l[i]="".join(sorted(l[i]))
l.sort()
cnt=ans=0
ref=[]
for i,j in zip(l,l[1:]):
	if i==j:
		cnt+=1
	else:
		ref.append(cnt)
		cnt=0
ref.append(cnt)
for i in ref:
	if i!=0:
		ans+=cmb(i+1,2)
print(ans)

Solution (Python):
from collections import Counter
from collections import defaultdict

d = defaultdict(int)

N = int(input())
SS = [0]*N
for _ in range(N):
    SS[_] = input()

for S in SS:
    o = [0]*26
    for s in S:
        o[ord(s)-97] += 1
    d[''.join(map(str,o))] += 1

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

print(ans)

Solution (Python):
from collections import defaultdict
def solve():
    n = int(input())
    m = defaultdict(int)
    for _ in range(n):
        m["".join(sorted(input()))] += 1
    ans = 0
    for s, i in m.items():
        if i != 1:
            ans += i * (i - 1) // 2
    print(ans)
solve()

Solution (Python):
N = int(input())
s_dict = {}
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

for _ in range(N):
  s_list = list(input())
  s_list.sort()
  S = ''.join(s_list)
  if S in s_dict:
    s_dict[S] += 1
  else:
    s_dict[S] = 1
ans = 0
for value in s_dict.values():
  if value > 1:
    ans += cmb(value, 2)
print(ans)

Solution (Python):
import sys
from collections import defaultdict

def main():
    input = sys.stdin.readline
    ans = 0
    d = defaultdict(lambda: 0)
    N = int(input())
    for _ in range(N):
        s = [c for c in str(input().strip())]
        s.sort()
        s = tuple(s)
        if s in d:
            ans += d[s]
        d[s] += 1

    return ans


if __name__ == '__main__':
    print(main())

Solution (Python):
N= int(input())
s= [input() for i in range(N)]
a=0
for i in range(N):
    s[i]=sorted(s[i])
s=sorted(s)
dp=s[0]
tmp=0
for i in range(N-1):
    if dp==s[i+1]:
        tmp+=1
    else:
        a+=int((1+tmp)/2*tmp)
        tmp=0
        dp=s[i+1]

a+=int((1+tmp)/2*tmp)
print(a)

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

strings = [input() for _ in range(n)]

st2 = [[]] * n
for i in range(n):
	st2[i] = sorted(strings[i])
st2.sort()

ans = 0
same = 1
for i in range(1, n):
	if st2[i] == st2[i-1]:
		same += 1
	else:
		ans += int(same * (same-1)//2)
		same = 1

ans += int(same * (same-1)//2)
print(ans)

Solution (Python):
s=[]
a=[]
n=int(input())
for i in range(n):
	x=input()
	s.append(x)
	aa=[]
	for j in range(27):
		bb=x.count(chr(97+j))
		aa.append(bb)
	a.append(aa)
a.sort()
ans=0
cnt=0
for i in range(n-1):
	if a[i]==a[i+1]:
		cnt+=1
	else:
		ans+=(cnt*(cnt+1))//2
		cnt=0
ans+=(cnt*(cnt+1))//2
print(ans)

Solution (Python):
from collections import defaultdict
dic = defaultdict(int)

N = int(input())
for _ in range(N):
    S = input()
    A = []
    for s in S:
        A.append(s)
    A.sort()
    word = ""
    for a in A:
        word += a
    dic[word] += 1

ans = 0
for v in dic.values():
    if v >= 2:
        ans += v * (v - 1) // 2
print(ans)

Solution (Python):
import math,string,itertools,fractions,heapq,collections,re,array,bisect,sys,random,time,queue,copy

sys.setrecursionlimit(10**7)
inf=10**20
mod=10**9+7
dd=[(-1,0),(0,1),(1,0),(0,-1)]
ddn=[(-1,0),(-1,1),(0,1),(1,1),(1,0),(1,-1),(0,-1),(-1,-1)]

def LI(): return [int(x) for x in sys.stdin.readline().split()]
def LI_(): return [int(x)-1 for x in sys.stdin.readline().split()]
def I(): return int(sys.stdin.readline())
def LS(): return sys.stdin.readline().split()
def S(): return input()


def nCr(n,r):
  if n<r:
    return 0
  return math.factorial(n)//(math.factorial(n-r)*math.factorial(r))

def main():
  n=I()
  l=[]
  for i in range(n):
    a=list(S())
    a.sort()
    l.append(a)

  l.sort()

  a=l[0]
  c=1
  ans=0
  for x in l[1:]:
    if a==x:
      c+=1
    else:
      ans+=nCr(c,2)
      c=1
      a=x

  ans+=nCr(c,2)
  c=1
  a=x
  return ans


print(main())

Solution (Python):
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())
S = [input() for _ in range(N)]

d = {}
for s in S:
    s = "".join(sorted(s))
    if s in d:
        d[s] += 1
    else:
        d[s] = 1
ans = 0
for v in d.values():
    if v > 1:
        ans += cmb(v, 2)
print(ans)

Solution (Python):


words = lambda t : list(map(t, input().split()))
n = int(input())
d = {}

for i in range(n):
    str = "".join(sorted(input()))
    if str not in d:
        d[str] = 1
    else:
        d[str] += 1

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

print(ans)

Solution (Python):


def readInts():
  return [int(s) for s in input().split(" ")]

def main():
  N = readInts()[0]
  counts = {}
  for i in range(N):
    s = input()
    ss = "".join(sorted(s))
    if not ss in counts:
      counts[ss] = 0
    counts[ss] += 1

  ans = 0
  for count in counts.values():
    if count > 1:
      combi = ((count - 1) * count) // 2
      ans += combi
  print(ans)

if __name__ == "__main__":
  main()

Solution (Python):
from collections import defaultdict
N = int(input())
d = defaultdict(int)
for i in range(N):
    S = input()
    S = "".join((sorted(list(S))))
    d[S] += 1
ans = 0
for val in d.values():
    ans += val * (val - 1) // 2
print(ans)

Solution (Python):
from collections import Counter
n = int(input())
ls = []
for i in range(n):
    ls.append("".join(sorted(input())))
valus = Counter(ls).values()
cnt=0
for v in valus:
    for vs in range(v):
        cnt += vs
print(cnt)

Solution (Python):
N = int(input())
s = []
for i in range(N):
	s.append(list(input()))
for i in range(N):
	s[i].sort()
s.sort()
total = 0
num = 0
for i in range(N - 1):
	for x in range(10):
		if s[i][x] != s[i+1][x]:
			total += num*(num+1)//2
			num = 0
			break
		if x == 9:
			num += 1
total += num*(num+1)//2

print(total)

Solution (Python):
n = int(input())
d = dict()
res = 0
for i in range(n):
    ss = input()
    ss = list(ss)
    ss.sort()
    ss = ''.join(ss)
    if d.__contains__(ss):
        res += d[ss]
        d[ss]+=1
    else:
        d[ss] = 1
print(res)

Solution (Python):
import sys
from collections import defaultdict

n = int(input())
s = [sys.stdin.readline().rstrip() for _ in range(n)][::-1]

d = defaultdict(int)

result = 0
for i in range(n):
    num = ''.join(sorted(s[i]))
    result += d[num]
    d[num] += 1

print(result)

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

dic = {}

cnt = 0
for i in range(n):
    s = input()
    ent = []
    lst = list(s)
    lst.sort()
    for c in lst:
        ent.append(c)

    t = tuple(ent)

    if t in dic:
        dic[t] += 1
    else:
        dic[t] = 1

for k in dic:
    v = dic[k]
    if v > 1:
        for i in range(v):
            cnt += i


print(cnt)

Solution (Python):
N = int(input())
Ts = []
for i in range(N):
  S = input()
  T = "".join(sorted(S))
  Ts.append(T)
Ts.sort()
r = 0
c = 1
for i in range(N-1):
  if Ts[i] == Ts[i+1]:
    c += 1
  else:
    r += c*(c-1)//2
    c = 1
r += c*(c-1)//2
print(r)

Solution (Python):

def cmp2(n):
    return n * (n-1) // 2

n = int(input())
s = {}

for i in range(n):
    si = input()
    anagram = "".join(sorted(si))
    if anagram in s:
        s[anagram] += 1
    else:
        s[anagram] = 1

cnt = 0
for c in s.values():
    cnt += cmp2(c)

print(cnt)