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

import fileinput


class Cache():
    def __init__(self, total):
        self._total = total + 1

        self._arr = [-1] * (self._total**3)

    def get(self, n_1, n_2, n_3):
        return self._arr[n_1 + n_2 * self._total + n_3 * self._total * self._total]

    def add(self, n_1, n_2, n_3, val):
        self._arr[n_1 + n_2 * self._total + n_3 * self._total * self._total] = val

def num_turns(total, n_1, n_2, n_3, cache):
    if cache.get(n_1, n_2, n_3) != -1:
        return cache.get(n_1, n_2, n_3)

    with_sushi = n_1 + n_2 + n_3

    if with_sushi == 0: return 0

    res = total / with_sushi

    if n_1 > 0:
        p = n_1 / with_sushi
        res += p * num_turns(total, n_1 - 1, n_2, n_3, cache)
    
    if n_2 > 0:
        p = n_2 / with_sushi
        res += p * num_turns(total, n_1 + 1, n_2 - 1, n_3, cache)

    if n_3 > 0:
        p = n_3 / with_sushi
        res += p * num_turns(total, n_1, n_2 + 1, n_3 - 1, cache)

    cache.add(n_1, n_2, n_3, res)
    return res

inp = fileinput.FileInput()
total = int(inp.readline())

n_1 = 0
n_2 = 0
n_3 = 0

for v in inp.readline().split(" "):
    v = int(v)
    if v == 1:
        n_1 += 1
    if v == 2:
        n_2 += 1
    if v == 3:
        n_3 += 1

print(num_turns(total, n_1, n_2, n_3, Cache(total)))

### FIXED CODE ###

import fileinput


def num_turns(total, n_1, n_2, n_3):
    _n_1 = n_1 + n_2 + n_3 + 1
    _n_2 = n_2 + n_3 + 1
    _n_3 = n_3 + 1

    _arr = [0.0] * (_n_1 * _n_2 * _n_3)

    for i_3 in range(n_3 + 1):
        for i_2 in range(n_2 + 1 + n_3 - i_3):
            for i_1 in range(n_1 + 1 + n_2 + n_3 - i_3 - i_2):
                with_sushi = i_1 + i_2 + i_3
                if with_sushi == 0:
                    continue
                expectation = total / with_sushi
                if i_1 > 0:
                    p = i_1 / with_sushi
                    expectation += p * _arr[(i_1 - 1) + i_2 * _n_1 + i_3 * _n_1 * _n_2]

                if i_2 > 0:
                    p = i_2 / with_sushi
                    expectation += p * _arr[i_1 + 1 + (i_2 - 1) * _n_1 + i_3 * _n_1 * _n_2]

                if i_3 > 0:
                    p = i_3 / with_sushi
                    expectation += p * _arr[i_1 + (i_2 + 1) * _n_1 + (i_3 - 1) * _n_1 * _n_2]
                _arr[i_1 + i_2 * _n_1 + i_3 * _n_1 * _n_2] = expectation

    return _arr[n_1 + n_2 * _n_1 + n_3 * _n_1 * _n_2]


inp = fileinput.FileInput()
total = int(inp.readline())

n_1 = 0
n_2 = 0
n_3 = 0

for v in inp.readline().split(" "):
    v = int(v)
    if v == 1:
        n_1 += 1
    if v == 2:
        n_2 += 1
    if v == 3:
        n_3 += 1

print(num_turns(total, n_1, n_2, n_3))
### BUGGY CODE ###

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

maxA = max(A) + 1

C = [0] * maxA

g = 0

for a in A:
    C[a] += 1
    g = math.gcd(g, a)

pairwise = True

for i in range(2, maxA):
    cnt = 0
    for j in range(i, maxA, i):
        cnt += C[j]

    if cnt > 1:
        pairwise = False

if pairwise:
    print("pairwise coprime")
    exit()

if g == 1:
    print("setwise coprime")

else:
    print("not coprime")

