Harryxun/stf_run huggingface dataset:
import math
from functools import reduce

n = int(input())
a_list = list(map(int, input().split()))
max = a_list[n - 1] + 100
memo = [0] * max

for a in a_list:
    memo[a] += 1

for i in range(2, max):
    if sum(memo[i::i]) > 1:
        if reduce(math.gcd, a_list) == 1:
            print("setwise coprime")
            exit()
        else:
            print("not coprime")
            exit()

print("pairwise coprime")


### FIXED CODE ###

import math
from functools import reduce
L = 10**6 + 1
n = int(input())
a_list = list(map(int, input().split()))
memo = [0] * L

for a in a_list:
    memo[a] += 1

for i in range(2, L):
    if sum(memo[i::i]) > 1:
        if reduce(math.gcd, a_list) == 1:
            print("setwise coprime")
            exit()
        else:
            print("not coprime")
            exit()

print("pairwise coprime")
n=int(input())
s=int(input())

b_ans=1
for b in range(2,int(n**0.5)+1):
  nn=n
  st=[]
  while(nn>0):
    st.append(nn%b)
    nn=(nn-st[-1])/b
  
  if sum(st)==s:
    b_ans=b
    break


if b_ans==1:
  for p in range(int(n**0.5)):
    b=int(n/p)
    q=n-p*b
    if s==p+q:
      b_ans=b
      break

if b_ans!=1:
  print(b_ans)
else:
  print(-1)

### FIXED CODE ###

n=int(input())
s=int(input())

b_ans=1



if n==s:
  b_ans=n+1
if b_ans==1:
  for b in range(2,int(n**0.5)+1):
    nn=n
    st=[]
    while(nn>0):
      st.append(nn%b)
      nn=(nn-st[-1])/b
  
    if sum(st)==s:
      b_ans=b
      break

if b_ans==1:
  for p in range(int(n**0.5),0,-1):
    b=(n-s+p)/p

    if b.is_integer() and 0<=s-p<b and b>n**0.5:
      b_ans=int(b)
      break

if b_ans!=1:
  print(b_ans)
else:
  print(-1)
n = int(input().split())
a = list(map(int,input().split()))
ans = []
for i in range(n,0,-1):
  if sum(a[::i]) % 2 == 1:
    ans.append(i)
ans.reverse()
print(len(ans))
print(" ".join(ans))

### FIXED CODE ###

n = int(input())
a = list(map(int,input().split()))
key = [0]*n
ans = []
for i in range(n-1,-1,-1):
  if sum(key[i::i+1]) % 2 != a[i]:
    ans.append(i+1)
    key[i] = 1
ans.reverse()
print(len(ans))
print(" ".join(list(map(str,ans))))
ans = []
for p in range(2, 10):
    for b in range(1, 32):
        if b**p <= X:
            ans.append(b**p)
        else:
            break
print(max(ans))

### FIXED CODE ###

X = int(input())
ans = []
for p in range(2, 10):
    for b in range(1, 32):
        if b**p <= X:
            ans.append(b**p)
        else:
            break
print(max(ans))
import bisect

n = int(input())
ls = list(map(int, input().split()))
ls.sort()

count = 0

for i in range(n - 2):
  a = ls[i]
  for j in range(i + 1, n - 1):
    b = ls[j]
    index = bisect.bisect_left(ls, a + b):
    count += index - j - 1
print(count)


### FIXED CODE ###

import bisect
n = int(input())

li = list(map(int, input().split()))
li.sort()

count = 0

for i in range(n - 2):
  for j in range(i + 1, n - 1):
    bi = bisect.bisect_left(li, li[i] + li[j])
    count += bi - j - 1
print(count)
A,B=map(int,input().split())
for i in range(10000):
  if A==int(i*0.08) and B==(i*0.1) :
    print(i)
    exit()
plint("-1")

### FIXED CODE ###

A,B=map(int,input().split())
for i in range(10000):
  if A==int(i*0.08) and B==int(i*0.1) :
    print(i)
    exit()
