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-----
3
acornistnt
peanutbomb
constraint

-----Sample Output-----
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.

Difficulty: introductory

Starter code:

Solutions:
from collections import defaultdict
n = int(input())
s_dict = defaultdict(int)
for i in range(n):
  s_int = [0] * 26
  s = list(input())
  for si in s:
    s_int[ord(si) - ord('a')] += 1
  cnt = 0
  for s_int_i in s_int:
    cnt *= 10
    cnt += s_int_i
  s_dict[cnt] += 1
ans = 0
for key in s_dict:
  ans += s_dict[key] * (s_dict[key] - 1) / 2
print(int(ans))

from collections import Counter

n = int(input())

a =[]
ans= 0
for i in range(n):
  b = sorted(input())
  b = "".join(b)
  a.append(b)
mycounter =Counter(a)
for j in mycounter.values():
  l = j
  if l >= 2:
    ans += ((l-1)+1)*(l-1)//2

print(ans)

N = int(input())
dic = {}
ans = 0
for i in range(N):
    a = sorted(input())
    a = "".join(a)
    if a in dic:
        ans += dic[a]
        dic[a] += 1
    else:
        dic[a] =1
print(ans)

N=int(input())
S=[''.join(sorted(input())) for _ in range(N)]
ans=0
num=1
S.sort()
for i in range(1,N):
    if S[i-1]==S[i]:
        num+=1
    else:
        ans+=num*(num-1)//2
        num=1
ans+=num*(num-1)//2
print(ans)


from collections import Counter
N = int(input())
Aset = dict()
Ans = 0
for _ in range(N):
    S = input()
    NewS = ''
    S = sorted(S)
    for i in range(len(S)):
        NewS += S[i]
    if NewS not in Aset:
        Aset[NewS] = 1
    else:
        Ans += Aset[NewS]
        Aset[NewS] += 1
print(Ans)

import collections
N = int(input())
ls, rst = [], 0
for i in range(N):
    s = list(input())
    s.sort()
    ls.append(''.join(s))
rst_ls = collections.Counter(ls)
for i in rst_ls.values():
    rst += (i * (i - 1)) // 2
print(rst)

import collections
import sys

input = sys.stdin.readline

class common_function():
    """
        1. よく使いそうで予め用意してあるものをまとめた
        2. よく使いそうな関数群をまとめた
    """
    def nCk(self, n:int, k:int):
        """
            mod を使用しない combination nCk を求めるメソッド
            1回 の nCk を求めるのに O(k) かかる.
        """
        k = min(k, n-k)
        numer = 1
        for i in range(n, n-k, -1):
            numer *= i
        denom = 1
        for i in range(k, 1, -1):
            denom *= i
        return numer // denom

def main():
    common = common_function()
    N = int(input())
    slist = []
    tlist = []
    for _ in range(N):
        s = list(input()[:-1])
        s.sort()
        slist.append(s)
    slist.sort()
    cnt = 1; tlist.append(cnt)
    for i in range(N-1):
        if slist[i] == slist[i+1]:
            tlist.append(cnt)
        else:
            cnt += 1
            tlist.append(cnt)
    tlistcount = list(collections.Counter(tlist).items())
    tlistcount.sort(key=lambda x: x[1], reverse=True)
    ans = 0
    for t0, t1 in tlistcount:
        if t1 == 1:
            break
        ans += common.nCk(t1, 2)
    print(ans)

def __starting_point():
    main()

__starting_point()

from collections import Counter
n = int(input())
m = []
count = 0
for i in range(n):
    m.append("".join(sorted(str(input()))))
m = Counter(m)
ans = 0
for j in m.values():
    ans += j * (j-1) / 2
print(int(ans))

from collections import Counter
n = int(input())
s = [tuple(sorted(input())) for _ in range(n)]

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


from math import factorial as f

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

for _ in range(n):
  s = list(input())
  s.sort()
  s = "".join(s)

  is_ok = d.get(s, False)
  if is_ok: d[s] += 1
  else: d[s] = 1

ans = 0

for i in d.values():
  if i >= 2:
    ans += f(i) // f(i-2) // f(2)

print(ans)

N = int(input())
l = []
for i in range(N):
    s = input()
    S = [s[x] for x in range(10)]
    S = sorted(S)
    s = ""
    for j in range(10):
        s += S[j]
    l.append(s)