### FIXED CODE ###

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

maxA = max(A) + 1

C = [0] * maxA

g = 0

for a in A:
    C[a] += 1
    g = math.gcd(g, a)

pairwise = True

for i in range(2, maxA):
    cnt = 0
    for j in range(i, maxA, i):
        cnt += C[j]

    if cnt > 1:
        pairwise = False

if pairwise:
    print("pairwise coprime")
    exit()

if g == 1:
    print("setwise coprime")

else:
    print("not coprime")
### BUGGY CODE ###

n = int(input())
p = list(map(int, input().split()))
c = 0
for j in range(n):
  if p[j] == min(p[:j+1]):
    c += 1
print(c)

### FIXED CODE ###

n = int(input())
p = list(map(int, input().split()))
c = 0
m = n + 1
for i in p:
  if i < m:
    c += 1
    m = i
print(c)
### BUGGY CODE ###

def calc_cost2(h, k):
    if (len(h) == 0):
        return 0

    cost = [None] * len(h)
    cost[0] = 0
    for i in range(1, len(h)):
        cost[i] = cost[i-1] + abs(h[i] - h[i-1])
        for d in range(1, k+1):
            if i >= d:
                cost[i] = min(cost[i], cost[i-d] + abs(h[i] - h[i-d]))

    return cost[len(h)-1]

if __name__ == "__main__":
    n, k = list(map(int, input().split(" ")))
    h = list(map(int, input().split(" ")))
    res = calc_cost2(h, k)
    print(res)

### FIXED CODE ###

def calc_cost2(h, k):
    n = len(h)
    if (n == 0):
        return 0

    cost = n * [None]
    cost[0] = 0
    for i in range(1, len(h)):
        cost[i] = min([cost[s] + abs(h[i] - h[s]) for s in range(max(0, i-k), i)])
        #cost[i] = min(map(lambda s: cost[s] + abs(h[i] - h[s]), range(max(0, i-k), i)))

    return cost[n-1]


if __name__ == "__main__":
    n, k = list(map(int, input().split(" ")))
    h = list(map(int, input().split(" ")))
    res = calc_cost2(h, k)
    print(res)
### BUGGY CODE ###

def resolve():
    def Dijkstra(s, g):
        import heapq
        d = {s}
        queue = []
        for q in edge[s]:
            heapq.heappush(queue, q)
        while queue:
            dist, point = heapq.heappop(queue)
            q = [point]
            while q:
                point = q.pop()
                if point in d:
                    continue
                d.add(point)
                if point == g:
                    return dist
                for nextdist, nextp in edge[point]:
                    if not nextp in d:
                        if nextdist:
                            heapq.heappush(queue, (dist + 1, nextp))
                        else:
                            q.append(nextp)
        return -1
    import sys
    input = sys.stdin.readline
    from collections import defaultdict
    n, m = map(int, input().split())
    edge = defaultdict(set)
    for _ in range(m):
        p, q, c = map(int, input().split())
        p, q = p - 1, q - 1
        edge[(p, -1)].add((1, (p, c)))
        edge[(q, -1)].add((1, (q, c)))
        edge[(p, c)].add((0, (p, -1)))
        edge[(q, c)].add((0, (q, -1)))
        edge[(p, c)].add((0, (q, c)))
        edge[(q, c)].add((0, (p, c)))
    print(Dijkstra((0, -1), (n - 1, -1)))


if __name__ == '__main__':
    resolve()


### FIXED CODE ###

