Harryxun/sft_time huggingface dataset:
### BUGGY CODE ###

N=int(input())
s=[]
an=0
for i in range(N):
    s.append([x for x in input()])
    s[i].sort()
i=0
while i<N:
    y=1
    n=i+1
    while n<N:
        if s[i]==s[n]:
            y+=1
            del s[n]
            N-=1
        else:
            n+=1
    i+=1
    an+=int((y*(y-1)/2))
print(an)

### FIXED CODE ###

from collections import defaultdict
x=defaultdict(int)
N=int(input())
for i in range(N):
    x[''.join(sorted(input()))]+=1
an=0
for i in x.values():
    an+=int(i*(i-1)/2)
print(an)
### BUGGY CODE ###

def main():
     s=input()
     ans=[0 for i in range(len(s))]
     for i in range(len(s)):
          ini=s[i]
          now=i
          if ini=='R':
               move=1
          else:
               move=-1
          while s[now]==ini:
               now+=move
               
          if abs(now-i)%2==1:
               now-=move
          ans[now]+=1
     print(" ".join(list(map(str,ans))))
     
     
if __name__ == '__main__':
     main()

### FIXED CODE ###

def main():
     dic={'R':+1,'L':-1}
     s=input()
     ans=[0 for i in range(len(s))]
     ini_pre=None
     for i in range(len(s)):
          if i==0 or ini!=s[i]:
               ini=s[i]
               now=i
               move=dic[ini]
               while s[now]==ini:
                    now+=move
               if abs(now-i)%2==1:
                    ans[now-move]+=1
               else:
                    ans[now]+=1
          elif ini==s[i]:
               if abs(now-i)%2==1:
                    ans[now-move]+=1
               else:
                    ans[now]+=1
     print(" ".join(list(map(str,ans))))
     
     
if __name__ == '__main__':
     main()
### BUGGY CODE ###

N, K = map(int, input().split())
p = list(map(int, input().split()))
cnt = list(map(lambda x : x * 0.5 + 0.5, p))

ans = []
x = 0
y = K
while len(cnt[x:y]) == K:
    ans.append(sum(cnt[x:y]))
    x += 1
    y += 1

print(max(ans))

### FIXED CODE ###

N, K = map(int, input().split())
cnt = [int(x) * 0.5 + 0.5 for x in input().split()]

add = [0]
for i in cnt:
    add.append(add[-1]+i)

ans = [add[i+K]-add[i] for i in range(N-K+1)]

print(max(ans))
### BUGGY CODE ###

import sys
input = sys.stdin.buffer.readline

N,Q = map(int,input().split())
BIT = [0]*(N+1)

def BIT_query(idx):
    res_sum = 0
    while idx > 0:
        res_sum += BIT[idx]
        idx -= idx&(-idx)
    return res_sum

def BIT_update(idx,x):
    while idx <= N:
        BIT[idx] += x
        idx += idx&(-idx)
    return

c = [0]+list(map(int,input().split()))
lastAppeared = [-1]*(N+1)
ans = [0]*Q
queries = []
for q in range(Q):
    l,r = map(int,input().split())
    queries.append(r*10**12+l*10**6+q)
queries.sort()

curR = 0
for i in range(Q):
    query = queries[i]
    r = query//10**12
    query %= 10**12
    l = query//10**6
    q = query % 10**6
    for R in range(curR+1,r+1):
        color = c[R]
        last = lastAppeared[color]
        if last != -1:
            BIT_update(last,-1)
        lastAppeared[color] = R
        BIT_update(R,1)
    ans[q] = BIT_query(r)-BIT_query(l-1)
for i in range(Q):
    print(ans[i])


### FIXED CODE ###

N,Q = map(int,input().split())
BIT = [0]*(N+1)

def BIT_query(idx):
    res_sum = 0
    while idx > 0:
        res_sum += BIT[idx]
        idx -= idx&(-idx)
    return res_sum

def BIT_update(idx,x):
    while idx <= N:
        BIT[idx] += x
        idx += idx&(-idx)
    return

c = [-1]+list(map(int,input().split()))
lastAppeared = [-1]*(N+1)
ans = [0]*Q
queries = []
for q in range(Q):
    l,r = map(int,input().split())
    queries.append((l,r,q))
queries.sort(key = lambda x:x[1])