print("-1")
N = int(input())
G = [[] for i in range(N)]
for i in range(N-1):
    a,b = map(int,input().split())
    a,b = a-1,b-1
    G[a].append([b, i])

ans = [None]*(N-1)
def rec(cur, color):
    cnt = 1
    for (to, j) in G[cur]:
        if cnt == color:
            cnt += 1
        ans[j] = cnt
        rec(to, cnt)
        cnt += 1

rec(0,0)
print(max(ans))
[print(a) for a in ans]


### FIXED CODE ###

import sys
sys.setrecursionlimit(1000000)

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

ans = [None]*(N-1)
def rec(cur, color):
    cnt = 1
    for (to, j) in G[cur]:
        if cnt == color:
            cnt += 1
        ans[j] = cnt
        rec(to, cnt)
        cnt += 1

rec(0,0)
print(max(ans))
[print(a) for a in ans]
input()

print(‘ ‘.join(input().split()[::-1]))


### FIXED CODE ###

input()
print(' '.join(input().split()[::-1]))
D,N=map(int,input()split())

if N<100:
  print(100**D*N)
else:
  print(100**D*101)


### FIXED CODE ###

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

if N<100:
  print(100**D*N)
else:
  print(100**D*101)
from collections import Counter

n = int(input())
a = list(map(int, input().split()))
m = n//2
ca = Counter(a)

if n % 2 == 0 and all(ca[i*2 + 1] == 2 for i in range(m)):
    ans = (2 ** m) % (1e9 + 7)
    print(int(ans))
elif n % 2 == 1 and ca[0] == 1 and all(ca[(i+1)*2] == 2 for i in range(m)):
    ans = (2 ** m) % (1e9 + 7)
    print(int(ans))
else:
    print(0)


### FIXED CODE ###


from collections import Counter

n = int(input())
a = list(map(int, input().split()))
m = n // 2
ca = Counter(a)

if n % 2 == 1 and ca[0] == 1 and all(ca[(i+1)*2] == 2 for i in range(m)):
    ans = (2 ** m) % (10 ** 9 + 7)
    print(ans)
elif n % 2 == 0 and all(ca[i*2 + 1] == 2 for i in range(m)):
    ans = (2 ** m) % (10 ** 9 + 7)
    print(ans)
else:
    print(0)
n = int(input())
S = input()
c = S[::-1]
w,b = 0,0

for i in range(len(S)):
    if S[i] != '.':
        break

for e in range(len(c)):
    if c[e] != '#':
        break

for s in range(i,len(S)-e+1):
    if S[s] == '.':
        w += 1
    else:
        b += 1

if b > w:
    print(w)
else:
    print(b)


### FIXED CODE ###

n = int(input())
S = [s for s in input()]
w,b = [0],[0]
for i in range(n):
    if S[i] is '#': w.append(w[i]+1)
    else:   w.append(w[i])
    if S[n-i-1] is '.': b.append(b[i]+1)
    else:   b.append(b[i])
b = b[::-1]
#print(w,b)
ans = float('inf')
for i in range(n+1):
    ans = min(ans, w[i]+b[i])
print(ans)
a,b=map(int,input().split())
x=100*a/8
y=100/8*(a+1)
z=10*b
w=10*(b+1)
import math
if max(math.ceil(z),math.ceil(x))<min(y,w)1 3 :
    print(math.ceil(max(z,x)))
else:
    print(-1)    

### FIXED CODE ###

a,b=map(int,input().split())
x=100*a/8
y=100/8*(a+1)
z=10*b
w=10*(b+1)
import math
if max(math.ceil(z),math.ceil(x))<min(y,w) :
    print(math.ceil(max(z,x)))
else:
    print(-1)
