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

S = input()[::-1]

cnt = [0] * 2019
cnt[0] = 1
total = 0
x = 1
ans = 0

for a in S:
    total += int(a) * x
    total %= 2019
    cnt[total] += 1
    x = x*10

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

print(ans)

### FIXED CODE ###

s=input()
n=len(s)
mod=2019
d=0
p=1
ml=[0]*mod
for i in range(1,n+1):
  k=int(s[-i])
  d+=p*k
  d%=mod
  ml[d]+=1
  p*=10
  p%=mod
ans=0
for i in ml:
  ans+=i*(i-1)//2
print(ans+ml[0])
### BUGGY CODE ###

h,w,m = map(int,input().split())
b = []
x = [0 for _ in range(w)]
y = [0 for _ in range(h)]
for i in range(m):
  bh,bw = map(int,input().split())
  bh -= 1
  bw -= 1
  b.append((bh,bw))
  x[bw] += 1
  y[bh] += 1
#print(b,x,y)

mxx = max(x)
mxy = max(y)
xb = []
for i in range(w):
  xb.append((x[i],i))
xb.sort(reverse = True)
yb = []
for i in range(h):
  yb.append((y[i],i))
yb.sort(reverse = True)
#print(xb,yb)

for xbi,i in xb:
  if xbi < mxx:
    break
  for ybi,j in yb:
    if ybi < mxy:
      continue
    else:
      if (j,i) not in b:
        print(xbi+ybi)
        exit()
print(mxx+mxy-1)

### FIXED CODE ###

h,w,m = map(int,input().split())
b = []
x = [0 for _ in range(w)]
y = [0 for _ in range(h)]
for i in range(m):
  bh,bw = map(int,input().split())
  bh -= 1
  bw -= 1
  b.append((bh,bw))
  x[bw] += 1
  y[bh] += 1
#print(b,x,y)

mxx = max(x)
mxy = max(y)

cmxb = 0
for by,bx in b:
  if y[by]+x[bx] == mxx+mxy:
    cmxb += 1
cmxx = 0
for xi in x:
  if xi == mxx:
    cmxx += 1
cmxy = 0
for yi in y:
  if yi == mxy:
    cmxy += 1
#print(cmxb,cmxx,cmxy)

if cmxb == cmxx*cmxy:
  print(mxx+mxy-1)
else:
  print(mxx+mxy)
### BUGGY CODE ###

import copy

n = int(input())
x = [int(i) for i in input().split()]
sortedx = copy.copy(x)
sortedx.sort()

m = {}
mid = int(n/2)-1

for i in x:
    if i in m:
        print(m[i])
    else:
        temp = copy.copy(sortedx)
        temp.remove(i)
        print(temp[mid])
        m[i] = temp[mid] 


### FIXED CODE ###

import copy

n = int(input())
x = [int(i) for i in input().split()]
sortedx = copy.copy(x)
sortedx.sort()

m = sortedx[int((n+1)/2)]

for i in x:
    if i < m:
        print(sortedx[int(n/2)])
    else:
        print(sortedx[int(n/2-1)])
### BUGGY CODE ###

N, K = map(int, input().split())
listp = tuple(map(int, input().split()))
listans1 = []
for n in range(N-K+1):
    b = sum(listp[n:n+K])
    listans1.append(b)
#print(listans1) 
print((max(listans1)+K)/2)

### FIXED CODE ###

N, K = map(int, input().split())
listp = tuple(map(int, input().split()))
bc =sum(listp[0:K])
b = sum(listp[0:K])
for n in range(1,N-K+1):
    b = b - listp[n-1]+listp[n+K-1]
    
    if b > bc:
        bc = b
    else:
        pass    
    #print(b)    
print((bc+K)/2)
### BUGGY CODE ###

import numpy as np

n = int(input())
#nums = np.zeros(2001, dtype=int)

ls = map(int, input().split(" "))
ls = sorted(ls)
#for l in ls:
#    nums[l] += 1    