curR = 0
for i in range(Q):
    l,r,q = queries[i]
    while curR < r:
        curR += 1
        new = c[curR]
        last = lastAppeared[new]
        if last != -1:
            BIT_update(last,-1)
        lastAppeared[new] = curR
        BIT_update(curR,1)
    ans[q] = BIT_query(r)-BIT_query(l-1)
for i in range(Q):
    print(ans[i])
### BUGGY CODE ###

int1 = lambda x: int(x) - 1
import sys
sys.setrecursionlimit(1000000000)

N, M = map(int, input().split())

edge = [[0]*N for _ in range(N)]
to_point = [[] for _ in range(N)]

for _ in range(M):
    x, y = map(int1, input().split())
    edge[x][y] += 1
    to_point[x].append(y)

end_point = set()
for x in range(N):
    if len(to_point[x]) == 0:
        end_point.add(x)

start_point = set()
for y in range(N):
    for x in range(N):
        if edge[x][y] > 0:
            break
    else:
        start_point.add(y)

# 点i始点のLongest Pathの長さ
def dp(i):
    if i in end_point:
        return 0
    else:
        lp = 0
        for j in to_point[i]:
            lp = max(lp, dp(j)+1)
        return lp

ans = 0
for x in start_point:
    ans = max(ans, dp(x))

print(ans)

### FIXED CODE ###

import sys
input = sys.stdin.buffer.readline
sys.setrecursionlimit(1000000000)

int1 = lambda x: int(x) - 1

N, M = map(int, input().split())

to_point = [[] for _ in range(N)]

for _ in range(M):
    x, y = map(int1, input().split())
    to_point[x].append(y)

dp_memo = [-1]*N
for x in range(N):
    if len(to_point[x]) == 0:
        dp_memo[x] = 0

# 点i始点のLongest Pathの長さ
def dp(i):
    if dp_memo[i] >= 0:
        return dp_memo[i]
    lp = 0
    for j in to_point[i]:
        lp = max(lp, dp(j)+1)
    dp_memo[i] = lp
    return lp

for i in range(N):
    dp(i)

print(max(dp_memo))
### BUGGY CODE ###

N = int(input())
A = list(map(int,input().split()))
 
def gcd(a,b):
    a,b = max(a,b),min(a,b)
    while a%b!=0:
        a,b = b,a%b
    return b

mod = 10**9 + 7