t=[int(input()) for _ in range(5)]
ans=0
b=[x%10 for x in t]
c=[x%10 for x in t if x%10>0]
for i in range(5):
    if b[i]>0:
        ans+=(t[i]//10+1)*10
    else:
        ans+=t[i]
print(ans-10+min(c))

### FIXED CODE ###

t=[int(input()) for _ in range(5)]
ans=0
b=[x%10 for x in t]
c=[x%10 for x in t if x%10>0]
if c==[]:
    print(sum(t))
else:
    for i in range(5):
        if b[i]>0:
            ans+=(t[i]//10+1)*10
        else:
            ans+=t[i]
    print(ans-10+min(c))
import heapq
hq=[]
X, Y, Z, K= map(int,input().split())
A=list(map(int,input().split()))
A.sort(reverse=True)
B=list(map(int,input().split()))
B.sort(reverse=True)
C=list(map(int,input().split()))
C.sort(reverse=True)
searched={(0,0,0)}
heapq.heappush(hq,(-(A[0]+B[0]+C[0]),0,0,0))
D=[[1,0,0],[0,1,0],[0,0,1]]

for _ in range(K):
    abc,x,y,z=heapq._heappop_max(hq)
    print(-abc)
    for dx,dy,dz in D:
        if x+dx<X and y+dy < Y and z+dz < Z and (x+dx,y+dy,z+dz) not in searched:
            heapq.heappush(hq,(-(A[x+dx]+B[y+dy]+C[z+dz]),x+dx,y+dy,z+dz))
            searched.add((x+dx,y+dy,z+dz))

### FIXED CODE ###

X, Y, Z, K= map(int,input().split())
A=list(map(int,input().split()))
A.sort(reverse=True)
B=list(map(int,input().split()))
B.sort(reverse=True)
C=list(map(int,input().split()))
C.sort(reverse=True)

ABC=[]
for i in range(X):
    for j in range(Y):
        for k in range(Z):
            if (i+1)*(j+1)*(k+1)<=K:
                ABC.append(A[i] + B[j] + C[k])
            else:
                break

ABC.sort(reverse=True)

for i in range(K):
    print(ABC[i])
# coding: utf-8
import math
A, B = [int(x) for x in input().split(" ")]

print((A*B) // math.gcd(A, B))


### FIXED CODE ###

# coding: utf-8
def gcd(a,b):
  while b!=0:
    a,b=b,a%b
  return a

 #最小公倍数
def lcm(a,b):
  return a*b//gcd(a,b)
 
A, B = [int(x) for x in input().split(" ")]
 
print(lcm(A, B))
import sys

import math
import itertools

n,m,k=map(int,input().split())
a = list(map(int, input().split()))
b = list(map(int, input().split()))
ans = 0
time = 0
max=len(a)+len(b)
for i in range(max):
    if (len(a) == 0):
        if (time + b[0] <= k):
            time += b[0]
            ans += 1
            b.pop(0)
    elif (len(b) == 0):
        if (time + a[0] <= k):
            time += a[0]
            ans += 1
            a.pop(0)
    else:
        tmp = 0
        isA=True
        if (a[0] < b[0]):
            tmp = a[0]
            isA=True
        else:
            tmp = b[0]
            isA = False
        if (time + tmp <= k):
            time += tmp
            ans += 1
            if (isA):
                a.pop(0)
            else:
                b.pop(0)
print(ans)
        

### FIXED CODE ###

import sys

import math
import itertools

a=int(input())
print(a+a**2+a**3)
n, m = [int (x) for x in input().split(' ')]
a = [[0 for i in range(n)] for j in range(m)]
b = [0 for i in range(m)]
c = [0 for i in range(n)]
for s in range(0,n):
    a[s] = [int (x) for x in input().split(' ')]
for s in range(0,m):
    b[s] = int(input())
for s in range(0,n):
    for t in range(0,m):
        c[s] += a[s][t] * b[t]
for t in range(0,n):
    print("%d" % c[t])

### FIXED CODE ###

n, m = [int (x) for x in input().split(' ')]
a = [[0 for i in range(m)] for j in range(n)]
b = [0 for i in range(m)]
c = [0 for i in range(n)]
for s in range(0,n):
    a[s] = [int (x) for x in input().split(' ')]
for s in range(0,m):
    b[s] = int(input())
for s in range(0,n):
    for t in range(0,m):
        c[s] += a[s][t] * b[t]
for t in range(0,n):
    print("%d" % c[t])
from collection import defaultdict
N, M = map(int, input().split())

aced = [False]*N
D = defaultdict(int)
ac = 0
pena = 0
for _ in range(M):
    id, judge = input().split()
    id = int(id)-1
    if judge == "WA":
        D[id] += 1
    else:
        if not aced[id]:
            aced[id] = True
            ac += 1
            pena += D[id]
print(ac, pena)


### FIXED CODE ###

from collections import defaultdict
N, M = map(int, input().split())

aced = [False]*N
D = defaultdict(int)
ac = 0
pena = 0
for _ in range(M):
    id, judge = input().split()
    id = int(id)-1
    if judge == "WA":
        D[id] += 1
    else:
        if not aced[id]:
            aced[id] = True
            ac += 1
            pena += D[id]
print(ac, pena)
while True:
    n = int(input())
    if n == 0:
        break
    d = {}
    for _ in range(n):
        a, b = input().split()
        d[a] = b
    m = int(input())
    tmp = [input().strip() for _ in range(int(input()))]
    ans = [d[a] if a in d.keys() else a for a in tmp]
    print("".join(ans))

### FIXED CODE ###

while True:
    n = int(input())
    if n == 0:
        break
    converter = {}
    for _ in range(n):
        k, v = input().split()
        converter[k] = v

    m = int(input())
    ans = []
    for _ in range(m):
        v = input().strip()
        try:
            ans.append(converter[v])
        except:
            ans.append(v)

    print("".join(ans))
x, y = map(int, input().split())
if x == 2 or y == 2:
  print("No")
elif {4, 6, 9, 11} <= x and {4, 6, 9, 11} <= y:
  print("Yes")
elif {1, 3, 5, 7, 8, 10, 12} <= x and {1, 3, 5, 7, 8, 10, 12} <= y:
  print("Yes")
else :
  print("No")

### FIXED CODE ###

x, y = map(int, input().split())
if x == 2 or y == 2:
  print("No")
elif {4, 6, 9} >= {x} and {6, 9, 11} >= {y}:
  print("Yes")
elif {1, 3, 5, 7, 8, 10} >= {x} and {3, 5, 7, 8, 10, 12} >= {y}:
  print("Yes")
else :
  print("No")
N,K = map(int,input().split())

ans=N-K+1;

input(ans)

### FIXED CODE ###

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

ans=N-K+1

print(ans)
n,m = map(int,input().split(' '))

bar = [[] for _ in range(m)]

for i in range(n):
    a,b = map(lambda x:int(x)-1,input().split(' '))
    bar[a].append(b)
    bar[b].append(a) 


result = 0

def search(root=[0]):
    global result
    if len(root) >= n:
        result += 1
        return
    nxt = set(bar[root[-1]])
    nxt = nxt - set(root)
    for nxt_ in nxt:
        search(root+[nxt_])

search()
print(result)

### FIXED CODE ###

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

bar = [[] for _ in range(n)]

for i in range(m):
    a,b = map(lambda x:int(x)-1,input().split(' '))
    bar[a].append(b)
    bar[b].append(a)

result = 0

def search(root=[0]):
    global result
    if len(root) >= n:
        result += 1
        return
    nxt = set(bar[root[-1]])
    nxt = nxt - set(root)
    for nxt_ in nxt:
        search(root+[nxt_])

search()
print(result)
A, B = map(int, input().split())
if A>= 13:
    print(B)
elif 6 =< A =< 12:
    print(B/2)
else:
    print(0)

### FIXED CODE ###

A, B = map(int, input().split())
if A>= 13:
    print(B)
elif A <= 5:
    print(0)
else:
    print(B//2)
n = int(input())
alist  = list(map(int,input().split()))
from collections import Counter
adic = Counter(alist)
vlist = sorted(list(adic.values()))
print(n - vlist[-1] - vlist[-2])

### FIXED CODE ###

n = int(input())
alist  = list(map(int,input().split()))
list1 = alist[1::2]
list2 = alist[0::2]
from collections import Counter
dic1 = Counter(list1).most_common()
dic2 = Counter(list2).most_common()
dic1.append([0,0])
dic2.append([0,0])
if dic1[0][0]!=dic2[0][0]:
  print(n - dic1[0][1] - dic2[0][1])
else:
  print(min(n - dic1[0][1] - dic2[1][1], n -dic1[1][1] - dic2[0][1]))
from collections import Counter
N = int(input())
A = list(set((map(int, input().split()))))

pc = True
if N != len(A):
    pc = False
    N = len(A)

gg = False
cnt = Counter()

def factorization(n):
    arr = []
    temp = n
    for i in range(2, int(-(-n**0.5//1))+1):
        if temp%i==0:
            while temp%i==0:
                temp //= i
            arr.append(i)
    if temp!=1:
        arr.append(temp)
    if arr==[]:
        arr.append(n)
    return arr

for a in factorization(A[0]):
    if a > 1:
        cnt[a] = 1

for i in range(1, N):
    for a in factorization(A[i]):
        if cnt[a] >= 1:
            pc = False
        if a > 1:
            cnt[a] += 1

if pc:
    print("pairwise coprime")
elif cnt.most_common(1)[0][1] < N:
    print("setwise coprime")
else:
    print("not coprime")

### FIXED CODE ###

from collections import Counter
N = int(input())
A = list(map(int, input().split()))

x = max(A)
hurui = [x]*(x+1)
for i in range(2, x+1):
    for j in range(i, x+1, i):
        hurui[j] = min(i, hurui[j])

cnt = Counter([1])
for i in range(N):
    num = A[i]
    while num > 1:
        x = hurui[num]
        while num%x == 0:
            num //= x
        cnt[x] += 1

a = cnt.most_common(1)[0][1]
if a == 1:
    print("pairwise coprime")
elif a < N:
    print("setwise coprime")
else:
    print("not coprime")
n, k = map(int, input().split())
a = [1] * n
for i in range(k):
    tmp = map(int, input().split())
    for j in range(tmp):
        a[j] = 0
print(sum(a[j]))


### FIXED CODE ###

n, k = map(int, input().split())
a = [1] * n
for i in range(k):
    d = int(input())
    tmp = map(int, input().split())
    for j in tmp:
        a[j - 1] = 0
print(sum(a))
from itertools import product
N = input()
length = len(N)
T = [''.join(t) for t in product(('3','5','7'),repeat = 3)]

def f(N,s):
    if len(s) == length:
        if int(s) < int(N) and '3' in s and '5' in s and '7' in s:
            return 1
        else:
            return 0
    else:
        if '3' in s and '5' in s and '7' in s:
            a = 1
        else:
            a = 0
        a += sum(f(N,s+c) for c in('3','5','7'))
        return a
print(sum(f(N, t) for t in T))

### FIXED CODE ###

from itertools import product
N = input()
length = len(N)
T = [''.join(t) for t in product(('3','5','7'),repeat = 3)]

def f(N,s):
    if len(s) == length:
        if int(s) <= int(N) and '3' in s and '5' in s and '7' in s:
            return 1
        else:
            return 0
    else:
        if '3' in s and '5' in s and '7' in s:
            a = 1
        else:
            a = 0
        a += sum(f(N,s+c) for c in('3','5','7'))
        return a
if int(N)<357:
    print(0)
else:
    print(sum(f(N, t) for t in T))
N = int(input())

E = []
T = [[] for i in range(N)]
for i,n in enumerate(range(N-1)):
    a,b = map(int,input().split())
    E.append((a-1,b-1))
    T[a-1].append(b-1)

# print(E)
# print(T)



R = [None for i in range(N)]
def dfs(using, cur):
    R[cur] = using
    i=0
    for t in T[cur]:
        if i==using:
            i+=1
        dfs(i,t)
        i+=1


dfs(-1, 0)

print(max(R)+1)
# print(K)
for e in E:
    print(R[e[1]]+1)

# print(K)


### FIXED CODE ###

import sys
sys.setrecursionlimit(10**9)

N = int(input())

E = []
T = [[] for i in range(N)]
for i,n in enumerate(range(N-1)):
    a,b = map(int,input().split())
    E.append((a-1,b-1))
    T[a-1].append(b-1)

# print(E)
# print(T)



R = [None for i in range(N)]
def dfs(using, cur):
    R[cur] = using
    i=0
    for t in T[cur]:
        if i==using:
            i+=1
        dfs(i,t)
        i+=1


dfs(-1, 0)

print(max(R)+1)
# print(K)
for e in E:
    print(R[e[1]]+1)

# print(K)
import math

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

br = [list(map(int, input().split())) for _ in range(m)]

ans = []

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

subg = {i+1:i+1 for i in range(n)}

nodes = {i+1:1 for i in range(n)}

res = []
r = ncr(n, 2)

def fetch(i):
    if i == subg[i]:
        return i
    j = fetch(subg[i])
    subg[i] = j
    return j

for a, b in reversed(br):
    # print(subg, nodes)

    if len(nodes.keys()) == 1:
        res.append(0)
        continue
    else:
        res.append(r)

    mi, ma = min(a,b), max(a,b)
    
    x = nodes[fetch(mi)] 
    y = nodes[fetch(ma)]

    r += ncr(x, 2) + ncr(y, 2)
    r -= ncr(x+y, 2)
    v, w = max(subg[a], subg[b]), min(subg[a], subg[b])
    nodes[w] += nodes[v]
    del nodes[v] 
    subg[ma] = subg[mi]

for i in reversed(res):
    print(i)



### FIXED CODE ###


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

br = [list(map(int, input().split())) for _ in range(m)]

ans = []

def nc2(n):
    if n<2:
        return 0
    return n * (n-1) // 2


class UnionFind:

    def __init__(self, size):
        self.table = [-1 for _ in range(size+1)]
        self.size = [1 for _ in range(size+1)]

    def find(self, x):
        while self.table[x] >= 0:
            x = self.table[x]
        return x

    def union(self, x, y):
        s1 = self.find(x)
        s2 = self.find(y)
        if s1 != s2:
            if self.table[s1] != self.table[s2]:
                if self.table[s1] < self.table[s2]:
                    self.table[s2] = s1
                    self.size[s1] += self.size[s2]
                    self.size[s2] = 0
                else:
                    self.table[s1] = s2
                    self.size[s2] += self.size[s1]
                    self.size[s1] = 0
            else:
                self.table[s1] += -1
                self.table[s2] = s1
                self.size[s1] += self.size[s2]
                self.size[s2] = 0

    def get_size(self, x):
        s1 = self.find(x)
        return self.size[s1]

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

res = []
r = nc2(n)

uf = UnionFind(n)

for a, b in reversed(br):

    res.append(r)

    if not uf.check_same(a,b):
        r -= uf.get_size(a)*uf.get_size(b)

    uf.union(a,b)

for i in reversed(res):
    print(i)
A, B = map(int, input().split())

divisors = []
for i in range(1, min(A,B) + 1):
	if A % i == 0 and B % i == 0:
		divisors.append(i)


done = {}
def is_coprime(a,b):
	if (a,b) in done:
		return done[a,b]
	if b == 1:
		return True
	for i in range(2, min(A,B)):
		if a % i == 0 and b % i == 0:
			done[(a,b)] = False
			return False
	done[(a,b)] = True
	return True


def getMaxLen(sofar, divisors):
	if len(divisors) == 0:
		return len(sofar)
	curr_max = getMaxLen(sofar,divisors[1:])
	for i in range(len(divisors)):
		d = divisors[i]
		flag = False
		for s in sofar:
			if not is_coprime(d,s):
				flag = True
				break
		if flag:
			continue
		new = sofar.copy()
		
		new.append(d)
		curr_max = max(curr_max, getMaxLen(new, divisors[i+1:]))
	return curr_max

print(getMaxLen([], divisors))


### FIXED CODE ###

n = int(input())
if n % 2 == 0:
	print(0.5)
else:
	print((1 + n//2) / n)
b

### FIXED CODE ###

n,d = map(int,input().split())
pnt = [list(map(int,input().split())) for _ in range(n)]




def dst(i, j):
    a = pnt[i]
    b = pnt[j]
    ret = 0
    for p, q in zip(a, b):
        ret += (p - q) ** 2
    r = ((ret ** (0.5)))

    return r


ans = 0
for i in range(n):
    for j in range(i + 1, n):
        tmp = dst(i, j)
        if tmp == int(tmp):
            ans = ans + 1 

print(ans)
n = int(input())

# alp = ["a","b","c","d","e",
# "f","g","h","i","j",
# "k","l","m","n","o",
# "p","q","r","s","t",
# "u","v","w","x","y","z"]
#
ans = 0
# array1 = np.zeros().reshape( n,10)


# list1 = []
list_s = []

for i in range(n):
    s = input()
    s.sort()
    ans += list_s.count(s)

    list_s.append(s)

print(int(ans))


### FIXED CODE ###

n = int(input())

ans = 0
ans_dict = {}

for i in range(n):
    s = input()
    s = ''.join(sorted(s))
    if(s in ans_dict):
        ans += ans_dict[s]
        ans_dict[s] += 1
    else:
        ans_dict[s] = 1
        
print(int(ans))
import math
from scipy.special import comb
p=[]
d=[i+1for i in range(1,10**5)]
while 1:
    t=d[0]
    if math.sqrt(10**5)<=t:
        p+=d
        break
    p.append(t)
    d=[e for e in d if e%t]
n,m=map(int,input().split())
a=1
while m>1:
    t=p.pop(0)
    if m%t:
        continue
    c=0
    while not m%t:
        m//=t
        c+=1
    a=a*comb(n+c-1,c,exact=1)%(10**9+7)
print(a)

### FIXED CODE ###

import math
import random
from scipy.misc import comb
class Prime:
    seed_primes=[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97]
    def is_prime(self,n):
        is_prime_common=self.is_prime_common(n)
        if is_prime_common is not None:return is_prime_common
        if n<2000000:return self.is_prime_brute_force(n)
        return self.is_prime_miller_rabin(n)
    def is_prime_common(self,n):
        if n==1:return False
        if n in Prime.seed_primes:return True
        if any(map(lambda x:n%x==0,self.seed_primes)):return False
    def is_prime_brute_force(self,n):
        for k in range(2,int(math.sqrt(n))+1):
            if n%k==0:return False
        return True
    def is_prime_miller_rabin(self,n):
        d=n-1
        while d&1==0:d>>=1
        witnesses=self.get_witnesses(n)
        for w in witnesses:
            y=pow(w,d,n)
            while d!=n-1and y!=1and y!=n-1:
                y=y*y%n
                d<<=1
            if y!=n-1and d&1==0:return False
        return True
    def get_witnesses(self,num):
        def _get_range(num):
            if num<2047:return 1
            if num<1373653:return 2
            if num<25326001:return 3
            if num<3215031751:return 4
            if num<2152302898747:return 5
            if num<3474749660383:return 6
            if num<341550071728321:return 7
            if num<3825123056546413051:return 9
            return 12
        return self.seed_primes[:_get_range(num)]
    def gcd(self,a,b):
        if a<b:return self.gcd(b,a)
        if b==0:return a
        while b:a,b=b,a%b
        return a
    @staticmethod
    def f(x,n,seed):
        p=Prime.seed_primes[seed%len(Prime.seed_primes)]
        return(p*x+seed)%n
    def find_factor(self,n,seed=1):
        if self.is_prime(n):return n
        x,y,d=2,2,1
        count=0
        while d==1:
            count+=1
            x=self.f(x,n,seed)
            y=self.f(self.f(y,n,seed),n,seed)
            d=self.gcd(abs(x-y),n)
        if d==n:
            return self.find_factor(n,seed+1)
        return self.find_factor(d)
    def find_factors(self,n):
        primes={}
        if self.is_prime(n):
            primes[n]=1
            return primes
        while n>1:
            factor=self.find_factor(n)
            primes.setdefault(factor,0)
            primes[factor]+=1
            n//=factor
        return primes
n,m=map(int,input().split())
a=1
for c in Prime().find_factors(m).values():
    a=a*comb(n+c-1,c,exact=1)%(10**9+7)
print(a)