def resolve():
    def Dijkstra(s, g):
        from collections import deque
        d = {s}
        queue = deque()
        for q in edge[s]:
            queue.append((1, q))
        while queue:
            dist, point = queue.popleft()
            if point in d:
                continue
            d.add(point)
            if point == g:
                return dist
            for nextp in edge[point]:
                if not nextp in d:
                    if not -1 in point or -1 in nextp:
                        queue.appendleft((dist, nextp))
                    else:
                        queue.append((dist + 1, nextp))
        return -1
    import sys
    input = sys.stdin.readline
    from collections import defaultdict
    n, m = map(int, input().split())
    edge = defaultdict(set)
    for _ in range(m):
        p, q, c = map(int, input().split())
        p, q = p - 1, q - 1
        edge[(p, c)].add((q, c))
        edge[(q, c)].add((p, c))
        edge[(p, c)].add((p, -1))
        edge[(q, c)].add((q, -1))
        edge[(p, -1)].add((p, c))
        edge[(q, -1)].add((q, c))
    print(Dijkstra((0, -1), (n - 1, -1)))


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

N = int(input())
ans = 0
for i in range(1,N+1):
    for j in  range(1,N+1):
        if i%j == 0:
            ans += i
print(ans)

### FIXED CODE ###

n=int(input())
ans=0
for i in range(1,n+1): #各iについて、i*(1～n//iまでの総和)を足し合わせればよい
 k=n//i
 ans+=i*(k*(k+1)//2)
print(ans)
### BUGGY CODE ###

# B
n, k = map(int, input().split())
h = list(map(int, input().split()))
dp = [0]*(n+1)
 
for i in range(2, n+1):
    c_list = []
    if i-2 >= k:
        for j in range(1,k+1):
            c_list.append(dp[i-j] + abs(h[i-1-j] - h[i-1]))
    else:
        for j in range(1, i):
            c_list.append(dp[i-j] + abs(h[i-1-j] - h[i-1]))
    dp[i] = min(c_list)
print(dp[-1])

### FIXED CODE ###

# B
import numpy as np
N, K = map(int, input().split())
h = np.array(input().split(), dtype="int32")
dp = np.zeros(N, dtype="int32")
 
for i in range(1, N):
    if i < K:
        dp[i] = np.min(dp[:i] + np.abs(h[i]-h[:i]))
    else:
        dp[i] = np.min(dp[i-K:i] + np.abs(h[i]-h[i-K:i]))
print(dp[-1])
### BUGGY CODE ###

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

if N >=B:
    floor_num.append(int(A*(B-1)/B))
else:  
    for x in range(0,N+1):

        floor_num.append(int(A*x/B)-A*int(x/B))


print(max(floor_num))



### FIXED CODE ###

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


floor_num=[]

if N >=B:
    floor_num.append(int(A*(B-1)/B))
else:  

        floor_num.append(int(A*N/B))


print(max(floor_num))
### BUGGY CODE ###

N, K = map(int, input().split())
P = list(map(int, input().split()))
memo = P[:K]
ans = sum(memo)

for i in range(K, N):
    memo.pop(0)
    memo.append(P[i])
    tmp = sum(memo)
    if tmp > ans:
        ans = tmp

print(K-1+((ans-K+1) - 0.5*((ans-K+1)-1)))

### FIXED CODE ###

N, K = map(int, input().split())
P = list(map(int, input().split()))
memo = sum(P[:K])
ans = memo

for i in range(K, N):
    memo = memo - P[i-K] + P[i]
    ans = max(ans, memo)

print(K-1+((ans-K+1) - 0.5*((ans-K+1)-1)))
### BUGGY CODE ###

class UnionFind():
    def __init__(self, n):
        self.n = n
        self.parents = [-1] * n

    def find(self, x):
        if self.parents[x] < 0:
            return x
        else:
            self.parents[x] = self.find(self.parents[x])
            return self.parents[x]

    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)

        if x == y:
            return

        if self.parents[x] > self.parents[y]:
            x, y = y, x

        self.parents[x] += self.parents[y]
        self.parents[y] = x

    def size(self, x):
        return -self.parents[self.find(x)]

    def same(self, x, y):
        return self.find(x) == self.find(y)

    def members(self, x):
        root = self.find(x)
        return [i for i in range(self.n) if self.find(i) == root]