#ls = list(ls)
ls = np.asarray(ls)
out = 0
for i in range(n-1):
    a = ls[i]
    for j in range(i+1, n-1):
        b = ls[j]
        cur_ls = ls[j+1:]
        #print(cur_ls, a+b)
        cur_num = (cur_ls < a+b).sum()
        out += cur_num

print(out)        

### FIXED CODE ###

#from collections import Counter

#import numpy as np

input = raw_input
n = int(input())
#nums = np.zeros(2001, dtype=int)
nums = [0] * 2001
#nums = np.zeros(2001, dtype=int)

ls = map(int, input().split(" "))
#ls = Counter(map(int, ls))
#vals = ls.keys()
ls = sorted(ls)
for l in ls:
    #print(l)
    nums[l] += 1

set_vals = [val for val in range(2001) if nums[val] >= 1]
#print(vals)

#cumsum = np.cumsum(nums)

#print(set_vals)
len_set = len(set_vals)
out = 0
for i in range(len_set):
    val1 = set_vals[i]
    num_i = nums[val1]
    if num_i >= 3:
        out += (num_i * (num_i-1) * (num_i-2) // 6)
    
    if num_i >= 2:
        val2 = set_vals[i]
        for j in range(i+1, len_set):
            val3 = set_vals[j]
            num_h = nums[val3]
            if 2 * val1 <= val3:
                break

            out += ((num_i * (num_i-1)) // 2) * num_h

    for j in range(i+1, len_set):
        val2 = set_vals[j]
        num_j = nums[val2]

        if num_j >= 2:
            out += (num_i *  num_j * (num_j - 1) // 2 )

        for h in range(j+1, len_set):
            val3 = set_vals[h]
            #print(val1, val2, val3)
            num_h = nums[val3]
            if val1 + val2 <= val3:
                break

            #print("num", num_i, num_j, num_h)
            out += (num_i * num_j * num_h)

print(out)
### BUGGY CODE ###

from sys import stdin
input = stdin.readline


def main():
    n, m = map(int, input().split())

    nexts = [[] for i in range(n)]
    
    for i in range(m):
        ai, bi = map(int, input().split())
        ai -= 1
        bi -= 1
        nexts[ai].append(bi)
        nexts[bi].append(ai)

    scores = [m] * m
    scores[0] = 0

    red_set = [0]
    new_red_set = []
    blue_set = [x + 1 for x in range(n - 1)]
    new_blue_set = blue_set

    arrows = [0] * n

    while len(blue_set) != 0:
        for r in red_set:
            for nxt in nexts[r]:
                if nxt in blue_set:
                    new_blue_set.remove(nxt)
                    if nxt not in new_red_set:
                        new_red_set.append(nxt)
                    arrows[nxt] = r
                blue_set = new_blue_set

        red_set = new_red_set
        new_red_set = []
    
    print("Yes")
    for arrow in arrows[1:]:
        print(arrow + 1)


if __name__ == "__main__":
    main()

### FIXED CODE ###

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


def main():
    n, m = map(int, input().split())

    nexts = [[] for i in range(n)]
    
    for _ in range(m):
        ai, bi = map(int, input().split())
        ai -= 1
        bi -= 1
        nexts[ai].append(bi)
        nexts[bi].append(ai)

    blues = [-1] * n # 1 is in blues
    blues[0] = 0 # 0 is not in blues
    checked = [0] * n

    red_deque = deque([0])

    while len(red_deque) > 0:
        rd = red_deque[0]
        red_deque.popleft()
        if checked[rd] == 0:
            checked[rd] = 1
            for nxt in nexts[rd]:
                if blues[nxt] == -1:
                    blues[nxt] = rd
                    red_deque.append(nxt)

    print("Yes")
    for blue in blues[1:]:
        print(blue + 1)
    

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

import math
import string
import itertools
import fractions
import heapq
import collections
import re
import array
import bisect
import sys
import random
import time
inf = 10**9


def main():
    k, s = map(int, input().split())

    c = 0
    for i in range(k+1):
        if i > s:
            break
        for j in range(k+1):
            if i + j > s:
                break
            for l in range(k + 1):
                if i + j + l > s:
                    break
                if i + j + l == s:
                    c += 1
                    # print(i, j, l)

    print(c)


if __name__ == '__main__':
    main()


### FIXED CODE ###

import math
import string
import itertools
import fractions
import heapq
import collections
import re
import array
import bisect
import sys
import random
import time
inf = 10**9


def main():
    k, s = map(int, input().split())

    c = 0
    for i in range(k+1):
        if i > s:
            break
        for j in range(k+1):
            if i + j > s:
                break
            if s-i-j <= k:
                c += 1

    print(c)


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

n = int(input())
a = list(map(int, input().split()))
q = int(input())
change = [list(map(int, input().split())) for i in range(q)]
sm = sum(a)
tmp = 0
for i in range(q):
    sm += a.count(change[i][0]) * (change[i][1] - change[i][0])
    print(sm)
    a = [change[i][1] if j == change[i][0] else j for j in a]

### FIXED CODE ###

import collections
n = int(input())
arr = list(map(int,input().split()))
cnt = collections.defaultdict(int)
for val in arr:
    cnt[val] += 1
sums = sum(arr)
q = int(input())
for _ in range(q):
    b, c = map(int,input().split())
    diff = (c-b)*(cnt[b])
    sums += diff
    print(sums)
    cnt[c] += cnt[b]
    cnt[b] = 0
### BUGGY CODE ###

n,k = map(int,input().split())
A = list(map(int,input().split()))

pre = 0
for i in range(n-k+1):
    tmp = 1
    for j in range(k):
        tmp*=A[i+j]
    if i>0:
        if pre<tmp:
            print('Yes')
        else:
            print('No')
    pre = tmp



### FIXED CODE ###

n,k = map(int,input().split())
A = list(map(int,input().split()))

for i in range(n-k):
    if A[i]<A[i+k]:
        print('Yes')
    else:
        print('No')
### BUGGY CODE ###

N=int(input())
L=list(map(int,input().split()))
X=sum([L[i]+(i+1)==(j+1)-L[j] for i in range(N-1) for j in range(i+1,N)])
print(X)

### FIXED CODE ###

def main():
    N=int(input())
    L=list(map(int,input().split()))
    L_i,L_j=[],[]
    L_memo = [0]*N
    cnt=0
    for i, j in enumerate(L):
        if i+j<N:
            L_memo[i+j]+=1
        if i-j>0:
            cnt+=L_memo[i-j]        
    print(cnt)
main()
### BUGGY CODE ###

import sys
sys.setrecursionlimit(10 ** 7)


N, Q = map(int, input().split())
AB = {i: [] for i in range(N)}
for _ in range(N - 1):
    a, b = map(int, input().split())
    AB[a - 1].append(b - 1)

X = [0] * N
for _ in range(Q):
    p, x = map(int, input().split())
    X[p - 1] += x


def recursive(p):
    for c in AB[p]:
        X[c] += X[p]
        recursive(c)


recursive(0)
print(" ".join(map(str, X)))



### FIXED CODE ###

import sys
sys.setrecursionlimit(10 ** 7)


N, Q = map(int, input().split())
AB = [[] for i in range(N + 1)]
for _ in range(N - 1):
    a, b = map(int, input().split())
    AB[a].append(b)

X = [0] * (N + 1)
for _ in range(Q):
    p, x = map(int, input().split())
    X[p] += x


def recursive(p):
    for c in AB[p]:
        X[c] += X[p]
        recursive(c)


recursive(1)
print(" ".join(map(str, X[1:])))
### BUGGY CODE ###

n = int(input())
arr = list()
for i in range(n):
    arr.append(input())

maxi = 0
s = set(arr)
res = list()
while True:
    flag = True
    x = ""
    if s:
        for i in s:
            if arr.count(i) >= maxi:
                x = i
                maxi = arr.count(i)
                flag = False
        if flag:
            break
        res.append(x)
        while x in arr:
            arr.remove(x)
    else:
        break
for i in sorted(res):
    print(i)



### FIXED CODE ###

from collections import defaultdict
N = int(input())
ans = dict()
for _ in range(N):
    k = str(input())
    if k in ans:
        ans[k]+=1
    else:
        ans.update({k:1})
groupedByValue = defaultdict(list)
for key, value in sorted(ans.items()):
    groupedByValue[value].append(key)
l = groupedByValue[max(groupedByValue)]
for i in l:
    print(i)
### BUGGY CODE ###

def BFS(K,path,N):
  """リストのリスト道順path,頂点の個数Nが与えられたとき, 頂点Kから各頂点までの距離をlistで返す"""
  dist=[-1]*N
  dist[K]=0
  que=[K]
  while que:
    label=que.pop(0)
    for i,c in path[label]:
      if dist[i]==-1:
        dist[i]=dist[label]+c
        que+=[i]
  return dist

N=int(input())
path=[ [] for i in range(N)]
for i in range(N-1):
  a,b,c=map(int,input().split())
  path[a-1]+=[[b-1,c]]
  path[b-1]+=[[a-1,c]]
Q,K=map(int,input().split())
xy=[list(map(int,input().split())) for i in range(Q)]
distance=BFS(K-1,path,N)
for i in range(Q):
  print(distance[xy[i][0]-1]+distance[xy[i][1]-1])


### FIXED CODE ###

from sys import stdin
input = stdin.readline
from collections import deque
def BFS(K,path,N):
  """リストのリスト道順path,頂点の個数Nが与えられたとき, 頂点Kから各頂点までの距離をlistで返す"""
  dist=[-1]*N
  dist[K]=0
  que=deque()
  que.append(K)
  while que:
    label=que.popleft()
    for i,c in path[label]:
      if dist[i]==-1:
        dist[i]=dist[label]+c
        que+=[i]
  return dist
 
N=int(input())
path=[ [] for i in range(N)]
for i in range(N-1):
  a,b,c=map(int,input().split())
  path[a-1]+=[[b-1,c]]
  path[b-1]+=[[a-1,c]]
Q,K=map(int,input().split())
xy=[list(map(int,input().split())) for i in range(Q)]
distance=BFS(K-1,path,N)
for i in range(Q):
  print(distance[xy[i][0]-1]+distance[xy[i][1]-1])
### BUGGY CODE ###

L, R = map(int, input().split())

minimum=2019
for i in range(L, R):
    for j in range(i+1, R+1):
        tmp = (i*j)%2019
        if minimum>tmp:
            minimum = tmp

print(minimum)

### FIXED CODE ###

L, R = map(int, input().split())

minimum=2019
z=0
for i in range(L, R+1):
    for j in range(i+1, R+1):
        tmp = (i*j)%2019
        if minimum>tmp:
            minimum = tmp
        if minimum==0:
            z=1
            break
    if z==1:
        break
    
print(minimum)
### BUGGY CODE ###

n = int(input())

A = list(map(int,input().split()))
ans = 1
for i in A:
    ans *= i

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

### FIXED CODE ###

n = int(input())

A = list(map(int,input().split()))
ans = 1
if 0 in A:
    print(0)
else:
    f = 0
    for i in A:
        ans *= i
        if ans > 10**18:
            print(-1)
            f = 1
            break
    if f == 0:
        print(ans)
### BUGGY CODE ###

# -*- coding: utf-8 -*-
 
## Library
 
import sys
from fractions import gcd
import math
from math import ceil,floor
import collections
from collections import Counter
import itertools
 
## input
 
# N=int(input())
# A,B,C,D=map(int, input().split())
# string = input()
# yoko = list(map(int, input().split()))
# tate = [int(input()) for _ in range(N)]
# N, M = map(int,input().split()) 
#    P = [list(map(int,input().split())) for i in range(M)]
 
N=int(input())
P = list(map(int, input().split()))

count = 1

for i in range(N):
    for j in range(i):
        if P[j] < P[i]:
            break
        if j == i-1:
            count += 1

print(count)

### FIXED CODE ###

# -*- coding: utf-8 -*-
 
## Library
 
import sys
from fractions import gcd
import math
from math import ceil,floor
import collections
from collections import Counter
import itertools
 
## input
 
# N=int(input())
# A,B,C,D=map(int, input().split())
# string = input()
# yoko = list(map(int, input().split()))
# tate = [int(input()) for _ in range(N)]
# N, M = map(int,input().split()) 
#    P = [list(map(int,input().split())) for i in range(M)]
 
N=int(input())
P = list(map(int, input().split()))

count = 1
min = P[0]

for i in range(1,N):
    if min > P[i]:
        count+=1
        min = P[i]

print(count)
### BUGGY CODE ###

s = input()
x, y = map(int, input().split())

mv = [len(e) for e in s.split("T")]
mv_x = mv[2::2]
mv_y = mv[1::2]

MAX = 8000


def solve_dp(li, start, end):
    l = len(li)
    dp = [[0] * (2 * MAX + 1) for _ in range(l + 1)]
    dp[0][start] = 1
    for i, e in enumerate(li, 1):
        for j in range(-MAX, MAX + 1):
            if -MAX <= j - e <= MAX:
                dp[i][j] |= dp[i-1][j-e]
            if -MAX <= j + e <= MAX:
                dp[i][j] |= dp[i-1][j+e]

    return dp[l][end]


bl_x = solve_dp(mv_x, mv[0], x)
bl_y = solve_dp(mv_y, 0, y)

if bl_x and bl_y:
    ans = "Yes"
else:
    ans = "No"

print(ans)


### FIXED CODE ###

s = input()
x, y = map(int, input().split())

mv = [len(e) for e in s.split("T")]
mv_x = mv[2::2]
mv_y = mv[1::2]


def solve_dp(li, start, end):
    l = len(li)
    mx = sum(li)

    if l == 0:
        return start == end

    left = start - mx
    right = start + mx

    if end > right or end < left:
        return 0

    dp = [[0] * (2 * mx + 1) for _ in range(l + 1)]
    dp[0][start] = 1
    for i, e in enumerate(li, 1):
        for j in range(left, right + 1):
            if left <= j - e <= right:
                dp[i][j] |= dp[i-1][j-e]
            if left <= j + e <= right:
                dp[i][j] |= dp[i-1][j+e]

    return dp[l][end]


bl_x = solve_dp(mv_x, mv[0], x)
bl_y = solve_dp(mv_y, 0, y)

if bl_x and bl_y:
    ans = "Yes"
else:
    ans = "No"

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

s = input()
t = input()

s_dict = {c:[] for c in s}
for i, c in enumerate(s):
  s_dict[c].append(i)

len_s = len(s)

ans = 0
prev_i = -1
for c in t:
  if c not in s_dict:
    ans = -1
    prev_i = -1
    break;
  else:
    if s_dict[c][-1] <= prev_i:
      ans += len_s 
      prev_i = min(i for i in s_dict[c])
    else:
      prev_i = min(i for i in s_dict[c] if i > prev_i)


print(ans + prev_i + 1)

### FIXED CODE ###

#14:20-


import bisect

s = input()
t = input()

s_dict = {c:[] for c in s}
for i, c in enumerate(s):
  s_dict[c].append(i)

len_s = len(s)

ans = 0
prev_i = -1
for c in t:
  if c not in s_dict:
    ans = -1
    prev_i = -1
    break;
  else:
    if s_dict[c][-1] <= prev_i:
      ans += len_s 
      prev_i = s_dict[c][0]
    else:
      prev_i = s_dict[c][bisect.bisect_right(s_dict[c], prev_i, lo=0, hi=len(s_dict[c]))]


print(ans + prev_i + 1)
### BUGGY CODE ###

def start_from(a, x):
  while a % x != 0:
    a += 1
  return a

def ends_with(b, x):
    while b % x != 0:
        b -= 1
    return b

def main():
  a, b, x = map(int, raw_input().split())
  start = start_from(a, x) / x
  end = ends_with(b, x) / x
  print(end-start+1)


main()

### FIXED CODE ###

def start_from(a, x):
  while a % x != 0:
    a += x - a % x
  return a

def ends_with(b, x):
    while b % x != 0:
        b -= b % x
    return b

def main():
  a, b, x = map(int, raw_input().split())
  start = start_from(a, x) / x
  end = ends_with(b, x) / x
  print(end-start+1)


main()
### BUGGY CODE ###

import sys
from math import ceil, floor
from collections import deque, Counter, defaultdict
from fractions import gcd
input = lambda: sys.stdin.readline().rstrip()

def eprint(s):
    sys.stderr.write('DEBUG: {}'.format(s))
    return

def main():
    n,a,b = map(int, input().split())
    q = deque()

    while len(q) < n:
        for i in range(a):
            q.append('Blue')
        for i in range(b):
            q.append('Red')
    
    blue = 0
    for i in range(n):
        if q[i] == 'Blue':
            blue += 1
    print(blue)
    return

if __name__ == '__main__':
    main()

### FIXED CODE ###

import sys
from math import ceil, floor
from collections import deque, Counter, defaultdict
from fractions import gcd
input = lambda: sys.stdin.readline().rstrip()

def eprint(s):
    sys.stderr.write('DEBUG: {}'.format(s))
    return

def main():
    n,a,b = map(int, input().split())

    # k = n // (a+b): 完璧にループがおわったぶん
    # ここにあるBlueはa*k
    # n -( k*(a+b)) : 端数
    # ここにあるBlueはmin(n-(k*(a+b)), a)
    k = n // (a+b)
    eprint(k)
    eprint(min(n-(k*(a+b)), a))
    print(a*k + min(n-(k*(a+b)), a))
    return 

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

N,M = map(int,input().split())
import time
start_t = time.time()
path = [[] for _ in range(N*3+3)]
for _ in range(M):
    u,v = map(int,input().split())
    path[u].append(v)

S,T = map(int,input().split())
import collections

q = collections.deque()
vis = [[-1 for _ in range(3)] for _ in range(N+3)]
vis[S][0] = 1
q.append([S,0])
while q:
    now,cnt = q.popleft()
    step = cnt % 3
    vis[now][step] = cnt
    if now == T and step  == 0:  
        print(cnt//3)
        exit()
    for x in path[now]:
        if vis[x][(step+1)%3] < 0:
            q.append((x,cnt+1))
print(-1)
exit()



### FIXED CODE ###

N,M = map(int,input().split())
import time
start_t = time.time()
path = [[] for _ in range(N+3)]
for _ in range(M):
    u,v = map(int,input().split())
    path[u].append(v)

S,T = map(int,input().split())
import collections

q = collections.deque()
vis = [[-1 for _ in range(3)] for _ in range(N+3)]
vis[S][0] = 1
q.append([S,0])
while len(q):
    now,cnt = q.popleft()
    step = cnt % 3
    for x in path[now]:
        if vis[x][(step+1)%3] < 0:
            vis[x][(step+1)%3] = cnt
            q.append((x,cnt+1))

if vis[T][0] == -1:
    print(-1)
else:
    print(vis[T][0]//3+1)
### BUGGY CODE ###

import sys, os 
sys.setrecursionlimit(10**8)
#resource.setrlimit(resource.RLIMIT_STACK, (2**29,-1))

read = lambda : sys.stdin.readline().rstrip('\n')
tint = lambda x: [int(x) for x in x.split()]
inf = float('inf')

def main():
    n, k = tint(read())
    stones = tint(read())
    dp = [inf]*n
    dp[0] = 0
    for i in range(n):
        for t in range(1, min(n, k+1)):
            if i+t < n:
                dp[i+t] = min(dp[i+t], dp[i]+abs(stones[i]-stones[i+t]))
    print(dp[-1])

if __name__ == '__main__':    
    main()


### FIXED CODE ###

def main():
    n, k = map(int, input().split())
    h = tuple(map(int, input().split()))
    INF = 10 ** 9
    dp = [INF] * n
    dp[0] = 0
    for i in range(n):
        for j in range(1, k + 1):
            i_j = i + j
            if i_j < n:
                x = dp[i] + abs(h[i] - h[i_j])
                if dp[i_j] > x:
                    dp[i_j] = x
    print(dp[-1])


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

N, M = map(int, input().split())
List = [list(map(int, input().split())) for _ in range(M)]

ones = [1]*N

for i in range(M):
    ones[List[i][1]:]=[0]*(N-List[i][1])
    ones[:List[i][0]-1]=[0]*(List[i][0]-1)
    
print(sum(ones))

### FIXED CODE ###

N, M = map(int, input().split())
List = [list(map(int, input().split())) for _ in range(M)]

left = 1
right = N
for i in range(M):
    if left<List[i][0]:
        left = List[i][0]
    if List[i][1]<right:
        right = List[i][1]

if right<left:
    print(0)
else:
    print(right-left+1)
### BUGGY CODE ###

def main():
    N = int(input())
    words = [ "".join(sorted(list(input()))) for i in range(N)]
    w = set(words)

    pair = 0
    for word in w:
        c = words.count(word)
        if c >= 2:
            pair += c*(c-1)//2
    
    print(pair)

if __name__ == "__main__":
    main()

### FIXED CODE ###

from collections import defaultdict
def main(): 
    N = int(input())
    words = [ "".join(sorted(list(input()))) for i in range(N)]
    w = defaultdict(int)

    for word in words:
        w[word] += 1
        
    pair = 0
    for k, v in w.items():
        if v >= 2:
            pair += v*(v-1)//2
    
    print(pair)

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

#!/usr/bin/env python3
# coding=utf-8

import sys

import numpy as np

n, k = map(int, sys.stdin.readline().strip().split(" "))
xyc = [l.strip().split(" ") for l in sys.stdin.readlines()]
xy = [tuple((int(_x), int(_y) if _c == "W" else int(_y) + k)) for (_x, _y, _c) in xyc]
xy = [tuple((_x % (2 * k), _y % (2 * k))) for (_x, _y) in xy]

ans = np.zeros((2 * k, 2 * k), dtype=np.int32)
for _x, _y in xy:
    check = np.zeros((2 * k, 2 * k), dtype=np.int32)
    check[_x:_x + k] = 1
    if _x > k:
        check[:_x - k] = 1
    check[:, _y:_y + k] = 1 - check[:, _y:_y + k]
    if _y > k:
        check[:, :_y - k] = 1 - check[:, :_y - k]
    check = 1 - check
    ans += check
print(np.max(ans))

### FIXED CODE ###

import numpy as np
N, K = map(int, input().split())
ub = K * 2
b = [[0 for j in range(ub + 1)] for i in range(ub + 1)]
ADD = {"B": 0, "W": K}


def create_bound(p, K, ub):
    if p - K + 1 >= 0:
        return [(p - K + 1, p + 1)]
    else:
        return [(0, p + 1), ((p - K + 1) % ub, ub)]


for i in range(N):
    x, y, c = input().split()
    nx = int(x) % ub
    ny = (int(y) + ADD[c]) % ub
    for add in [0, K]:
        for xlb, xub in create_bound((nx + add) % ub, K, ub):
            for ylb, yub in create_bound((ny + add) % ub, K, ub):
                b[xlb][ylb] += 1
                b[xlb][yub] -= 1
                b[xub][ylb] -= 1
                b[xub][yub] += 1

b_arr = np.array(b)
for i in range(ub):
    b_arr[i + 1, :] += b_arr[i, :]
for j in range(ub):
    b_arr[:, j + 1] += b_arr[:, j]
print(b_arr.max())
### BUGGY CODE ###

def makedic(str1):
    dic = {}
    for s in str1:
        if s in dic:
            dic[s] += 1
        else:
            dic[s] = 1
    #print(dic)
    return dic

N = int(input())
S = [makedic(input()) for _ in range(N)]

ans = 0
for i in range(N):
    for j in range(i+1,N):
        if S[i] == S[j]:
        #if S[i] == S[j]:
            ans += 1
print(ans)



### FIXED CODE ###

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

dic = {}
ans = 0
for s in S:
    sortstr = str(sorted(s))
    if sortstr in dic:
        ans += dic[sortstr]
        dic[sortstr] += 1
    else:
        dic[sortstr] = 1
print(ans)