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

from fractions import gcd

def main():
    A, B = [int(i) for i in input().split()]
    G = gcd(A, B)
    factor = set()
    i = 2
    while G != 1:
        while True:
            if G % i == 0:
                factor.add(i)
                G = G // i
            else:
                break
        i += 1
    print(len(list(factor))+1)


if __name__ == "__main__":
    main()

### FIXED CODE ###

from fractions import gcd
import copy


def coprime2(a, b):
    return gcd(a, b) == 1


def main():
    A, B = [int(i) for i in input().split()]

    A_l = divisor(A)
    B_l = divisor(B)
    AB_l = set()
    for a in A_l:
        if a in B_l:
            AB_l.add(a)
    AB_l = sorted(list(AB_l))
    tmp = set(AB_l)
    ans = []
    for i, a in enumerate(AB_l):
        if a not in tmp:
            continue
        try:
            tmp.remove(a)
        except:
            pass
        for b in list(tmp):
            if gcd(a, b) != 1:
                try:
                    tmp.remove(b)
                except:
                    pass
        else:
            ans.append(a)

    print(len(ans))


def divisor(n):
    i = 1
    table = set()
    while i * i <= n:
        if n % i == 0:
            table.add(i)
            table.add(n//i)
        i += 1
    return table


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

def main():
    s = input()
    q = int(input())
    for i in range(q):
        query = input().split()
        if query[0] == "1":
            s = s[::-1]
        else:
            if query[1] == "1":
                s = query[2] + s
            if query[1] == "2":
                s = s + query[2]
    print(s)



if __name__ == '__main__':
    main()


### FIXED CODE ###

def main():
    s = input()
    q = int(input())
    left = ""
    right = ""
    hanten = False
    for i in range(q):
        query = input().split()
        if query[0] == "1":
            hanten = not hanten
        else:
            c = query[2]
            if query[1] == "1":
                if not hanten:
                    left += c
                else:
                    right += c
            else:
                if not hanten:
                    right += c
                else:
                    left += c
        #print(query)
        #print(s,left,right)
    left = left[::-1]
    answer = left + s + right

    if not hanten:
        print(answer)
    else:
        print(answer[::-1])


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

n,m = map(int,input().split())

li = list(range(1,n+1))
for i in range(m):
  l,r = map(int,input().split())
  if li[len(li)-1] < l or r < li[0]:
    break
  li = list(range(max(min(li),l),min(max(li),r)+1))
else:
  print(len(li))
  exit()
print(0)

### FIXED CODE ###

n,m = map(int,input().split())

lans = 1
rans = n
for i in range(m):
  l,r = map(int,input().split())
  lans = max(lans,l)
  rans = min(rans,r)
if lans <= rans:
  print(len(list(range(lans,rans+1))))
else:
  print(0)
### BUGGY CODE ###

import bisect
n = int(input())
l = list(map(int, input().split()))
l.sort()
ans = 0
biSet = set()


for i in range(n):
    for j in range(i+1, n):
        length = l[i] + l[j]

        index = bisect.bisect_left(l[j+1:], length)
        #print(index)
        if index > 0:
            ans += index


print(ans)

### FIXED CODE ###

import bisect
n = int(input())
l = list(map(int, input().split()))
l.sort()
ans = 0
biSet = set()


for i in range(n):
    for j in range(i+1, n):
        length = l[i] + l[j]

        index = bisect.bisect_left(l[j+1:], length)
        #print(index)
        if index > 0:
            ans += index


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

from itertools import combinations
from operator import itemgetter
N = int(input())
XY = [list(map(int, input().split())) for _ in range(N)]
X, Y = list(map(list, zip(*XY)))

P = [abs(x1 - x2) for x1, x2 in combinations(X, 2)]
P = set(P)
if 0 in P:
    P.remove(0)
P = list(P)
Q = [abs(y1 - y2) for y1, y2 in combinations(Y, 2)]
Q = set(Q)
if 0 in Q:
    Q.remove(0)
Q = list(Q)
ans = 10**10
geta = 10**10
XY.sort()
for p in P:
    S = set()
    la = 0
    for x, y in XY:
        if (x, y) not in S:
            la += 1
        S.add((x+p, y))
    ans = min(ans, la)
XY1 = XY[:]
XY1.sort(key = itemgetter(1))
for q in Q:
    S = set()
    la = 0
    for x, y in XY1:
        if (x, y) not in S:
            la += 1
        S.add((x, y+q))
    ans = min(ans, la)

for p in P:
    for q in Q:
        S1 = set()
        S2 = set()
        la1 = 0
        la2 = 0
        for x, y in XY:
            if x*geta + y not in S1:
                la1 += 1
            if x*geta + y not in S2:
                la2 += 1
            S1.add((x+p)*geta + y+q)
            S2.add((x+p)*geta + y-q)
        ans = min(ans, la1, la2)
        
if N == 1:
    ans = 1
print(ans)


### FIXED CODE ###

from collections import Counter
from itertools import combinations
N = int(input())
XY = [list(map(int, input().split())) for _ in range(N)]
XY.sort()
A = Counter()
for (x1, y1), (x2, y2) in combinations(XY, 2):
    A[(x1-x2, y1-y2)] += 1
if N == 1:
    print(1)
else:
    print(N - max(A.values()))
### BUGGY CODE ###

import sys

N = int(input())
A = [int(x) for x in input().split(" ")]
product = 1
for a in A:
    product = product * a
if product > 10 ** 18:
    print(-1)
    sys.exit(0)

print(product)

### FIXED CODE ###

import sys

N = int(input())
A = [int(x) for x in input().split(" ")]
if 0 in set(A):
    print(0)
    sys.exit(0)

product = 1
for a in A:
    product = product * a
    if product > 10 ** 18:
        print(-1)
        sys.exit(0)


print(product)
### BUGGY CODE ###

from collections import deque

H, W = list(map(int,input().split()))
A = [input() for _ in range(H)]

dx = [0, 1, -1, 0]
dy = [1, 0, 0, -1]

def bfs(sx, sy):
    q = deque([])
    d = [[-1 for _ in range(W)] for _ in range(H)]
    q.append([sx, sy])
    d[sy][sx] = 0
    
    while(q):
        pop = q.popleft()
        x, y = pop[0], pop[1]
        if A[y][x] == "#":
            return d[y][x]
        for i in range(4):
            nx = x + dx[i]
            ny = y + dy[i]
            if 0 <= nx and nx < W and ny >= 0 and ny < H:
                if d[ny][nx] == -1:
                    q.append([nx, ny])
                    d[ny][nx] = d[y][x] + 1

                 
ans = 0
for i in range(H):
    for j in range(W):
        if A[i][j] == ".":
            res = bfs(i, j)
            ans = max(res, ans)
print(ans)

### FIXED CODE ###

from collections import deque

H, W = list(map(int,input().split()))
A = [input() for _ in range(H)]

from collections import deque

dx = [0, 1, -1, 0]
dy = [1, 0, 0, -1]  

def bfs(q, a):
  
    ret = deque([])
    while(q):
        pop = q.popleft()
        x, y = pop[0], pop[1]
        for i in range(4):
            nx = x + dx[i]
            ny = y + dy[i]
            if 0 <= nx and nx < W and ny >= 0 and ny < H:
                if a[ny][nx] == -1:
                    ret.append([nx, ny])
                    a[ny][nx] = 0
    return ret, a
  
q = deque([])

a = [[0 for _ in range(W)] for _ in range(H)]
for i in range(W):
    for j in range(H):
        if A[j][i] == ".":
            a[j][i] = -1  

ans = 0
for i in range(W):
    for j in range(H):
        if a[j][i] == 0:
            q.append([i, j])

ans = -1
while q:
    ans += 1
    q, a = bfs(q, a)
            
print(ans)
### BUGGY CODE ###

import math

n = int(input())
answer_list = []
for x in range(1, int(math.sqrt(n+1)), 1):
    for y in range(1, int(math.sqrt(n+1)), 1):
        for z in range(1, int(math.sqrt(n+1)), 1):
            formula = (x+y+z)**2 - (x*y + y*z + z*x)
            if formula <= n:
                answer_list.append(formula)
            else:
                break
for i in range(1, n+1, 1):
    print(answer_list.count(i))

### FIXED CODE ###

import math

n = int(input())
answer_lists = [0 for i in range(10001)]
for x in range(1, int(math.sqrt(n+1)), 1):
    for y in range(1, int(math.sqrt(n+1)), 1):
        for z in range(1, int(math.sqrt(n+1)), 1):
            formula = (x+y+z)**2 - (x*y + y*z + z*x)
            if formula <= n:
                answer_lists[formula] += 1
            else:
                break
for i in range(1, n+1, 1):
    print(answer_lists[i])
### BUGGY CODE ###

import copy
n = int(input())
a = []
for i in range(n):
    a.append(int(input()))
c = a.count(max(a))
a_2 = copy.copy(a)

if c > 1:
    for i in range(n):
        print(max(a))
else:
    t = max(a)
    a_2.remove(t)
    t_2 = max(a_2)
    for i in a:
        if i == t:
            print(t_2)
        else:
            print(t)


### FIXED CODE ###

import copy
n = int(input())
a = []
for i in range(n):
    a.append(int(input()))
c = a.count(max(a))
a_2 = copy.copy(a)
t = max(a)

if c > 1:
    for i in range(n):
        print(t)
else:
    a_2.remove(t)
    t_2 = max(a_2)
    for i in a:
        if i == t:
            print(t_2)
        else:
            print(t)
### BUGGY CODE ###

from numpy import*;a,b=loadtxt(open(0),'i',skiprows=1);c=0;l=2**29
while l:h=l;l//=2;i,j=searchsorted(sort(hstack((b%h-h,b%h))),[l-a%h,h-a%h]);c+=sum(j-i)%2*l
print(c)

### FIXED CODE ###

from numpy import*;B,I=searchsorted,lambda:int32(input().split());input();a,b=I(),I();c=0
for k in range(29):l=2**k;h=l*2;x,y=a%h,sort(b%h);y=hstack((y-h,y));c+=sum(B(y,h-x)-B(y,l-x))%2*l
print(c)
### BUGGY CODE ###

n = int(input())
word = [input() for i in range(n)]
test = list([x,0] for x in set(word))
max_num = 0

for i, num in enumerate(test):
  test[i][1] = word.count(num[0])
  if(test[i][1] >= max_num):
    max_num = test[i][1]

print('\n'.join(sorted([num[0] for num in test if int(num[1]) == max_num])))


### FIXED CODE ###

from collections import Counter
n = int(input())
word = Counter([input() for i in range(n)]).most_common()
print('\n'.join(sorted([num[0] for num in word if int(num[1]) == word[0][1]])))
### BUGGY CODE ###

import numpy as np
N, C = list(map(int, input().split()))
s = [0 for _ in range(N)]
t = [0 for _ in range(N)]
c = [0 for _ in range(N)]
for i in range(N):
    s[i], t[i], c[i] = list(map(int, input().split()))

tmax = max(t)
c_timeline = [[0 for _ in range(2*tmax + 1)] for _ in range(C)]
rokuga = 0
for i in range(N):
    Si = s[i]
    Ti = t[i]
    Ci = c[i]
    c_timeline[Ci-1][2*Si-1:2*Ti+1] = [1 for _ in range(2*(Ti-Si)+2)]

c_timeline = np.array(c_timeline).T
for timeline in c_timeline:
    time = sum(timeline)
    if rokuga < time:
        rokuga = time

print(rokuga)


### FIXED CODE ###

N, C = list(map(int, input().split()))
tmax = 0
s = [0 for _ in range(N)]
t = [0 for _ in range(N)]
c = [0 for _ in range(N)]
for i in range(N):
    s[i], t[i], c[i] = list(map(int, input().split()))

tmax = max(t)
c_timeline = [[0]*C for _ in range(2 * tmax + 1)]
for i in range(N):
    S = s[i]
    T = t[i]
    channel = c[i] - 1
    for j in range(2 * S - 1, 2 * T + 1):
        c_timeline[j][channel] = 1

rokuga = 0
for timeline in c_timeline:
    time = sum(timeline)
    if rokuga < time:
        rokuga = time

print(rokuga)
### BUGGY CODE ###

job = list()
salary = list()
j = 0
n,m = map(int,input().split())
for i in range(n):
    a,b = map(int,input().split())
    job.append((a,b))
job.sort(reverse = True)
for i in range(n):
    a,b = job[i]
    salary.append(b)
    if a + j > m :
        salary.remove(min(salary))
        continue
    j += 1
print(sum(salary))


### FIXED CODE ###

import heapq
job = list()
salary = list()
n,m = map(int,input().split())

for i in range(n):
    a,b = map(int,input().split())
    job.append((a,b))

job.sort(reverse = True)

for x in job:
    s,t = x
    heapq.heappush(salary,t)
    if s - m > 0:
        heapq.heappop(salary)
    else:
        m -= 1

print(sum(salary))
### BUGGY CODE ###

import sys

def exhaustiveSearch(A, m, i):
    if A[i] == m:
        return True
    elif i == len(A) - 1 or m < 0:
        return False

    return exhaustiveSearch(A, m, i + 1) or exhaustiveSearch(A, m - A[i], i + 1)

if __name__ == "__main__":
    lines = sys.stdin.readlines()
    A = map(int, lines[1].split())
    M = map(int, lines[3].split())

    for m in M:
        if exhaustiveSearch(A, m, 0):
            print "yes"
        else:
            print "no"

### FIXED CODE ###

import sys

def exhaustiveSearch(A, m, i, s):
    if A[i] == m:
        return True
    elif i == len(A) - 1 or m < 0 or m > s:
        return False

    return exhaustiveSearch(A, m, i + 1, s) or exhaustiveSearch(A, m - A[i], i + 1, s)

if __name__ == "__main__":
    lines = sys.stdin.readlines()
    A = map(int, lines[1].split())
    M = map(int, lines[3].split())
    s = sum(A)

    for m in M:
        if exhaustiveSearch(A, m, 0, s):
            print "yes"
        else:
            print "no"
### BUGGY CODE ###

N,M=map(int,input().split())
L=[0]*M
R=[0]*M
LR=[]
for i in range(M):
  L[i],R[i]=map(int,input().split())
  LR.append([L[i],R[i]])
a=max(L)
b=min(R)
ans=0
for i in range(a,b+1):
  count=0
  for j in range(M):
    if LR[j][0]<=i<=LR[j][1]:
      count+=1
  if count==M:
      ans+=1
print(ans)

### FIXED CODE ###

N,M=map(int,input().split())
L,R=[],[]

for i in range(M):
  l,r=map(int,input().split())
  L.append(l)
  R.append(r)
L.sort(reverse=True)
R.sort()

if R[0]>=L[0]:
  print(R[0]-L[0]+1)
else:
  print(0)
### BUGGY CODE ###

from scipy.sparse.csgraph import dijkstra

N = int(input())

G = [[float('inf')] * N for i in range(N)]

if N == 1:
    print(1)
else:
    for i in range(N-1):
        u, v, w = map(int, input().split())
        G[u-1][v-1] = w
        G[v-1][u-1] = w

    # G2 = csgraph_from_dense(G)
    d = dijkstra(G, indices=0)

    for dist in d:
        if dist % 2 == 0:
            print(1)
        else:
            print(0)


### FIXED CODE ###

import sys
sys.setrecursionlimit(1000000)


N = int(input())
G = [[] for i in range(N)]

for i in range(N-1):
    u, v, w = map(int, input().split())
    if w % 2 == 0:
        G[u-1].append((v-1, 1))
        G[v-1].append((u-1, 1))
    else:
        G[u-1].append((v-1, -1))
        G[v-1].append((u-1, -1))

color = [None for i in range(N)]


def set_color(v, c):
    color[v] = c
    for next_v, d in G[v]:
        if color[next_v] is None:
            set_color(next_v, d*c)


set_color(0, 1)

for c in color:
    if c == 1:
        print(1)
    else:
        print(0)
### BUGGY CODE ###

def p_e():
    N = int(input())
    A = [int(input()) for _ in range(N)]
    ans = 0

    while A:
        ans += 1
        stv = -1
        start = A.index(min(A))
        while start < len(A):
            if A[start] > stv:
                stv = A.pop(start)
            else:
                start += 1

    print(ans)


if __name__ == '__main__':
    p_e()


### FIXED CODE ###

from bisect import *


def p_e():
    N = int(input())
    # A = [int(input()) for _ in range(N)]
    ans = [-1] * N

    for _ in range(N):
        a = int(input())
        ans[bisect(ans, a - 1) - 1] = a

    print(N - bisect(ans, -1))


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

n = int(input())
D = list(map(int, input().split()))


if D[0] != 0:
    ans = 0
else:
    ans = 1
    cnt = 1
    for i in range(max(D)+1):
        ans = ans * (cnt ** D.count(i)) % 998244353
        cnt = D.count(i)

print(ans)


### FIXED CODE ###

n = int(input())
D = list(map(int, input().split()))


if D[0] != 0 or 0 in D[1:]:
    ans = 0
else:
    num = [0 for i in range(max(D)+1)]
    ans = 1
    cnt = 1
    for i in range(n):
        num[D[i]] += 1
    for i in range(len(num)):
        ans = ans * (cnt ** num[i]) % 998244353
        cnt = num[i]

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

# coding: utf-8
import sys
#from operator import itemgetter
sysread = sys.stdin.readline
#from heapq import heappop, heappush
#from collections import defaultdict
sys.setrecursionlimit(10**7)
#import math
#from itertools import combinations
def run():
    k,q = map(int, sysread().split())
    d = list(map(int,sysread().split()))


    def check(n ,x, m):
        _d = [d[0] % m]
        for val in d[1:]:
            _d.append(_d[-1] + val % m)

        # n_step
        n_d = (n-1)// k
        n_rest = (n-1) % k
        x %= m
        _d_rest = 0 if n_rest == 0 else _d[n_rest-1]
        a_last = x + n_d * _d[k-1] + _d_rest
        n_step = a_last // m - x // m
        # n_same
        d0 = [1] if _d[0] == 0 else [0]
        for val in d[1:]:
            plus = 1 if val % m == 0 else 0
            d0.append(d0[-1] + plus)
        d0_rest = 0 if n_rest == 0 else d0[n_rest-1]
        n_same = n_d * d0[k-1] + d0_rest

        return n-1 - n_same - n_step


    for _ in range(q):
        n,x,m = map(int, sysread().split())
        print(check(n, x, m))

if __name__ == "__main__":
    run()

### FIXED CODE ###

# coding: utf-8
import sys
#from operator import itemgetter
sysread = sys.stdin.readline
#from heapq import heappop, heappush
#from collections import defaultdict
sys.setrecursionlimit(10**7)
#import math
#from itertools import combinations
import numpy as np
def run():
    k,q = map(int, sysread().split())
    d = list(map(int,sysread().split()))
    d = np.array(d, dtype=np.uint64)

    def check(n ,x, m):
        _d = d % m
        d0 = d % m == 0
        # n_step
        n_d = (n-1) // k
        n_rest = (n-1) % k
        x %= m
        _d_rest, d0_rest = 0, 0
        if n_rest != 0:
            _d_rest = _d[:n_rest].sum()
            d0_rest = d0[:n_rest].sum()

        a_last = x + n_d * _d.sum() + _d_rest
        n_step = a_last // m
        # n_same
        n_same = n_d * d0.sum() + d0_rest

        return n-1 - n_same - n_step


    for _ in range(q):
        n,x,m = map(int, sysread().split())
        print(int(check(n, x, m)))

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

S = input()
Sr = S[::-1] # 一の位から考える

T = 0 # 部分文字列
mod = [0] * 2019 # mod数え上げ配列
mod[0] += 1 # 「部分文字列T = S」の場合の、 「0 % 2019 = 0」を予めカウント
for i, s in enumerate(Sr):
  T += int(s) * (10 ** i)
  mod[T%2019] += 1

# ペアを合計
mod = [m//2 for m in mod]
print(sum(mod))

### FIXED CODE ###

S = input()
Sr = S[::-1] # 一の位から考える

T = 0 # 部分文字列
mod = [0] * 2019 # mod数え上げ配列
mod[0] += 1 # 「部分文字列T = S」の場合の、 「0 % 2019 = 0」を予めカウント
d = 1 # 桁数
for i, s in enumerate(Sr):
  T += int(s) * d
  T %= 2019
  d = (d * 10) % 2019
  
  mod[T] += 1
  
# ペアを合計
# n個から2通り選ぶ（nC2）
mod = [n * (n-1) // 2 for n in mod]
print(sum(mod))
### BUGGY CODE ###

#n = int(input())
#s = input()
#n, k= map(int,input().split())
#da = list(map(int,input().split()))
class SegTree:
    def __init__(self,n):
        self.size=1
        while(n>self.size):
            self.size<<=1
        self.nod=[0 for i in range(self.size*2-1)]
    def update(self,k,a):
        k+=self.size-1
        self.nod[k]+=a
        while(k>0):
            k=(k-1)>>1
            self.nod[k]|=a
    def dedate(self, k, a):
        k += self.size-1
        self.nod[k] -= a
        while(k>0):
            k=(k-1)>>1
            self.nod[k] = self.nod[(k<<1)|1]|self.nod[(k+1)<<1]
    def query(self,a,b,k,l,r):
        if(r<=a or b<=l):
            return 0
        if(a<=l and r<=b):
            return self.nod[k]
        else:
            return self.query(a,b,(k<<1)|1,l,(l+r)>>1)|self.query(a,b,(k+1)<<1,(l+r)>>1,r)

def pop_c(x):
    ret = 0
    while x:
        ret += x&1
        x>>=1
    return ret

n = int(input())
t = input()
q = int(input())
EE = ord('a')
st = SegTree(n)
s = [t[i] for i in range(n)]

def adding(x, c):
    global st
    st.dedate(x, 1<<(ord(s[x])-EE))
    st.update(x, 1<<(ord(c)-EE))
    s[x] = c

def query(l, r):
    now = st.query(l, r+1, 0, 0, st.size)
    return pop_c(now)

for i in range(n):
    st.update(i, 1<<(ord(s[i])-EE))
ans = []
for i in range(q):
    x,l,r = map(str,input().split())
    if x=='1':
        adding(int(l)-1, r)
    else:
        ans.append(query(int(l)-1, int(r)-1))
for i in range(len(ans)):
    print(ans[i])

### FIXED CODE ###

#n = int(input())
#s = input()
#n, k= map(int,input().split())
#da = list(map(int,input().split()))
class SegTree:
    def __init__(self,n):
        self.size=1
        while(n>self.size):
            self.size<<=1
        self.nod=[0 for i in range(self.size*2-1)]
    def update(self,k,a):
        k+=self.size-1
        self.nod[k]+=a
        while(k>0):
            k=(k-1)>>1
            self.nod[k]|=a
    def dedate(self, k, a):
        k += self.size-1
        self.nod[k] -= a
        while(k>0):
            k=(k-1)>>1
            self.nod[k] = self.nod[(k<<1)|1]|self.nod[(k+1)<<1]
    def query(self,a,b,k,l,r):
        if(r<=a or b<=l):
            return 0
        if(a<=l and r<=b):
            return self.nod[k]
        else:
            return self.query(a,b,(k<<1)|1,l,(l+r)>>1)|self.query(a,b,(k+1)<<1,(l+r)>>1,r)

def pop_c(x):
    ret = 0
    while x:
        ret += x&1
        x>>=1
    return ret

n = int(input())
t = input()
q = int(input())
EE = ord('a')
st = SegTree(n)
s = [t[i] for i in range(n)]

def adding(x, c):
    global st
    st.dedate(x, 1<<(ord(s[x])-EE))
    st.update(x, 1<<(ord(c)-EE))
    s[x] = c

def query(l, r):
    now = st.query(l, r+1, 0, 0, st.size)
    return pop_c(now)

for i in range(n):
    st.update(i, 1<<(ord(s[i])-EE))
ans = []
for i in range(q):
    x,l,r = map(str,input().split())
    if x=='1':
        adding(int(l)-1, r)
    else:
        ans.append(query(int(l)-1, int(r)-1))
for i in range(len(ans)):
    print(ans[i])
### BUGGY CODE ###

# TODO: WAなので修正する
from math import factorial
from operator import mul
from functools import reduce

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

n = int(input())
li = []
for i in range(n):
    s = input()
    s = "".join(sorted(s))
    li.append(s)

li.sort()
index = 0
anagram_cnt_sum = 0
while(index < n):
    anagram_cnt = li.count(li[index])
    if anagram_cnt > 1:
        anagram_cnt_sum += cmb(anagram_cnt, 2)
    index += anagram_cnt
print(anagram_cnt_sum)


### FIXED CODE ###

N = int(input())
d = {}
ans = 0
for _ in range(N):
    s = str(sorted(input()))
    if s not in d.keys():
        d[s] = 0
    else:
        d[s] += 1
        ans += d[s]
print(ans)
### BUGGY CODE ###

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


def dfs(v, visited, G):
    visited[v] = True
    for nv in G[v]:
        if visited[nv]==False:
            dfs(nv, visited, G)


def main():
    N, M = map(int, input().split())
    G = [[] for _ in range(N)]
    for _ in range(M):
        x, y, z = map(int, input().split())
        G[x-1].append(y-1)
        G[y-1].append(x-1)
    
    nodes = list(range(N))
    visited = [False]*N
    ans = 0
    while len(nodes)!=0:
        v = nodes.pop()
        if visited[v]==True:
            continue
        ans += 1
        dfs(v, visited, G)
        # print(visited)
        # print(nodes)
    
    print(ans)



if __name__ == '__main__':
    main()

### FIXED CODE ###

import heapq
import sys
input = sys.stdin.readline
sys.setrecursionlimit(10**7)


def dfs(v, visited, G):
    visited[v] = True
    for nv in G[v]:
        if visited[nv]==False:
            dfs(nv, visited, G)


def main():
    N, M = map(int, input().split())
    G = [[] for _ in range(N)]
    for _ in range(M):
        x, y, z = map(int, input().split())
        G[x-1].append(y-1)
        G[y-1].append(x-1)
    
    nodes = list(range(N))
    visited = [False]*N
    ans = 0
    while len(nodes)!=0:
        v = nodes.pop()
        if visited[v]==True:
            continue
        ans += 1
        dfs(v, visited, G)
        # print(visited)
        # print(nodes)
    
    print(ans)



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

import math

n = input()
a = input().split()
N = int(n)

ans_list = []
ann = []
ana = 1
for j in range(N):
    ana = ana * int(a[j])
ana = ana -1
for i in range(N):

    ans = 0
    for k in range(i+1):
        ans += int(ana % int(a[k]))
    ans_list.append(ans)

ans_list.sort()
ans_list.reverse()
print(str(ans_list[0]))







### FIXED CODE ###

import math

n = input()
a = input().split()
N = int(n)

ans_list = []
ann = []
ana = 1
for j in range(N):
    ana = ana * int(a[j])
ana = ana -1
ans = 0
for k in range(N):
    ans += int(ana % int(a[k]))
ans_list.append(ans)

ans_list.sort()
ans_list.reverse()
print(str(ans_list[0]))