"""
    def roots(self):
        return [i for i, x in enumerate(self.parents) if x < 0]

    def group_count(self):
        return len(self.roots())

    def all_group_members(self):
        return {r: self.members(r) for r in self.roots()}

    def __str__(self):
        return '\n'.join('{}: {}'.format(r, self.members(r)) for r in self.roots())
"""
N,M,K = map(int,input().split())
F = UnionFind(N)
B = [set() for _ in range(N)]
FF = [0]*N
for _ in range(M):
    a,b = map(int,input().split())
    F.union(a-1,b-1)
    FF[a-1] += 1
    FF[b-1] += 1
# print(F)
for j in range(K):
    a,b = map(int,input().split())
    B[a-1].add(b-1)
    B[b-1].add(a-1)

Y = []
for i in range(N):
    y = F.size(i) - FF[i] -1
    for b in B[i]:
        if b in F.members(i):
            y += -1
    Y.append(str(y))
print(" ".join(Y))


### FIXED CODE ###

def find(x):
    if par[x]<0:
        return x
    else:
        par[x]=find(par[x])
        return par[x]
 
def unite(x,y):
  x,y=find(x),find(y)
  if x!=y:
    if x>y:
        x,y=y,x
    par[x]+=par[y]
    par[y]=x
    
def same(x,y):
  return find(x)==find(y)
 
def size(x):
  return-par[find(x)]
 
N,M,K = map(int,input().split())
par=[-1]*N
B = [set() for _ in range(N)]
FF = [0]*N
for _ in range(M):
    a,b = map(int,input().split())
    unite(a-1,b-1)
    FF[a-1] += 1
    FF[b-1] += 1
# print(F)
for j in range(K):
    a,b = map(int,input().split())
    B[a-1].add(b-1)
    B[b-1].add(a-1)

Y = []
for i in range(N):
    y = size(i) - FF[i] -1
    for b in B[i]:
        if same(i,b):
            y += -1
    Y.append(str(y))
print(" ".join(Y))
### BUGGY CODE ###

N, M = map(int, input().split())
A = list(map(int, input().split()))
A.sort()
ope = []
for _ in range(M):
  ope.append(list(map(int, input().split())))
for m in ope:
  for _ in range(m[0]):
    if m[1] > A[0]:
      A[0] = m[1]
      A.sort()
    else:
      break
print(sum(A))      


### FIXED CODE ###

N, M = map(int, input().split())
A = list(map(int, input().split()))
ans = 0
pool = []
[pool.append((a, 1)) for a in A]
for _ in range(M):
  b, c = (map(int, input().split()))
  pool.append((c, b))
pool.sort(reverse=True, key=lambda x:x[0])

while N>0:
  for p in pool:
    if p[1] >= N:
      ans += p[0]*N
      N = 0
    if p[1] < N:
      ans += p[0]*p[1]
      N -= p[1]

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

import math
import sys
input = sys.stdin.readline

N = int(input())
A = list(map(int, input().split()))
A.sort()
#A = [i for i in range(2, N+2)]

def is_prime(n):
  if n == 1:
    return False
  for i in range(2, int(math.sqrt(n)) + 1):
    if n % i == 0:
      return False
  return True

D = []
E = []

for i, x in enumerate(A):
  Flag = True
  
  if i >= 1 and x == D[-1]:
    E.append(x)
    continue

  if i >= 1 and D[0] != 1 and is_prime(x):
    D.append(x)
    continue
    
  for j in D:
    if x%j == 0:
      Flag = False
      if x == j:
        E.append(x)
      break
    
  if Flag:
    D.append(x)

print(len(set(D)-set(E)))

### FIXED CODE ###


import math
from collections import defaultdict

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

D = defaultdict(int)

AM = A[-1]
dp = [True]*(AM)

for x in A:
  if dp[x-1]:
    temp = 2 * x
    while temp <= AM:
      dp[temp-1] = False
      temp += x

for x in A:
  if dp[x-1]:
    D[x] += 1