from collections import Counter

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

print(ans)

n = int(input())
L = ["".join(sorted(input())) for i in range(n)]


from collections import Counter
L = Counter(L)

def num(n):
    return n*(n-1)//2
    
cnt = 0  
for v in L.values():
    cnt +=num(v)
print(cnt)

n = int(input())
d = dict()
for i in range(n):
  S = ''.join(sorted(list(input())))
  if S in d.keys():
    d[S] +=1
  else:
    d[S] = 1
 
ans = 0
for i in d.values():
  ans += i*(i-1)//2
print(ans)

from collections import Counter 
N = int(input())
s = [input() for _ in range(N)]
 
# N=10^5より、O(N)で解く
for i in range(N):
  s[i] = sorted(s[i])
  s[i] = ''.join(s[i])

s = Counter(s).most_common()
ans = 0
for t in s:
  ans += t[1]*(t[1]-1)//2
  
print(ans)

import collections
n=int(input())
s=[]
a=0

for i in range(n):
    b=list(input())
    b.sort()
    b=str(b)
    s.append(b)

c=collections.Counter(s)

for i in c.values():
    if i>1:
        a+=i*(i-1)//2

print(a)

n=int(input())
mozi=[]
for i in range(n):
    mozi.append(sorted(input()))
mozi.sort()

def hantei(x,y):
    for i in range(10):
        if x[i]!=y[i]:
            return False
    return True