l = A[0]
for i in range(1,N):
    l = (A[i]//gcd(A[i],l))*l


ans = 0
for i in range(N):
    ans+=l//A[i]
    ans%=mod
    
print(ans)

### FIXED CODE ###


N = int(input())
A = list(map(int,input().split()))

mod = 10**9 + 7

from collections import defaultdict

B = [defaultdict(int) for i in range(N)]
C = defaultdict(int)

for x in range(N):
    a = A[x]
    for i in range(2,int(a**0.5)+1):
        while a%i==0 and a>0:
            B[x][i]+=1
            a//=i
            #print(a)
            C[i]=max(C[i],B[x][i])
    #print(a)
    if a>1:
        B[x][a]+=1
        C[a] = max(C[a],B[x][a])
#print(B,C)
l = 1
for key in C:
    l*=pow(key,C[key],mod)
    l%=mod

ans = 0
for i in range(N):
    b = l
    for key in B[i]:
        c = pow(key,B[i][key],mod)
        b *= pow(c,mod-2,mod)
    ans+=b
    ans%=mod

print(ans)
### BUGGY CODE ###

import math
from functools import reduce

def gcd(*numbers):
    return reduce(math.gcd, numbers)

def gcd_list(numbers):
    return reduce(math.gcd, numbers)
k=int(input())
ans=0
for i in range(1,k+1):
  for u in range(1,k+1):
    for y in range(1,k+1):
      ans+=gcd(i,u,y)
print(ans)



### FIXED CODE ###

import math
from functools import reduce

def gcd(*numbers):
    return reduce(math.gcd, numbers)

def gcd_list(numbers):
    return reduce(math.gcd, numbers)
k=int(input())
ans=0
for i in range(1,k+1):
  for u in range(1,k+1):
    for y in range(1,k+1):
      ans+=gcd(i,u,y)
print(ans)
### BUGGY CODE ###

n,k = map(int,input().split())
s = list(input())
 
l0 = []
l1 = []
pred = s[0]
if s[0] == "0":
    l0.append(1)
    l1.append(0)
else:
    l1.append(1)
 
for i in range(1,n):
    if pred == s[i]:
        if s[i] == "0":
            l0[-1] += 1
        else:
            l1[-1] += 1
    else:
        if s[i] == "0":
            l0.append(1)
        else:
            l1.append(1)
    pred = s[i]
if s[-1] == "0":    
    l1.append(0)

ans = 0
if k >= len(l0):
    print(n)
else:
    nl1 = len(l1)
    for i in range(nl1-k):
        ans = max(ans,(sum(l0[i:i+k])+sum(l1[i:i+k+1])))
    print(ans)

### FIXED CODE ###

n,k = map(int,input().split())
s = list(input())
 
l0 = []
l1 = []
pred = s[0]
if s[0] == "0":
    l0.append(1)
    l1.append(0)
else:
    l1.append(1)
 
for i in range(1,n):
    if pred == s[i]:
        if s[i] == "0":
            l0[-1] += 1
        else:
            l1[-1] += 1
    else:
        if s[i] == "0":
            l0.append(1)
        else:
            l1.append(1)
    pred = s[i]
if s[-1] == "0":    
    l1.append(0)
 
ans = sum(l0[:k])+sum(l1[:k+1])
tmp = ans
for i in range(k,min(len(l0),len(l1))):
    tmp -= l0[i-k]
    tmp -= l1[i-k]
    tmp += l0[i]
    tmp += l1[i+1]
    ans = max(ans, tmp)
print(ans)
### BUGGY CODE ###

N = int(input())
l = sorted(list(map(int, input().split())))

from bisect import bisect_left, bisect_right

kumi = set()
for i in range(N):
    a = l[i]
    for j in range(i, N):
        if i == j:
            continue
        b = l[j]
        start = bisect_right(l, max(a,b)-min(a,b))
        end = bisect_left(l, a+b)
        for c in l[start:end]:
            if c == a or c == b:
                continue
            kumi.add(tuple(sorted([a,b,c])))
print(len(kumi))

### FIXED CODE ###

N = int(input())
l = sorted(list(map(int, input().split())))
 
from bisect import bisect_left

cnt = 0
for i in range(N):
    a = l[i]
    for j in range(i+1, N):
        b = l[j]
        cnt += bisect_left(l[j+1:], a+b)
print(cnt)
### BUGGY CODE ###

import numpy as np
def main():
  N, K = map(int, input().split())
  A = list(map(int, input().split()))

  def CalExVal(x):
      return (1/2*(x+1))
  Ex = np.array(list((map(CalExVal, A))))
  temp = len(A)-K + 1
  #adjlist = [0]*(temp)
  adjlist = [np.sum(Ex[i:(K+i)]) for i in range(temp)]
  #for i in range(temp):
  #    adjlist[i] = sum(Ex[i:(K+i)])

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

### FIXED CODE ###

def main():
  def CalExVal(x):
    return (1/2*(x+1))
  N, K = map(int, input().split())
  A = list(map(int, input().split()))


  Ex = list((map(CalExVal, A)))
  #temp = len(A)-K + 1
  #adjlist = [0]*(temp)
  #adjlist = [sum(list(map(CalExVal, A))[i:(K+i)]) for i in range(temp)]
  tem = sum(Ex[:K])
  res = tem
  for i in range(0,N-K):
      tem = tem - Ex[i] + Ex[i+K]
      if res < tem:
      	res = tem
  print(res)
if __name__ == '__main__':
    main()
### BUGGY CODE ###

import math
N, K = map(int, input().split())
As = sorted(list(map(int, input().split())))
Bs = sorted(list(map(int, input().split())))[::-1]
Cs = [a*b for a, b in zip(As, Bs)]
BCs = list(zip(Bs, Cs))

def func(target):
    r = 0
    for b, c in BCs:
        r += math.ceil(max(0, c - target) / b)
    return r <= K

if __name__ == '__main__':
    min_i, max_i, index = -1, max(Cs)+1, 1
    while True:
        if func(index):
            index, max_i = (index-1 + min_i)//2, index-1
            continue
        index, min_i = (index+1 + max_i)//2, index+1
        if min_i > max_i:
            print(min_i)
            break

### FIXED CODE ###

import math
N, K = map(int, input().split())
As = sorted(list(map(int, input().split())))
Bs = sorted(list(map(int, input().split())))[::-1]
Cs = [a*b for a, b in zip(As, Bs)]
BCs = list(zip(Bs, Cs))

def func(target):
    r = 0
    for b, c in BCs:
        r += math.ceil(max(0, c - target) / b)
    return r <= K

if __name__ == '__main__':
    min_i, max_i, index = 0, max(Cs)+1, 1
    while True:
        if func(index):
            index, max_i = (index-1 + min_i)//2, index-1
        else:
            index, min_i = (index+1 + max_i)//2, index+1
        if min_i > max_i:
            print(min_i)
            break
### BUGGY CODE ###


from collections import Counter
import numpy as np

N = int(input())
A = np.array(list(map(int, input().split())))
A_set = np.unique(A)
count_dict= Counter(A)
count_sum = np.sum([count_dict[i]*(count_dict[i]-1)/2 for i in A_set])
    
for i in A:
    print(int(count_sum-(np.count_nonzero(A==i)-1)))

### FIXED CODE ###


from collections import Counter
import numpy as np

N = int(input())
A = np.array(list(map(int, input().split())))
A_set = np.unique(A)
count_dict= Counter(A)
count_sum = np.sum([count_dict[i]*(count_dict[i]-1)/2 for i in A_set])

out = [int(count_sum-count_dict[i]+1) for i in A]
for i in out:
    print(i)
### BUGGY CODE ###

n, k = map(int, input().split())
A = [int(a) for a in input().split()]
Jump = [None] * n
Jump[0] = 1
next = 0
for i in range(1,n+1):
    to = A[next]
    if to in Jump:
        start = Jump.index(to)
        end = i
        dis = end - start

        roop = (k-start) % dis
        print(Jump[start+roop])
        break

    Jump[i] = to
    next = to-1
    if i ==k:
        print(to)
        break


### FIXED CODE ###

n, k = map(int, input().split())
A = [int(a) for a in input().split()]
Jump = [None] * n
Jump[0] = 1
Rireki = [-1] * (n+1)
Rireki[0] = 0
next = 0
for i in range(1,n+1):
    to = A[next]

    if Rireki[to] >= 0:
        start = Jump.index(to)
        end = i
        dis = end - start

        roop = (k-start) % dis
        print(Jump[start+roop])
        break
    Rireki[to] = i
    Jump[i] = to
    next = to-1
    if i ==k:
        print(to)
        break
### BUGGY CODE ###

A, B, N = map(int, input().split())

tmp = 0
for i in range(B - 1, N + 1, B):
    tmp = max((A * i) // B - A * (i // B), tmp)
    
for i in range(N, N - N % B - 1, -1):
    tmp = max((A * i) // B - A * (i // B), tmp)

print(tmp)



### FIXED CODE ###

global A, B
A, B, N = map(int, input().split())

def f(num):
    return(A * num) // B - A * (num // B)

print(f(min(B - 1, N)))
### BUGGY CODE ###

def main():
  if 'get_ipython' not in globals():  
    # For Subsession
    N,K = map(int, input().split())
    S = input()
  else:
    # For Test
    # N = 5
    # K = 1
    # S = "00010"
    N = 14
    K = 2
    S = "11101010110011"
    # N = 1
    # K = 1
    # S = "1"
    
  SC = []
  i = 0
  if S[0] == "0":SC.append(0)
  while i < N:
    if S[i] == "0":
      cnt = -1
      i += 1
      while i < N:
        if S[i] == "0":
          cnt -= 1
          i += 1
        else:
          break
    else:
      cnt = 1
      i += 1
      while i < N:
        if S[i] == "1":
          cnt += 1
          i += 1
        else:
          break
    SC.append(cnt)
    
  if 'get_ipython' in globals(): print(SC)
    
  i = 0
  lenSC = len(SC) - 1
  ans = 0
  while i <= lenSC:
    if SC[i] >= 0:
      cnt = 0
      k = i + K * 2
      if k > lenSC:
        k = lenSC
      for j in range(i,k + 1):
        cnt += abs(SC[j])
      if ans < cnt:
        ans = cnt
    i += 2

  print(ans)

main()

### FIXED CODE ###

import sys
def main():
  if 'get_ipython' not in globals():  
    # For Subsession
    N,K = map(int, input().split())
    S = sys.stdin.readline()
  else:
    # For Test
    # N = 5
    # K = 1
    # S = "00010"
    # N = 14
    # K = 2
    # S = "11101010110011"
    # N = 1
    # K = 1
    # S = "1"
    N = 5
    K = 1
    S = "11111"
    
  SC = []
  i = 0
  if S[0] == "0":SC.append(0)
  while i < N :
    if S[i] == "0":
      j = S.find("1",i)
    else:
      j = S.find("0",i)
    if j == -1: j = N 
    cnt = j - i
    i = j
    SC.append(cnt)
    
  if 'get_ipython' in globals(): print(SC)
    
  SH = []
  cnt = 0
  for i in range(len(SC)):
    cnt += SC[i]
    SH.append(cnt)
  
  if 'get_ipython' in globals(): print(SH)
  
  lenSC = len(SC) - 1
  ans = 0
  for i in range(0,lenSC+1,2):
    k = i + K * 2
    if k > lenSC:
      k = lenSC
    if i != 0:
      cnt = SH[k] - SH[i-1]
    elif k == i:
      cnt = SH[k]
    else:
      cnt = SH[k] - SH[i]
    if ans < cnt: ans = cnt

  print(ans)

main()
### BUGGY CODE ###


def resolve():
    N = int(input())
    A = list(map(int, input().split()))

    dp = [[0] * (N+1) for _ in range(N+1)]
    # 左側をとる: 区間 [i+1,j)[i+1,j) に遷移
    # 右側をとる: 区間 [i,j−1)[i,j−1) に遷移
    for L in range(1, N + 1):
        i = 0
        while i + L <= N:
            j = i + L
            # 先手番
            if (N - L) % 2 == 0:
                dp[i][j] = max(dp[i + 1][j] + A[i], dp[i][j - 1] + A[j - 1])
            # 後手番
            else:
                dp[i][j] = min(dp[i + 1][j] - A[i], dp[i][j - 1] - A[j - 1])
            i += 1

    print(dp[0][N])


if __name__ == "__main__":
    resolve()

### FIXED CODE ###


def resolve():
    N = int(input())
    A = list(map(int, input().split()))

    dp = [[0] * (N+1) for _ in range(N+1)]
    # 左側をとる: 区間 [i+1,j)[i+1,j) に遷移
    # 右側をとる: 区間 [i,j−1)[i,j−1) に遷移
    for L in range(1, N + 1):
        i = 0
        while i + L <= N:
            j = i + L
            # 先手番
            if (N - L) % 2 == 0:
                dp[i][j] = max(dp[i + 1][j] + A[i], dp[i][j - 1] + A[j - 1])
            # 後手番
            else:
                dp[i][j] = min(dp[i + 1][j] - A[i], dp[i][j - 1] - A[j - 1])
            i += 1

    print(dp[0][N])


if __name__ == "__main__":
    resolve()
### BUGGY CODE ###

n = int(input())
s = list(input() for _ in range(n))
ss = sorted(list(set(s)))
dpl = []
for i in ss:
    dpl.append(s.count(i))
for j in range(len(dpl)):
    if dpl[j] == max(dpl):
        print(ss[j])

### FIXED CODE ###

n = int(input())
dic = {}
for _ in range(n):
    s = input()
    if s in dic:
        dic[s] += 1
    else:
        dic[s] = 1
mv = max(dic.values())
for s, v in sorted(dic.items()):
    if v == mv:
        print(s)
### BUGGY CODE ###

def main():
    import sys
    sys.setrecursionlimit(10**6)
    input = sys.stdin.readline
    N = int(input())
    for h in range(1, 3501):
        if 1 / h > 4 / N:
            continue
        for n in range(h, 3501):
            if 1 / h + 1 / n > 4 / N:
                continue
            l = 1
            r = 3500
            # print(h, n)
            while l + 1 < r:
                m = (l + r) // 2
                p = N * ((n * m + h * m + h * n) / (h * n * m))
                if p == 4:
                    print(h, n, m)
                    return True
                elif p < 4:
                    r = m
                else:
                    l = m

if __name__ == '__main__':
    main()

### FIXED CODE ###

def main():
    import sys
    sys.setrecursionlimit(10**6)
    input = sys.stdin.readline
    N = int(input())
    for h in range(1, 3501):
        if N >= 4 * h:
            continue
        for n in range(h, 3501):
            if N * (h + n) >= 4 * h * n:
                continue
            t1 = N * h * n
            t2 = 4 * h * n - N * n - N * h
            if t1 % t2 == 0:
                print(h, n, t1 // t2)
                return True

if __name__ == '__main__':
    main()
### BUGGY CODE ###

def u(a,b):
  if(a<b):
    z = b
    b = a
    a = z
  r = a % b
  while(r!=0):
    a = b
    b = r
    r = a % b
  return b
 
l = int(input())
s = 0
for i in range(1,l+1):
  for i2 in range(1,l+1):
    z = u(i,i2)
    for i3 in range(1,l+1):
      z2 = u(z,i3)
      s+=z2
print (s)

### FIXED CODE ###

def u(a,b):
  if(a<b):
    z = b
    b = a
    a = z
  r = a % b
  while(r!=0):
    a = b
    b = r
    r = a % b
  return b
 
l = int(input())
s = 0
for i in range(1,l+1):
  for i2 in range(1,l+1):
    z = u(i,i2)
    for i3 in range(1,l+1):
      z2 = u(i3,z)
      s+=z2
print (s)
### BUGGY CODE ###

n = int(input())
a = list(map(int,input().split()))
from operator import mul
from functools import reduce
ans = (reduce(mul,a))

if ans > 10**18:
    print(-1)
else:
    print(ans)

### FIXED CODE ###

n = int(input())
a = list(map(int,input().split()))
ans = a[0]
for i in range(n-1):
    ans *= a[i+1]
    if ans > 10**18:
        break
if 0 in a:
    print(0)
elif ans > 10**18:
    print(-1)
else:
    print(ans)
### BUGGY CODE ###

n=int(input())
ln=[int(a) for a in input().split()]
ln.sort(reverse=True)
sum1=0
for i in range(n):
    sum1+=ln[1]
    del ln[0:2]
print(sum1)

### FIXED CODE ###

n=int(input())
ln=[int(a) for a in input().split()]
ln.sort(reverse=True)
print(sum(ln[1:n*2:2]))
### BUGGY CODE ###

import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines
import numpy as np

n,k = map(int,readline().split())
if k == 1:
  print(0)
  exit()
  
a = np.array([0]+[int(i) for i in readline().split()])
np.cumsum(a,out=a)
  
a = [(ai-i)%k for i,ai in enumerate(a)]

from collections import Counter,deque
c = Counter({a[0]:1})
d = deque([a[0]])
ans = 0
cnt = 1
for j,aj in enumerate(a[1:]):
  ans += c[aj]
  d.append(aj)
  c.update({aj:1})
  cnt += 1
  if cnt >= k:
    p = d.popleft()
    c.update({p:-1})
  
print(ans)

### FIXED CODE ###

import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

n,k = map(int,readline().split())
if k == 1:
  print(0)
  exit()
  
a = [0]+[int(i) for i in readline().split()]
for i in range(1,n+1):
  a[i] = a[i-1]+a[i]
  
a = [(ai-i)%k for i,ai in enumerate(a)]
#print(a)
from collections import Counter,deque
c = Counter({a[0]:1})
d = deque([a[0]])
ans = 0
cnt = 1
for j,aj in enumerate(a[1:]):
  ans += c[aj]
  d.append(aj)
  c.update({aj:1})
  cnt += 1
  if cnt >= k:
    p = d.popleft()
    c.update({p:-1})
  
print(ans)
### BUGGY CODE ###

import sys
input = sys.stdin.readline

def main():
    N = int(input())
    s = []
    for i in range(N):
        s.append("".join(sorted(list(input().strip()))))
    s = sorted(s)

    ans = 0
    for i in range(N-1):
        for j in range(i+1, N):
            ok = True
            for k in range(10):
                if s[i][k] != s[j][k]:
                    ok = False
                    break
            if ok:
                ans += 1
    print(ans)

if __name__ == "__main__":
    main()

### FIXED CODE ###

import sys
input = sys.stdin.readline

def main():
    N = int(input())
    s = []
    for i in range(N):
        s.append("".join(sorted(list(input().strip()))))
    s = sorted(s)
    # print(s)
    tmp = []
    pre = s[0]
    count = 1
    for i in range(1, N):
        if s[i] == pre:
            count += 1
        else:
            if count > 1:
                tmp.append(count)
            count = 1
        if i == N-1:
            if count > 1:
                tmp.append(count)
        pre = s[i]
    ans = 0
    for n in tmp:
        ans += (n * (n-1))//2
    print(ans)


if __name__ == "__main__":
    main()