ans = len([i for i in D if D[i] == 1])

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

n,q=map(int,input().split())
s=input()
lr=[]
for i in range(q):
    lr.append(list(map(int,input().split())))

for i in range(q):
    cnt=0
    S=s[lr[i][0]-1:lr[i][1]]
    for j in range(len(S)-1):
        if S[j]=="A" and S[j+1]=="C":
            cnt+=1
    print(cnt)


### FIXED CODE ###

n,q=map(int,input().split())
s=input()

ac=[0]*n
for i in range(n-1):
    ac[i+1]=ac[i]
    if s[i]=="A" and s[i+1]=="C":
        ac[i+1]+=1


lr=[]
for i in range(q):
    lr.append(list(map(int,input().split())))

for i in range(q):
    print(ac[lr[i][1]-1]-ac[lr[i][0]-1])
### BUGGY CODE ###

# key not available ""
import math
n, k = [int(i) for i in input().split()]
arr = [int(i) for i in input().split()]
dp = [0]*n
dp[0] = 0
for i in range(1, n):
    for j in range(1, k+1):
        if i-j >= 0:
            if j == 1:
                dp[i] = dp[i-1]+abs(arr[i]-arr[i-1])
            else:
                dp[i] = min(dp[i], dp[i-j]+abs(arr[i]-arr[i-j]))
print(dp[-1])


### FIXED CODE ###

# key not available ""
import sys
n, k = [int(i) for i in input().split()]
arr = [int(i) for i in input().split()]
dp = [sys.maxsize]*n
dp[0] = 0
for i in range(n):
    for j in range(i+1, i+k+1):
        if j < n:
            dp[j] = min(dp[j], dp[i]+abs(arr[i]-arr[j]))
print(dp[-1])
### BUGGY CODE ###



N, Q = map(int, input().split())
S = input()

for q in range(Q):
  s, t = map(int, input().split())
  print(S[s-1:t:1].count("AC"))

### FIXED CODE ###


N, Q = map(int, input().split())
S = input()

A = []

for n in range(N):
  if n == 0:
    A.append(0)
  elif S[n] == "C" and S[n-1] == "A":
    A.append(A[n-1] + 1)
  else:
    A.append(A[n-1])

A.insert(0, 0)

for i in range(Q):
  x, y = map(int, input().split())
  print(A[y] - A[x])
### BUGGY CODE ###

S = input()
list1 = []

for i in range(len(S)+1):
    for j in range(len(S)+1):
        if i<j and int(S[i:j])%2019==0:
            list1.append(1)
print(sum(list1))
  

### FIXED CODE ###

s = input()[::-1]
counts = [0] * 2019
counts[0] = 1
num, d = 0, 1
result = 0

for i in s:
    num += int(i) * d
    num %= 2019
    d *= 10
    d %= 2019
    counts[num] += 1
    
for cnt in counts:
    result += cnt*(cnt-1)//2
    
print(result)
### BUGGY CODE ###

import numpy as np

N = int(input())

spot = np.array(list(map(int, input().split())))

for i in range(N):
    temp = np.zeros(N)
    temp[1:] = np.delete(spot, i)
    print(int(np.abs(np.roll(temp, 1) - temp).sum()))

### FIXED CODE ###

import numpy as np
import math

N = int(input())

spot = np.zeros(N + 1)
spot[1:] = np.array(list(map(int, input().split())))

tot = int(np.abs(np.roll(spot, 1) - spot).sum())

for i in range(1, N+1):
    print(int(tot - math.fabs(spot[i] - spot[i-1]) - math.fabs(spot[(i+1) % (N+1)] - spot[i])\
            + math.fabs(spot[(i+1) % (N+1)] - spot[i-1])))
### BUGGY CODE ###

n, k = map(int, input().split())
h = list(map(int, input().split()))
a = [0] * n
a[0] = 0
for i in range(1, n):
    a[i] = min([a[j] + abs(h[i] - h[j]) for j in range(max(0, i - k), i)])