def conbi(n,r):
    ue=1
    for i in range(n-r+1,n+1):
        ue*=i
 
    sita=1
 
    for i in range(1,r+1):
        sita*=i
 
 
    return (ue//sita)
i=0
ans=0
while i<n-1:
    c=1
    while i<n-1 and hantei(mozi[i],mozi[i+1]):
        c+=1
        i+=1
    ans+=conbi(c,2)
    i+=1

print(ans)

import bisect, collections, copy, heapq, itertools, math, string, sys
input = lambda: sys.stdin.readline().rstrip() 
sys.setrecursionlimit(10**7)
INF = float('inf')
def I(): return int(input())
def F(): return float(input())
def SS(): return input()
def LI(): return [int(x) for x in input().split()]
def LI_(): return [int(x)-1 for x in input().split()]
def LF(): return [float(x) for x in input().split()]
def LSS(): return input().split()

def resolve():
    N = I()
    s = [''.join(sorted(list(SS()))) for _ in range(N)]

    cnt = collections.Counter(s)
    ans = sum([i * (i - 1) // 2 for i in list(cnt.values())])

    print(ans)

def __starting_point():
    resolve()

__starting_point()

import collections 
from scipy.special import comb

N=int(input())
List=[]
for i in range(N):
    line=list(str(input()))
    line.sort()
    List.append("".join(line))
 
ans=0   
for i,j in collections.Counter(List).items():
    num=comb(j, 2, exact=True)
    ans+=num
    
print(ans)


url = "https://atcoder.jp//contests/abc137/tasks/abc137_c"

import itertools

def main():
    n = int(input())
    maps = {}
    count = 0
    for i in range(n):
        s = sorted(input())
        s = ''.join(s)
        maps.setdefault(s, 0)
        maps[s] += 1
    for k in maps:
        count += maps[k] * (maps[k] - 1) // 2
    print(count)

def __starting_point():
    main()

__starting_point()

import math

N = int(input())
records = {}

for i in range(N):
    l = ''.join(sorted(input()))
    records.setdefault(l, 0)
    records[l] += 1

count = 0
for v in records.values():
    if v == 1:
        continue
    else:
        count += math.comb(v, 2)

print(count)

from collections import Counter
n = int(input())
s = []
for i in range(n):
    s1 = ''.join(sorted(input()))
    s.append(s1)
s = Counter(s).most_common()
num = 0
for i,h in s:
    num += (h*(h-1))//2
print(num)

N = int(input())
D = {}
res = 0

for i in range(N):
  A = list(input())
  A.sort()
  if str(A) in D:
    res += D[str(A)]
    D[str(A)] += 1
  else:
    D[str(A)] = 1
    
print(res)

from collections import defaultdict as dd

n=int(input())
dic=dd(int)
for i in range(n):
  s=sorted(input())
  dic[''.join(s)]+=1

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

from collections import defaultdict

n=int(input())
l=[]
clst=defaultdict(lambda:0)
for i in range(n):
  clst[str(sorted(input()))]+=1
  
ans=0
for x in clst.values():
  x-=1
  if x > 0:
    ans+=(1+x)*x//2 
print(ans)

import itertools
N = int(input())
A = [input() for i in range(N)]
dic = {}
ans = 0
for j in range(N):
    a = str(sorted(A[j]))
    if a not in dic:
        dic[a] = 1
    else:
        dic[a] += 1
        ans += dic[a]-1

print(ans)

from collections import Counter
n = int(input())
lst = []
for _ in range(n):
    s = sorted(list(input()))
    lst.append("".join(s))
c = Counter(lst)
ans = 0
for k,v in c.items():
    ans += v*(v-1)//2

print(ans)

N = int(input())
S = []
ans = 0

for i in range(N):
  s = list(input())
  s.sort()
  S.append("".join(s))

S.sort()

count = 1

for j in range(N-1):
  if S[j] == S[j+1]:
    count += 1
  else:
    if count > 1:
      ans += count*(count-1)//2
    count = 1
else:
    if count > 1:
      ans += count*(count-1)//2

print(ans)

N = int(input())
s = [sorted(input()) for i in range(N)]
s.sort()
ans = 0
for i in range(N-1):
    if s[i] == s[i+1]:
        start = i
        end = N-1
        while start != end:
            center = (start + end) // 2
            if s[center] == s[i]:
                if s[center+1] == s[i]:
                    start = center+1
                else:
                    start = end = center
            else:
                end = center
        ans += start - i
print(ans)

# -*- coding: utf-8 -*-
"""
Created on Thu Sep 10 00:32:19 2020

@author: liang
"""

N = int(input())
d = dict()
for i in range(N):
    S = input()
    S = ''.join(sorted(list(S)))
    #print(S)
    if S in d.keys():
        d[S] += 1
    else:
        d[S] = 1

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

import collections
N = int(input())
S_ls = []
cnt, rst = 0, 0
for i in range(N):
    S = list(input())
    S.sort()
    val = ''
    S_ls.append(''.join(S))
rst_ls = collections.Counter(S_ls)
for i in rst_ls.values():
    rst += i * (i - 1) // 2
print(rst)

N=int(input())
d={}
c=0
for i in range(N):
    s=str(sorted(input()))
    if s in d:
        c+=d[s]
        d[s]+=1
    else:
        d[s]=1
print(c)

n = int(input())
d = {}
ans = 0
for i in range(n):
    s = ''.join(sorted(input()))
    if s in d:
        ans += d[s]
        d[s] += 1
    else:
        d[s] = 1
print(ans)

from collections import Counter
n = int(input())
cnt_s = Counter([" ".join(sorted(input())) for i in range(n)])
print(sum(v*(v - 1)//2 for v in cnt_s.values()))

N = int(input())
S = [list(map(str, input())) for _ in range(N)]
S.sort()
for s in S:
    s.sort()

ans = 0
dic = {}

for s in S:
    ss = "".join(s)
    if ss in dic:
        ans += dic[ss]
        dic[ss] += 1
    else:
        dic[ss] = 1

print(ans)

n = int(input())
d = {}
ans = 0
for i in range(n):
    s = ''.join(sorted(input()))
    if s in d:
        ans += d[s]
        d[s] += 1
    else:
        d[s] = 1
print(ans)

n = int(input())
d = {}
e = []
ans = 0
for i in range(n):
  s = list(input())
  s.sort()
  s = "".join(s)
  if s in d:
    d[s] += 1
  else:
    d[s] = 1
for key,value in d.items():
  if value > 1:
    e.append(d[key])
for j in e:
  ans += j*(j-1)//2
print(ans)

n = int(input())
s = [list(input()) for i in range(n)]
cnt_dic = {}
sum_cnt = 0

for i in range(n):
    s[i].sort()
    if str(s[i]) in cnt_dic:
        cnt_dic[str(s[i])] = cnt_dic[str(s[i])] + 1
    else:
        cnt_dic[str(s[i])] = 1

for n in cnt_dic.values():
    sum_cnt += int( n * (n-1) / 2)

print(sum_cnt)

import sys
from collections import Counter

sys.setrecursionlimit(10 ** 8)
ini = lambda: int(sys.stdin.readline())
inl = lambda: [int(x) for x in sys.stdin.readline().split()]
ins = lambda: sys.stdin.readline().rstrip()
debug = lambda *a, **kw: print("\033[33m", *a, "\033[0m", **dict(file=sys.stderr, **kw))


def solve():
    n = ini()
    count = Counter()
    for i in range(n):
        s = ins()
        s = "".join(sorted(s))
        count[s] += 1

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


print(solve())


# import sys
# sys.setrecursionlimit(10 ** 6)
# import bisect
# from collections import deque
# from decorator import stop_watch
#
#
# @stop_watch
def solve(N, Ss):
    for i in range(N):
        Ss[i] = ''.join(sorted(list(Ss[i])))
    Ss.sort()
    ans = 0
    flg = False
    counter = 0
    for i in range(N - 1):
        if Ss[i] == Ss[i + 1]:
            if not flg:
                flg = True
                counter = i
        elif flg:
            ans += (i - counter + 1) * (i - counter) // 2
            flg = False
    if flg:
        ans += ((N - 1) - counter + 1) * ((N - 1) - counter) // 2
    print(ans)


def __starting_point():
    # S = input()
    N = int(input())
    # N, M = map(int, input().split())
    Ss = [input() for _ in range(N)]
    # As = [int(i) for i in input().split()]
    # Bs = [int(i) for i in input().split()]
    solve(N, Ss)

__starting_point()

import sys
import math
from collections import defaultdict, deque, Counter
from copy import deepcopy
from bisect import bisect, bisect_right, bisect_left
from heapq import heapify, heappop, heappush
    
input = sys.stdin.readline
def RD(): return input().rstrip()
def F(): return float(input().rstrip())
def I(): return int(input().rstrip())
def MI(): return map(int, input().split())
def MF(): return map(float,input().split())
def LI(): return list(map(int, input().split()))
def TI(): return tuple(map(int, input().split()))
def LF(): return list(map(float,input().split()))
def Init(H, W, num): return [[num for i in range(W)] for j in range(H)]
    
    
def main():
    N = I()
    L = []
    for i in range(N):
        temp = input().rstrip()
        temp = sorted(temp)
        L.append(temp)
    for i in range(9, -1, -1):
        L.sort(key = lambda x:x[i])
    ans = 0
    index = 0
    temp_index = 0

    while True:
        while index+1 < N and L[index+1] == L[index]:
            index+=1
            temp_index+=1
        ans += (temp_index+1)*temp_index // 2
        temp_index=0
        index+=1
        if index >= N-1:
            break
    print(ans)
    
def __starting_point():
    main()
__starting_point()

import collections
S=[]
n=int(input())
for _ in range(n):
    s=input()
    S.append(str(sorted(s)))
ss=collections.Counter(S)
count=0
for i in ss.values():
    count+=int(i*(i-1)/2)
print(count)

import collections
N = int(input())
ls, rst = [], 0
for i in range(N):
    s = list(input())
    s.sort()
    ls.append(''.join(s))
rst_ls = collections.Counter(ls)
for i in rst_ls.values():
    if i >= 2:
        rst += i * (i - 1) // 2
print(rst)

n=int(input())
l=[]

for i in range(n):
  l.append(sorted(input()))

l.sort()

clst=[]
cnt=0
for i in range(len(l)-1):
  if l[i]==l[i+1]:
    cnt+=1
    if i == len(l)-2:
      clst.append(cnt)
  else:
    if cnt > 0:
      clst.append(cnt)
    cnt=0

ans=0
for x in clst:
  ans+=(1+x)*x//2 
print(ans)

from collections import Counter
N = int(input())
s = [str(sorted(input())) for _ in range(N) ]
c = Counter(s)
cnt = []

for i in list(c.values()):
    cnt.append(i * (i -1)//2)
print((sum(cnt)))



n = int(input())

count = 0
sn = {}
for i in range(n):
  s = list(input())
  check = "".join(sorted(s)) 
  if not check in sn:
    sn[check] = 1
  else :
    count += sn[check]
    sn[check] += 1
    
print(count)   

import math
import collections
import itertools
import copy

def YesNo(Bool):
    if(Bool):
        print("YES")
    else:
        print("NO")
    return


def resolve():

    N=int(input())
    tmp={}

    ans=0
    for i in range(N):
        S=list(input())
        S.sort()
        Ssort=''.join(S)
        if(Ssort in tmp):
            tmp[Ssort]+=1
        else:
            tmp[Ssort]=1

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

    print(ans)

resolve()



import collections

from scipy.special import comb


n = int(input())
aa = []

for i in range(n):
  s = sorted(input())
  s = [''.join(s)]
  aa.append(*s)

cc = collections.Counter(aa)
c = [c[1] for c in cc.items() if c[1] >1]

ans = 0
for i in range(len(c)):
  ans += comb(c[i], 2, exact=True)
  

print(int(ans))

from collections import defaultdict

dd = defaultdict(int)
n = int(input())
ans = 0
for _ in range(n):
    m = list(input())
    m.sort()
    tmp = "".join(m)
    ans += dd[tmp]
    dd[tmp] += 1
print(ans)


import collections

n = int(input())
abc = []

for i in range(n):
  a = list(input())
  a.sort()
  a = str(a)
  abc.append(a)

c = collections.Counter(abc)
cnt = 0

for i in c:
  num = c[i]
  if num != 1:
    cnt += num*(num-1) // 2
 
print(cnt)

import collections
N = int(input())
ls = []
rst = 0
for i in range(N):
    s = list(input())
    s.sort()
    ls.append(''.join(s))
rst_cnt = collections.Counter(ls)
for i in rst_cnt.values():
    rst += i * (i - 1) // 2
print(rst)

N=int(input())
ans=0
li=[]
for i in range(N):
    s=list(input())
    s.sort()
    li.append(s)
li.sort()
temp=1
for j in range(N-1):
    if li[j]==li[j+1]:
        temp+=1
    else:
        ans+=temp*(temp-1)//2
        temp=1
        
ans+=temp*(temp-1)//2
print(ans)


from collections import Counter

# 入力 (各文字列をソートしておく)
N = int(input())
S = [''.join(sorted(input())) for _ in range(N)]

# Counter でヒストグラムに
num = Counter(S)

# 各文字列ごとに個数 x を扱う
result = sum(x * (x - 1) // 2 for x in num.values())
print(result)


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

    S = []
    d = {}
    ans = 0
    for _ in range(N):
        t = input()
        t = "".join(sorted(t))
        if t in d:
            ans += d[t]
            d[t] += 1
        else:
            d[t] = 1

    print(ans)

def __starting_point():
    main()
__starting_point()

from collections import defaultdict
N=int(input())
charl=[]
ans=0
for _ in range(N):
    charl.append(''.join(sorted(input())))
anad=defaultdict(int)
for char in charl:
    anad[char]+=1
for anadv in anad.values():
    if anadv>1:
        ans+=anadv*(anadv-1)//2
print(ans)

n=int(input())
howmany={}
cou=0
for i in range(n):
  s=input()
  sen=[c for c in s]
  sen.sort()
  a=''.join(sen)
  if a in howmany:
    howmany[a]+=1
    cou+=howmany[a]
  else:
    howmany[a]=0
print(cou)

import collections

n = int(input())
s = [''.join(sorted(list(input()))) for _ in range(n)]

c = collections.Counter(s)
print(sum([i*(i-1)//2 for i in c.values()]))

import math
N = int(input())
S = [list(map(str, input())) for _ in range(N)]
S.sort()
for s in S:
    s.sort()

ans = 0

dic = {}

SS = []

for s in S:
    SS.append("".join(s))

for i in range(N):
    if SS[i] in dic:
        dic[SS[i]] += 1
    else:
        dic[SS[i]] = 1

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

print(ans)

def anagram(s):
    dic = {}
    for moji in s:
        dic.setdefault(moji,0)
        dic[moji]+=1
    sort_list = sorted(dic)
    #print(sort_list)
    ans = ''
    for moji in sort_list:
        ans += moji + str(dic[moji])
    return ans

n = int(input())
s = []
ans_dic = {}
for i in range(n):
    s.append(anagram(str(input())))
    ans_dic.setdefault(s[i],0)
    ans_dic[s[i]] += 1
#print(ans_dic)
ans = 0
for val in ans_dic.values():
    ans += val * (val - 1) //2
print(ans)

from collections import Counter


def mapt(fn, *args):
    return tuple(map(fn, *args))


def Input():
    return mapt(int, input().split(" "))


def main():
    k = int(input())
    a = sorted(["".join(sorted(input())) for _ in range(k)])
    d = Counter(a)
    return int(sum(val*(val-1)/2 for val in d.values()))



print(main())

import collections as c
print(sum(i*(i-1)//2 for i in c.Counter(''.join(sorted(input())) for _ in range(int(input()))).values()))

import math
def comb(n, r):
  if n-r>=0:
    return math.factorial(n) // (math.factorial(n - r) * math.factorial(r))
  else:
    return 0
    
n=int(input())
l=[]
for i in range(n):
  s=sorted(input())
  l.append(s)
l.sort()
cnt=1
ans=0

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

import collections
N = int(input())
ls = []
rst = 0
for i in range(N):
    s = list(input())
    s.sort()
    ls.append(''.join(s))
rst_cnt = collections.Counter(ls)
for i in rst_cnt.values():
    rst += i * (i - 1) // 2
print(rst)

N=int(input())
d={}
c=0
for i in range(N):
    s=''.join(sorted(input()))
    if s in d:
        c+=d[s]
        d[s]+=1
    else:
        d[s]=1
print(c)

N = int(input())
s = [input() for i in range(N)]
t = sorted(map(sorted,s))
count = 0
ans = 0
for i in range(N-1):
    if(t[i] == t[i+1]):
        count += 1
    else:
        ans += (count*(count+1))//2
        count = 0
if(count > 0):
    ans += (count*(count+1))//2
print(ans)

from collections import Counter

N = int(input())
s = [input() for _ in range(N)]
 
# N=10^5より、O(N)で解く
# ソート（さらに扱いやすくするため、文字列に直す）することで、文字分布を得る
for i in range(N):
  s[i] = ''.join(sorted(s[i]))

# 文字分布が同じになる組み合わせの個数を求めればよい
# 各文字分布の出現個数nに対して、nC2の和を取る
s = Counter(s).most_common()
ans = 0
for p in s:
  ans += p[1] * (p[1]-1) // 2
  
print(ans)

import math

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

n = int(input())
d = dict()
for _ in range(n):
    s = "".join(sorted([c for c in input()]))
    d[s] = d.get(s, 0) + 1

ans = 0
for v in d.values():
    if v >= 2:
        ans += c(v, 2)
print(ans)

import sys
import math


inint = lambda: int(sys.stdin.readline())
inintm = lambda: map(int, sys.stdin.readline().split())
inintl = lambda: list(inintm())
instrm = lambda: map(str, sys.stdin.readline().split())
instrl = lambda: list(instrm())

n = inint()

z = {():0}
ans = 0

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

for i in range(n):
    c = [0]*123
    s = input()
    for j in range(len(s)):
        c[ord(s[j])] += 1
    try:
        z[tuple(c)] += 1
    except:
        z[tuple(c)] = 1

for i in z:
    ans += combinations(z[i],2)

print(ans)

import collections
def resolve():
    n = int(input())
    words = []
    for _ in range(n):
        words.append(str(sorted(list(input()))))
    a = collections.Counter(words)
    ans = 0
    for i in a.values():
        ans += i*(i-1)//2
    print(ans)
resolve()

import itertools,math
n = int(input())
word = [input() for _ in range(n)]
count = 0

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

for i in range(n):
    word[i] = sorted(word[i])

new_word = list(sorted(word))

x = 1

for i in range(n-1):
    if new_word[i] == new_word[i+1]:
        x += 1
    elif x >= 2:
        count += combinations_count(x,2)
        x = 1
if x >= 2:
    count +=  combinations_count(x,2)

print(count)

from collections import Counter
import math

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

n=int(input())
l=["".join(sorted(input())) for i in range(n)]
c=Counter(l).most_common()
ans=0
for i in range(len(c)):
    if c[i][1]>=2:
        ans+=combinations_count(c[i][1],2)
print(ans)

N=int(input())
P=[]
for i in range(N):
    s=input()
    s=sorted(s)
    P.append(s)

P=sorted(P)
last=P[0]
cnt=0
ans=0
for i in range(1,N):
    if P[i]==last:
        cnt+=1
        ans+=cnt
    else:
        last=P[i]
        cnt=0
print(ans)

n=int(input())
s={}
ans=0
for i in range(n):
    a=tuple(sorted(input()))
    if a in s:
        s[a]+=1
    else:
        s[a]=1
for i in s.values():
    ans+=((i*(i-1))//2)
print(ans)

n = int(input())
s = sorted([sorted(input()) for _ in range(n)])
ans = 0
x = 0
i = 0
while x < n-1:
    cnt = 1
    for i in range(x, n-1):
        if s[i] == s[i+1]:
            cnt += 1
            x = i+1
        else:
          x = i+1
          break
    ans += (cnt*(cnt-1))/2
print(int(ans))

import collections
N=int(input())
S = collections.Counter([''.join(sorted(input())) for i in range(N)])
print(sum(map(lambda x: x*(x-1)//2, S.values())))

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

ans = 0
cnt = collections.Counter(s)
for i in cnt.values():
    if i > 1:
        ans += i*(i-1)//2

print(ans)

from math import factorial
n = int(input())
s = [input() for i in range(n)]
d = {}
for i in s:
    x = "".join(sorted(list(i)))
    if x not in d:
        d[x] = 1
    else:
        d[x] += 1
ans = 0
for i in d:
    if d[i] >= 2:
        ans += factorial(d[i]) // (factorial(d[i]-2)*2)
print(ans)

from collections import Counter
N = int(input())
s = [str(sorted(input())) for _ in range(N)]
c = Counter(s)

cnt = []
for i in list(c.values()):
    cnt.append(i * (i - 1)//2)
print((sum(cnt)))


N = int(input())

ans = 0
d = {}

for i in range(N):
    txt = "".join(sorted(input()))
    d.setdefault(txt,0)
    
    ans += d[txt]
    d[txt] += 1
    
print(ans)

from collections import defaultdict,Counter

N = int(input())
S = [str(input())for _ in range(N)]
D = defaultdict(int)

for s in S:
  cur = sorted(s)
  cur = "".join(map(str,cur))
  D[cur] += 1
cnt = 0
for c in D.values():
  cnt += c*(c-1)//2
ans = cnt
print(ans)

import collections
N = int(input())
s = ["".join(sorted(input())) for _ in range(N)]
s.sort()
C = collections.Counter(s)
D = C.most_common()

ans = 0
for i in D:
    ans += i[1]*(i[1] - 1)//2
print(ans)

#他の人の回答
import collections

N = int(input())
s = ["".join(sorted(input())) for _ in range(N)]
#sortedでリストになった文字列をjoinでもう一度文字列に
c = collections.Counter(s)
#cは辞書の形をとる
ans = 0

# sから重複を無くす
for si in set(s):
    n = c[si]
    ans += n * (n - 1) // 2 
    # n C 2を計算
print(ans)


import sys
import math
from collections import defaultdict, deque, Counter
from copy import deepcopy
from bisect import bisect, bisect_right, bisect_left
from heapq import heapify, heappop, heappush
    
input = sys.stdin.readline
def RD(): return input().rstrip()
def F(): return float(input().rstrip())
def I(): return int(input().rstrip())
def MI(): return map(int, input().split())
def MF(): return map(float,input().split())
def LI(): return list(map(int, input().split()))
def TI(): return tuple(map(int, input().split()))
def LF(): return list(map(float,input().split()))
def Init(H, W, num): return [[num for i in range(W)] for j in range(H)]
    
    
def main():
    N = I()
    L = []
    for i in range(N):
        temp = input().rstrip()
        temp = sorted(temp)
        L.append("".join(temp))
    L.sort()
    ans = 0
    index = 0
    temp_index = 0

    while True:
        while index+1 < N and L[index+1] == L[index]:
            index+=1
            temp_index+=1
        ans += (temp_index+1)*temp_index // 2
        temp_index=0
        index+=1
        if index >= N-1:
            break
    print(ans)
    
def __starting_point():
    main()
__starting_point()

import collections as c

n = int(input())
s = []
ans = 0

for i in range(n):
    t = list(input())
    t.sort()
    t = str(t)
    s.append(t)

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

from collections import Counter

N = int(input())
s_list = []
for i in range(N):
    s = input()
    s_min = sorted(s)
    s_min_join = "".join(s_min)
    s_list.append(s_min_join)

s_list_c = Counter(s_list)

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

print(ans) 

import sys
import math
from collections import defaultdict, deque, Counter
from copy import deepcopy
from bisect import bisect, bisect_right, bisect_left
from heapq import heapify, heappop, heappush
    
input = sys.stdin.readline
def RD(): return input().rstrip()
def F(): return float(input().rstrip())
def I(): return int(input().rstrip())
def MI(): return map(int, input().split())
def MF(): return map(float,input().split())
def LI(): return list(map(int, input().split()))
def TI(): return tuple(map(int, input().split()))
def LF(): return list(map(float,input().split()))
def Init(H, W, num): return [[num for i in range(W)] for j in range(H)]
    
    
def main():
    N = I()
    L = []
    for i in range(N):
        temp = input().rstrip()
        temp = [ord(temp[i]) - 97 for i in range(10)]
        temp.sort()
        L.append(temp)
    for i in range(9, -1, -1):
        L.sort(key = lambda x:x[i])
    ans = 0
    index = 0
    temp_index = 0

    while True:
        while index+1 < N and L[index+1] == L[index]:
            index+=1
            temp_index+=1
        ans += (temp_index+1)*temp_index // 2
        temp_index=0
        index+=1
        
        if index >= N-1:
            break
        
    print(ans)
    
def __starting_point():
    main()
__starting_point()

import collections
N = int(input())
ls, rst = [], 0
for i in range(N):
    s = list(input())
    s.sort()
    ls.append(''.join(s))
rst_dic = collections.Counter(ls)
for i in rst_dic.values():
    if i >= 2:
        rst += i * (i - 1) // 2
print(rst)

n = int(input())
s = {}
for _ in range(n):
  t = "".join(sorted(input()))
  if t not in s: s[t] = 1
  else: s[t] += 1

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

import sys
input = sys.stdin.readline
from collections import defaultdict


def read():
    N = int(input().strip())
    S = []
    for i in range(N):
        S.append(input().strip())
    return N, S


def solve(N, S):
    words = defaultdict(int)
    for s in S:
        key = "".join(list(sorted(s)))
        words[key] += 1
    
    ans = 0
    for key in words:
        n = words[key]
        if n >= 2:
            ans += n * (n-1) // 2
    return ans


def __starting_point():
    inputs = read()
    print(("%s" % solve(*inputs)))

__starting_point()

N = int(input())
M = [input() for i in range(N)]
 
M_sorted = [''.join(sorted(m)) for m in M]
d = {}
ans = 0
 
for m in M_sorted :
    d.setdefault(m,0)
    ans += d[m]
    d[m] += 1
 
print(ans)

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

ans = 0
for i in range(n):
    x = "".join(sorted(input()))
    if x not in s:
        s[x] = 1
    else:
        ans += s[x]
        s[x] += 1

print(ans)


from collections import Counter


def main():
    n = int(input())
    cnt = Counter()
    ans = 0
    for i in range(n):
        s = "".join(sorted(input()))
        if cnt[s] == 0:
            cnt[s] = 1
        else:
            ans += cnt[s]
            cnt[s] += 1
    print(ans)


def __starting_point():
    main()

__starting_point()

n = int(input())
count = 0
x = {}

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

import collections
import math
n=int(input())
s=[input() for i in range(n)]

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

c=collections.Counter(s)

a=0

for i in c.values():
    if i>1:
        a+=i*(i-1)//2

print(a)

N = int(input())
cnt = {}

for _ in range(N):
    s = ''.join(sorted(input(), key=str.lower))
    if s in cnt:
        cnt[s] += 1
    else:
        cnt[s] = 1

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

print(res)

import sys
import math


inint = lambda: int(sys.stdin.readline())
inintm = lambda: map(int, sys.stdin.readline().split())
inintl = lambda: list(inintm())
instrm = lambda: map(str, sys.stdin.readline().split())
instrl = lambda: list(instrm())

n = inint()

z = {}
ans = 0

for i in range(n):
    s = "".join(sorted(input()))
    try:
        z[s] += 1
    except:
        z[s] = 1

for i in z:
    ans += z[i]*(z[i]-1)//2

print(ans)

import sys
input = sys.stdin.readline
lis = {}
counter = 0
N = int(input().rstrip())
for i in range(N):
  str = "".join(sorted(list(input().rstrip())))
  if str in lis:
    lis[str] += 1
    counter += lis[str]
  else:
    lis[str] = 0
print(counter)