print(a[-1])


### FIXED CODE ###

def main():
    n, k = map(int, input().split())
    h = list(map(int, input().split()))
    a = [0] * n
    a[0] = 0
    for i in range(1, n):
        a[i] = min([a[j] + abs(h[i] - h[j]) for j in range(max(0, i - k), i)])
    print(a[-1])
 
if __name__ == '__main__':
    main()
### BUGGY CODE ###

import numpy as np
import sys
input = sys.stdin.readline
def IL(): return list(map(int,input().split()))
def SL(): return input().split()
def I(): return int(sys.stdin.readline())
def S(): return input()

def nibutan(n,list):
    left = 0
    right = len(list)
    while left+1 != right:
        middle = (left+right)//2
        if list[middle] <= n:
            left = middle
        else:
            right = middle
    return left+1

N,M,Q = IL()

l = [[] for i in range(N+1)]

for i in range(M):
    a,b = IL()
    l[a].append(b)

for i in l:
    i.sort()

for i in range(Q):
    cnt = 0
    start, end = IL()
    for j in range(start,end+1):
        if len(l[j]) == 0 or l[j][0] > end:
            continue
        elif l[j][-1] <= end:
            cnt += len(l[j])
        else:
            cnt += nibutan(end,l[j])
    print(cnt)

### FIXED CODE ###

import numpy as np
import sys
input = sys.stdin.readline
def IL(): return list(map(int,input().split()))
def SL(): return input().split()
def I(): return int(sys.stdin.readline())
def S(): return input()

def imos():
  for j in range(N+1):
    cnt = 0
    for i in range(N+1):
      tmp = l[j][i]
      l[j][i] += cnt
      cnt += tmp

  for j in range(N+1):
    cnt = 0
    for i in range(N+1):
      tmp = l[i][j]
      l[i][j] += cnt
      cnt += tmp

N,M,Q = IL()
l = [[0]*(N+1) for i in range(N+1)]
for i in range(M):
  a,b = IL()
  l[1][b] += 1
  if a+1 <= N:
    l[a+1][b] += -1

imos()

ans = [IL() for i in range(Q)]
for i in range(Q):
    print(l[ans[i][0]][ans[i][1]])
### BUGGY CODE ###

def bfs(s, t):
  q = [s]
  visited = []
  while len(q) > 0:
    v = q.pop(0)
    if v == t: return True
    if v not in visited and len(G[v]) > 0:
      q.extend(sorted(G[v]))
      visited.append(v)
  return False

u, n = map(int, input().split())
G = [[] for _ in range(u)]
for _ in range(n):
  a, b = map(int, input().split())
  if b not in G[a]: G[a].append(b)
  if a not in G[b]: G[b].append(a)

q = int(input())
for _ in range(q):
  s, t = map(int, input().split())
  if bfs(s, t):
    print("yes")
  else:
    print("no")

### FIXED CODE ###

def grouping(G):
  gid_list = [0] * len(G)

  gid = 1
  for i, _ in enumerate(G):
    if gid_list[i] > 0: continue
    q = [i]
    while len(q) > 0:
      v = q.pop(0)
      gid_list[v] = gid
      for v in sorted(G[v]):
        if gid_list[v] <= 0: q.append(v)
    gid += 1
  return gid_list

u, n = map(int, input().split())
G = [[] for _ in range(u)]
for _ in range(n):
  a, b = map(int, input().split())
  if b not in G[a]: G[a].append(b)
  if a not in G[b]: G[b].append(a)

gid_list = grouping(G)

q = int(input())
for _ in range(q):
  s, t = map(int, input().split())
  if gid_list[s] == gid_list[t]:
    print("yes")
  else:
    print("no")
### BUGGY CODE ###

import copy
import math

# a = get_int()
def get_int():
    return int(input())
# a = get_string()
def get_string():
    return input()
# a_list = get_int_list()
def get_int_list():
    return [int(x) for x in input().split()]
# a_list = get_string_list():
def get_string_list():
    return input().split()
# a, b = get_int_multi()
def get_int_multi():
    return map(int, input().split())
# a_list = get_string_char_list()
def get_string_char_list():
    return list(str(input()))
# print("{} {}".format(a, b))
# for num in range(0, a):
# a_list[idx]
# a_list = [0] * a
'''
while (idx < n) and ():

    idx += 1
'''

def main():
    n = get_int()
    s_list = get_string_char_list()
    ans_set = set([])

    for i in range(0,n):
        for ii in range(i+1, n):
            for iii in range(ii+1, n):
                ans_set.add(int(s_list[i]) * 100 + int(s_list[ii]) * 10 + int(s_list[iii]) * 1)

    print(len(ans_set))

if __name__ == '__main__':
    main()




### FIXED CODE ###

import copy
import math
import time

# a = get_int()
def get_int():
    return int(input())
# a = get_string()
def get_string():
    return input()
# a_list = get_int_list()
def get_int_list():
    return [int(x) for x in input().split()]
# a_list = get_string_list():
def get_string_list():
    return input().split()
# a, b = get_int_multi()
def get_int_multi():
    return map(int, input().split())
# a_list = get_string_char_list()
def get_string_char_list():
    return list(str(input()))
# print("{} {}".format(a, b))
# for num in range(0, a):
# a_list[idx]
# a_list = [0] * a
'''
while (idx < n) and ():

    idx += 1
'''

def main():
    start = time.time()

    n = get_int()
    s_list = get_string_char_list()
    s_list = [int(x) for x in s_list]

    #n = 30000
    #s_list = [1] * 30000

    #ans_set = set([])

    #for i in range(0,n):
    #    for ii in range(i+1, n):
    #        for iii in range(ii+1, n):
    #            ans_set.add(int(s_list[i]) * 100 + int(s_list[ii]) * 10 + int(s_list[iii]) * 1)

    #print(len(ans_set))

    ans = 0

    for i in range(0, 1000):
        a = i // 100
        b = (i % 100) // 10
        c = i % 10

        find_a = False
        find_b = False
        for ii in s_list:

            if (find_a == False) and (ii == a):
                find_a = True
            elif (find_a == True) and (find_b == False) and (ii == b):
                find_b = True
            elif (find_b == True) and (ii == c):

                ans += 1
                break
    print(ans)

    #print(time.time() - start)

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

L, R = map(int, input().split())
import numpy as np
min = 2019
for i in range(L, R+1):
    for j in range(i+1, R+1):
        if (i*j)%2019 < min:
            min = (i*j)%2019

print(min)

### FIXED CODE ###

L, R = map(int, input().split())
import numpy as np
LL = L%2019
RR = R%2019

min = 2019
if LL >= RR:
    min = 0
elif R-L >= 2018:
    min = 0
else:
    for i in range(LL, RR+1):
        for j in range(i+1, RR+1):
            if (i*j)%2019 < min:
                min = (i*j)%2019
            if (i*j)%2019 == 0:
                min = 0
                break
        else:
            continue
        break


print(min)
### BUGGY CODE ###

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

ans=[[0 for i in range(26)] for j in range(n)]
check="abcdefghijklmnopqrstuvwxyz"

for j in range(n):
    for i in range(26):
        ans[j][i]=s[j].count(check[i])

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

print(cnt)

### FIXED CODE ###

import math

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

std=[]
for i in range(n):
    std.append(sorted(s[i]))
stdx=[]
stdx=sorted(std)

cnt=0
k=1
for i in range(n-1):
    if stdx[i]==stdx[i+1]:
        k+=1
        if k>1 and i==n-2:
            cnt+=math.factorial(k)//math.factorial(k-2)//math.factorial(2)
    else:
        if k>1:
            cnt+=math.factorial(k)//math.factorial(k-2)//math.factorial(2)
            k=1

print(cnt)