Problem:
 Score : 400 points    Problem Statement You are given positive integers N and M .  How many sequences a of length N consisting of positive integers satisfy a_1 \times a_2 \times ... \times a_N = M ? Find the count modulo 10^9+7 .  Here, two sequences a' and a'' are considered different when there exists some i such that a_i' \neq a_i'' .      Constraints  All values in input are integers.  1 \leq N \leq 10^5  1 \leq M \leq 10^9         Input Input is given from Standard Input in the following format:  N  M       Output Print the number of the sequences consisting of positive integers that satisfy the condition, modulo 10^9 + 7 .        Sample Input 1 2 6      Sample Output 1 4  Four sequences satisfy the condition: \{a_1, a_2\} = \{1, 6\}, \{2, 3\}, \{3, 2\} and \{6, 1\} .       Sample Input 2 3 12      Sample Output 2 18       Sample Input 3 100000 1000000000      Sample Output 3 957870001

Solution (Python):
n,m = map(int, input().split())
import math
import collections
def tds(n):
    prime_count = collections.Counter()
    
    for i in range(2, int(math.sqrt(n)) + 2):
        while n % i == 0:
            n /= i
            prime_count[i] += 1
    if n > 1:
        prime_count[n] += 1
    
    return prime_count
c=tds(m)
ans=1
def C(n,r):
    res=1
    for i in range(n,n-r,-1):
        res*=i
    return res//math.factorial(r)
for ci in c.values():
    ans*=C(n+ci-1,ci)
    ans%=10**9+7
print(int(ans))

Solution (Python):
from math import factorial as fac
from collections import defaultdict as ddict
n,m = map(int,input().split())
d = ddict(int)
ans = 1
mod = 10**9+7
def f2(n,r):
  ret = 1
  for i in range(n,n-r,-1):
    ret *= i
  return ret
def cc(n,r):
  t = min(r,n-r)
  return f2(n,t)//fac(t)
for i in range(2,int(m**.5)+1):
  while m % i == 0:
    d[i] += 1
    m //= i
if m > 1:
  d[m] += 1
for x in d:
  ans = ans * cc(d[x]+n-1,d[x])%mod
print(ans)

Solution (Python):
N,M = list(map(int,input().split()))

P = 10**9+7
def get_soinsu(M):
    for i in range(2,1+int(M**0.5)):
        if M%i == 0:
            return [i] + get_soinsu(M//i)
    else:
        return [M]

soinsu = {}
for n in get_soinsu(M):
    soinsu[n] = 1 + soinsu.get(n,0)

def combi(n,r):
    tmp1,tmp2 = (1,1)
    for i in range(n-r+1,n+1):
        tmp1 *= i
    for i in range(2,r+1):
        tmp2 *= i
    return (tmp1//tmp2)%P

out = 1
soinsu.pop(1,None)
for n in soinsu.values():
    out *= combi(N-1+n,n)
    out %= P
print(out)

Solution (Python):
n,m=map(int,input().split())

def prime(n):
    for i in range(2,n):
        if n%i==0:
            return 0
    return 1













def prime_l(n):
    l=[1 for i in range(2,n+1)]
    
    for i in range(n-1):
        if l[i]==1:
            for j in range(2*(i+2),n+1,i+2):
                l[j-2]=0
    l1=[]
    for i in range(n-1):
        if l[i]==1:
            l1.append(i+2)
    return l1


def modpow(a,n,p):
    res=1
    while n>0:
        if n&1:
            res=res*a%p
        a=a*a%p
        n>>=1
        
    return res

if m==1:
    print(1)
else:
    
    
    l=prime_l(int(m**(1/2)))
    
    i=0
    d={}
    while m!=1 and i!=len(l):
        if m%(l[i])==0:
            d[l[i]]=1
            m/=l[i]
            while m%(l[i])==0:
                d[l[i]]+=1
                m/=l[i]
        
        i+=1
        
        
    if m!=1:
        d[m]=1
    
    
    
    
    mod=int(1e9+7)
    n_fac=1
    fac_l=[1]
    d_max=max(d.values())
    
    
    for i in range(n+d_max-1):
        n_fac*=i+1
        n_fac=n_fac%mod
        fac_l.append(n_fac)

    fac_1_l=[]
    for i in range(n+d_max):
        fac_1_l.append(modpow(fac_l[i],mod-2,mod))
    w=1
    for dv in d.values():
        w*=fac_l[n+dv-1]
        w=w%mod
        
        
        
        
        
        
        w=w*fac_1_l[n-1]%mod
        w=w*fac_1_l[dv]%mod
    print(w)

Solution (Python):
from collections import Counter
from scipy.misc import comb
c=Counter()
n,m=map(int,input().split())
t=2

while(t**2 <= m):
    if m%t:
        t+=1
        continue
    while m%t==0:
        c[t]+=1
        m//=t
if m>1:c[m]+=1
a=1

for i in c:
    a=a*comb(n+c[i]-1,n-1,exact=1)%(10**9+7)
print(a)

Solution (Python):
MOD = 10**9+7

MAX = 10**6
fac = [0]*MAX  
finv = [0]*MAX 
inv = [0]*MAX  

def comb_init():
    global fac, finv, inv
    fac[0] = fac[1] = 1
    finv[0] = finv[1] = 1
    inv[1] = 1
    for i in range(2, MAX):
        fac[i] = fac[i-1] * i % MOD
        inv[i] = MOD - inv[MOD%i] * (MOD//i)%MOD
        finv[i] = finv[i-1] * inv[i] % MOD

def comb(n:int, r:int)->int:
    global fac, finv
    if n < r: return 0
    if n < 0 or r < 0: return 0
    return fac[n] * (finv[r] * finv[n-r] % MOD) % MOD

if __name__ == '__main__':
    N,M = map(int, input().split())
    ans = 1
    comb_init()
    
    
    i=2
    nokori = M
    while i*i <= nokori:
        if nokori%i==0:
            cnt = 0
            while nokori%i==0:
                cnt += 1
                nokori //= i
            ans *= comb(N+cnt-1, N-1)
            ans %= MOD
        i += 1
            
    if nokori != 1:
        ans *= comb(N+1-1, N-1)
        ans %= MOD
        
    print(ans)

Solution (Python):
MOD = 10**9+7
    
def comb(a:int, b:int):
    if b > a-b: return comb(a, a-b)
    mul = 1
    div = 1
    for i in range(b):
        mul *= a-i
        div *= i+1
        mul %= MOD
        div %= MOD
        
    ret = mul * pow(div, MOD-2, MOD)
    return ret

if __name__ == '__main__':
    N,M = map(int, input().split())
    ans = 1
    
    
    i=2
    nokori = M
    while i*i <= nokori:
        if nokori%i==0:
            cnt = 0
            while nokori%i==0:
                cnt += 1
                nokori //= i
            ans *= comb(N+cnt-1, N-1)
            ans %= MOD
        i += 1
            
    if nokori != 1:
        ans *= comb(N+1-1, N-1)
        ans %= MOD
        
    print(ans)

Solution (Python):
MOD = 10**9+7

def modpow(a:int, p:int)->int:
    
    if p==0: return 1
    if p%2==0:
        half_p = p//2
        half = modpow(a, half_p)
        return half*half % MOD
    else:
        return a * modpow(a, p-1) % MOD
    
def comb(a:int, b:int):
    if b > a-b: return comb(a, a-b)
    mul = 1
    div = 1
    for i in range(b):
        mul *= a-i
        div *= i+1
        mul %= MOD
        div %= MOD
        
    ret = mul * modpow(div, MOD-2) % MOD
    return ret

if __name__ == '__main__':
    N,M = map(int, input().split())
    ans = 1
    
    
    i=2
    nokori = M
    while i*i <= nokori:
        if nokori%i==0:
            cnt = 0
            while nokori%i==0:
                cnt += 1
                nokori //= i
            ans *= comb(N+cnt-1, N-1)
            ans %= MOD
        i += 1
            
    if nokori != 1:
        ans *= comb(N+1-1, N-1)
        ans %= MOD
        
    print(ans)

Solution (Python):
import sys
sys.setrecursionlimit(10**7)
INF = 10 ** 18
MOD = 10 ** 9 + 7
def LI(): return [int(x) for x in sys.stdin.readline().split()]
def LI_(): return [int(x) - 1 for x in sys.stdin.readline().split()]
def LF(): return [float(x) for x in sys.stdin.readline().split()]
def LS(): return sys.stdin.readline().split()
def II(): return int(sys.stdin.readline())
def SI(): return input()
from collections import Counter
from itertools import product
from math import factorial


primes = list(range(int(10**5) + 1))
primes[1] = 0
for i in range(2, int(len(primes) ** 0.5) + 1):
    if primes[i]:
        for j in range(2 * i, len(primes), i):
            primes[j] = 0

def main():
    N, M = LI()
    
    factors = Counter()
    for i in range(int(M ** 0.5) + 1):
        if primes[i]:
            while M % i == 0:
                factors[i] += 1
                M //= i
        if M < i:
            break
    if M != 1:
        factors[M] += 1
    ans = 1
    for k in factors.values():
        a, b = 1, 1
        for i in range(1, k + 1):
            a *= N + k - i
            b *= i
        ans = (ans * (a // b)) % MOD

    return ans % MOD

print(main())

Solution (Python):
import collections
import math
n, m = [int(item) for item in input().split()]

def trial_division_sqrt(n):
    prime_count = collections.Counter()
    for i in range(2, int(math.sqrt(n)) + 2):
        while n % i == 0:
            n /= i
            prime_count[i] += 1
    if n > 1:
        prime_count[int(n)] += 1
    return prime_count

cnt = trial_division_sqrt(m)

ans = 1
for item in cnt:
  h = 1
  k_fact = 1
  for i in range(cnt[item]):
    h *= n + cnt[item] - 1 - i
    k_fact *= (i+1)
  ans *= h
  ans = ans // k_fact
  ans = ans % (1000000000 + 7)
print(ans)

Solution (Python):

from collections import defaultdict
from collections import deque
from heapq import heappush, heappop
import sys
import math
import bisect
import random
def LI(): return list(map(int, sys.stdin.readline().split()))
def I(): return int(sys.stdin.readline())
def LS():return list(map(list, sys.stdin.readline().split()))
def S(): return list(sys.stdin.readline())[:-1]
def IR(n):
    l = [None for i in range(n)]
    for i in range(n):l[i] = I()
    return l
def LIR(n):
    l = [None for i in range(n)]
    for i in range(n):l[i] = LI()
    return l
def SR(n):
    l = [None for i in range(n)]
    for i in range(n):l[i] = S()
    return l
def LSR(n):
    l = [None for i in range(n)]
    for i in range(n):l[i] = SR()
    return l
mod = 1000000007
sys.setrecursionlimit(1000000)


def A():
    return


def B():
    return


def C():
    s = S()
    t = S()
    n = len(s)
    d = defaultdict(list)
    for i in range(n):
        d[s[i]].append(t[i])
    d2 = defaultdict(list)
    for i in range(n):
        d2[t[i]].append(s[i])
    for i in d.keys():
        k = d[i]
        k = list(set(d[i]))
        if len(k) > 1:
            print("No")
            quit()
    for i in d2.keys():
        k = d2[i]
        k = list(set(d2[i]))
        if len(k) > 1:
            print("No")
            quit()
    print("Yes")

def D():
    n,m = LI()
    if m == 1:
        print(1)
        quit()
    d = defaultdict(int)
    i = 2
    a = m
    while i**2 <= m:
        if not a%i:
            while not a%i:
                a//=i
                d[i] += 1
        i += 1
    if a != 1:
        d[a] += 1
    fact = [1 for i in range(n+31)]
    for i in range(n+30):
        fact[i+1] = fact[i]*(i+1)%mod
    inv_fact = [None for i in range(n+31)]
    inv_fact[n+30] = pow(fact[n+30],mod-2,mod)
    for i in range(n+30)[::-1]:
        inv_fact[i] = inv_fact[i+1]*(i+1)%mod
    ans = 1
    for i in d.values():
        ans *= fact[i+n-1]*inv_fact[i]*inv_fact[n-1]%mod
        ans %= mod
    print(ans)

def E():
    return


def F():
    return


def G():
    return


def H():
    return


if __name__ == "__main__":
    D()

Solution (Python):

import sys
import math
import collections

MOD = 1000000007  


def trial_division_sqrt(n):
    prime_count = collections.Counter()
    for i in range(2, int(math.sqrt(n)) + 2):
        while n % i == 0:
            n /= i
            prime_count[i] += 1
    if n > 1:
        prime_count[int(n)] += 1

    return prime_count


def cmb(n, r):
    r = min(r, n-r)
    if r == 0:
        return 1
    if r == 1:
        return n

    numer = [n - r + k + 1 for k in range(r)]
    denom = [k + 1 for k in range(r)]

    for p in range(2, r+1):
        pivot = denom[p - 1]
        if pivot > 1:
            offset = (n - r) % p
            for k in range(p-1, r, p):
                numer[k - offset] /= pivot
                denom[k] /= pivot

    result = 1
    for k in range(r):
        if numer[k] > 1:
            result *= int(numer[k])

    return result


def solve(N: int, M: int):
    pc = trial_division_sqrt(M)
    ans = 1
    for c in pc:
        ans = (ans * cmb(pc[c]+N-1, pc[c])) % MOD
    print(int(ans))
    return



def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    N = int(next(tokens))  
    M = int(next(tokens))  
    solve(N, M)


if __name__ == '__main__':
    main()

Solution (Python):
from collections import defaultdict
c=defaultdict(int)
n,m=map(int,input().split())
for i in range(2,int(m**0.5)+1):
    if m%i==0:
        d=0
        while m%i==0:
            d+=1
            m//=i
        else:
            c[i]+=d
            if m==1:
                break
if m!=1:
    c[m]+=1
def comb(x, y):
    y = min(y, x - y)
    a = 1
    for i in range(x, x - y, -1):
        a *= i
    b = 1
    for i in range(1, y + 1):
        b *= i
    return a // b
a=1
for i in c.values():
    a=comb(n+i-1,i)*a%(10**9+7)
print(a)

Solution (Python):
import sys
from collections import deque
import copy
import math
def get_read_func(fileobject):
    if fileobject == None :
        return raw_input
    else:
        return fileobject.readline

def prime_decomposition(n):
  i = 2
  table = []
  while i * i <= n:
    while n % i == 0:
      n /= i
      table.append(i)
    i += 1
  if n > 1:
    table.append(n)
  return table

def power_func(a,b,p):
  if b==0: return 1
  if b%2==0:
    d=power_func(a,b//2,p)
    return d*d %p
  if b%2==1:
    return (a*power_func(a,b-1,p ))%p

class comb_calclator():
    def __init__(self, N, p):
        self.N = N
        self.p = p
        self.frac_N = [0 for i in range(N + 1)]
        self.frac_N[0] = 1L
        self.comb_N = {}
        for i in range(1, N + 1):
            self.frac_N[i] = (self.frac_N[i - 1] * i ) % p

    def comb(self, n, r):
        if n<0 or r<0 or n<r: return 0
        if n==0 or r==0: return 1
        if (n, r) in self.comb_N:
            return self.comb_N[(n, r)]
        a = self.frac_N[n]
        b = self.frac_N[r]
        c = self.frac_N[n - r]
        self.comb_N[(n, r)] = (a*power_func(b,self.p-2,self.p)*power_func(c,self.p-2, self.p))% self.p
        self.comb_N[(n, n - r)] = self.comb_N[(n, r)]
        return self.comb_N[(n, r)]


def main():
    if len(sys.argv) > 1:
        f = open(sys.argv[1])
    else:
        f = None
    read_func = get_read_func(f);
    input_raw = read_func().strip().split()
    [N, M] = [int(input_raw[0]), long(input_raw[1])]
    prime = prime_decomposition(M)
    prime_num = {}
    for p in prime:
        if p not in prime_num:
            prime_num[p] = 1
        else:
            prime_num[p] += 1

    cmb = comb_calclator(N * 10, 1000000007)
    count = 1L
    for p in prime_num:
        count = (count * cmb.comb(N + prime_num[p]- 1, prime_num[p])) % 1000000007

    print count
if __name__ == '__main__':
    main()

Solution (Python):
n, m = map(int, input().split())

yd = {}
i = 2
while m != 1:
  while m % i == 0:
    if i in yd:
      yd[i] += 1
    else:
      yd[i] = 1
    m //= i
  i += 1

ans = 1
for v in yd.values():
  start = v + n - 1
  c = 1
  for _ in range(v):
    c *= start
    start -= 1
  d = 1
  for _v in range(v):
    d *= (_v + 1)
  ans *= (c // d)
print(ans % 1000000007)

Solution (Python):
N, M = map(int, input().split())
mod = 10**9 + 7


def factorize(n):
    b = 2
    fct = {}
    while b * b <= n:
        while n % b == 0:
            n //= b
            if b in fct.keys():
                fct[b] += 1
            else:
                fct[b] = 1
        b = b + 1
    if n > 1:
        fct[n] = 1
    return fct


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


fac_list = factorize(M)
ans = 1
for k, v in fac_list.items():
    ans *= cmb(v+N-1, v)
    if ans >= mod:
        ans %= mod

print(int(ans))

Solution (Python):
import math
def prime_factor(n):
    ass = []
    for i in range(2,int(n**0.5)+1):
        while n % i==0:
            ass.append(i)
            n = n//i
    if n != 1:
        ass.append(n)
    return ass
N,M = map(int,input().split())
L = prime_factor(M)
L.append(0)
K = []
cur = L[0]
cnt = 0
for i in range(len(L)):
  if cur == L[i]:
    cnt += 1
  else:
    K.append(cnt)
    cnt = 1
    cur = L[i]
ans = 1
for i in range(len(K)):
  n = K[i]+N-1
  k = N-1
  cur = 1
  for i in range(k+1,n+1):
    cur *= i
  for j in range(1,n-k+1):
    cur = cur//j
  ans *= cur%(10**9+7)
print(ans%(10**9+7))

Solution (Python):
a,b=map(int,input().split())


from collections import Counter
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

def factorize(n):
    b = 2
    fct = []
    while b * b <= n:
        while n % b == 0:
            n //= b
            fct.append(b)
        b += 1
    if n > 1:
        fct.append(n)
    return fct
if len(factorize(b))==0:
    print(1)
    exit()

mod=10**9+7
print(reduce(mul,map(lambda x:cmb(a-1+x,a-1),Counter(factorize(b)).values()))%mod)

Solution (Python):


def modpow(a,p):
    mod = 1000000007
    if p==0:
        return 1
    elif p%2==0:
        halfP = p/2
        half = modpow(a,halfP)
        return half * half %mod
    else:
        return a * modpow(a,p-1) % mod
    
def calccomb(a,b):
    mod = 1000000007
    if b>a-b:
        return calccomb(a,a-b)
    ansMul = 1
    ansDiv = 1
    for i in range(b):
        ansMul *= a-i
        ansDiv *= i+1
        ansMul %= mod
        ansDiv %= mod
    
    ans = ansMul * modpow(ansDiv, mod-2)
    return ans
  
import math
N ,M =map(int,input().split())
Mnokori = M
ans = 1
for i in range(2,int(math.sqrt(Mnokori))+1):
    if Mnokori % i == 0:
        cnt = 0
        while Mnokori % i == 0:
            cnt = cnt + 1
            Mnokori /= i
        ans *= calccomb(N+cnt-1,N-1)
        ans %= 1000000007
if Mnokori != 1:
    ans *= calccomb(N+1-1,N-1)
    ans %=  1000000007
print(ans)

Solution (Python):
n,m = map(int,input().split())
def div(x,y):
    if x%y!=0:
        return 0
    else:
        return 1+div(int(x/y),y)

p=[]
q=[]

def fact(s):
    if len(p)!=0:
        k=p[-1]
    else:
        k=2
    for i in range(2,max(int(s**0.5) +2,2)):
        a=div(s,i)
        if a==0:
            0
        else:
            p.append(a)
            q.append(i)
            s=int(s/i**a)
    if s!=1:
        p.append(1)
            
fact(m)
def comb(nn,rr):
    rr=min(rr,nn-rr)
    rt=1
    for i in range(rr):
        
        rt*=(nn-i)
    for i in range(rr):
        rt//=(rr-i)
    return int(rt)

mo=10**9 +7
ans=1
if len(p)==0:
    ans=1
else:
    for i in p:
        ans*=comb(i+n-1, i) % mo
print(ans % mo)

Solution (Python):
N,M=map(int,input().split())
a=[]
ans=1
def calc(n):
    for i in range(2,int(n**0.5)+10):
        count=0
        while n%i==0:
            n//=i
            count+=1
        if count>=1:
            a.append([i,count])
    if n!=1:
        a.append([n,1])
calc(M)
def cmb(n, r):
    if n - r < r: r = n - r
    if r == 0: return 1
    if r == 1: return n

    numerator = [n - r + k + 1 for k in range(r)]
    denominator = [k + 1 for k in range(r)]

    for p in range(2,r+1):
        pivot = denominator[p - 1]
        if pivot > 1:
            offset = (n - r) % p
            for k in range(p-1,r,p):
                numerator[k - offset] /= pivot
                denominator[k] /= pivot

    result = 1
    for k in range(r):
        if numerator[k] > 1:
            result *= int(numerator[k])

    return result
for i in range(len(a)):
    ans*=cmb(a[i][1]+N-1,a[i][1])
print(ans%(10**9+7))

Solution (Python):
from collections import defaultdict

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

MOD = 1000000007


TABLE_NUM = 10001 + N
facts = [0 for _ in range(TABLE_NUM)]
invs = [0 for _ in range(TABLE_NUM)]
finvs = [0 for _ in range(TABLE_NUM)]
def create_table():
    facts[0] = facts[1] = 1
    invs[0] = invs[1] = 1
    finvs[0] = finvs[1] = 1
    for i in range(2, TABLE_NUM):
        facts[i] = facts[i - 1] * i % MOD
        invs[i] = MOD - invs[MOD % i] * (MOD // i) % MOD
        finvs[i] = finvs[i - 1] * invs[i] % MOD
create_table()

def comb(n, k):
    if n < k:
        return 0
    if n < 0 or k < 0:
        return 0
    return facts[n] * (finvs[k] * finvs[n - k] % MOD) % MOD



prime_dict = defaultdict(int)
primes = []
n = 2
m = M
M_ROOT = int(M ** 0.5)
while m > 1 and n <= M_ROOT:
    if m % n == 0:
        prime_dict[n] += 1
        primes.append(n)
        m = m // n
        continue
    n += 1

if m > M_ROOT:
    primes.append(m)
    prime_dict[m] += 1







ans = 1
for k in prime_dict.keys():
    v = prime_dict[k]
    count = comb(v + N - 1, N - 1)
    ans = (ans * count) % MOD
print(ans)

Solution (Python):

def sieve(x):
    if x < 2: return []
    primes = [i for i in range(x)]
    primes[1] = 0
    for p in primes:
        if p > x ** (1/2): break
        if p == 0: continue
        for np in range(2 * p, x, p): primes[np] = 0
    return [p for p in primes if p != 0]

PS = sieve(10**6)


def factorint(x):
  d = {}
  for k in PS:
    if(x % k== 0):
      m = 1
      while(x % (k**m) == 0):
        m += 1
      d[k] = m - 1
      x = x / (k ** (m - 1))
      if x == 1:
        break
  return d

n, m = map(int, input().split())
f = factorint(m)
idx = [i for i in f.values()]

re = 1
for k, v in f.items():
  re *= k**v
if m // re != 1:
  idx.append(1)


def fact(n):
  ret = 1
  for i in range(1, n + 1):
    ret *= i
  return ret
def com(n, r):
  if n - r < r: r = n - r
  ret = 1
  for i in range(n-r+1, n+1):
    ret *= i
  for j in range(1, r+1):
    ret //= j
  return ret

ans = 1
for i in range(len(idx)):
  ans *= com(idx[i] + n - 1, n - 1) % (10 ** 9 + 7)

  
print(ans % (10 ** 9 + 7))

Solution (Python):
n, m = map(int, input().split())
mod = 10**9+7

def prime_decomposition(n):
    p = 2
    prime = {}
    while n!=1:
        while n%p == 0:
            n = n//p
            if p not in prime:
                prime[p] = 0
            prime[p] += 1
        p += 1
    return prime

primes = prime_decomposition(m)

ans = 1

def combination(n,k):
    ret1 = 1
    ret2 = 1
    for i in range(k):
        ret1 *= n-i
        ret2 *= k-i
    return ret1//ret2

for pw in primes.values():
    comb = combination(pw+n-1, pw)
    ans *= comb
    ans %= mod

print(ans)

Solution (Python):
N,M=map(int,input().split())
rM=M**(1/2)
MOD=10**9+7
i=2
s=0
ans=1
while i<=rM:
  if M%i==0:
    M=M//i
    s+=1
  elif s!=0:
    comb=1
    for j in range(s+N-1,N-1,-1):
      comb*=j
    for j in range(s,0,-1):
      comb//=j
    ans*=comb
    ans%=MOD
    i+=1
    s=0
  else:
    i+=1
if M!=1:
  ans*=N
  ans%=MOD
print(ans)

Solution (Python):
def prime_factorize(num):
    
    prime_factor = {}
    i = 2
    while i ** 2 <= num:
        while num % i == 0:
            num //= i
            if i in prime_factor.keys():
                prime_factor[i] += 1
            else:
                prime_factor[i] = 1
        i += 1
    if num > 1:
        prime_factor[num] = 1
    return prime_factor
def combination(n, r):
    
    r = min(n-r, r)
    result = 1
    for i in range(n, n-r, -1):
        result *= i
    for i in range(1, r+1):
        result //= i
    return result


n, m = map(int, input().split())
MOD = 10**9 + 7
P = prime_factorize(m)
ans = 1
for prime in P:
    k = combination(P[prime] + n - 1, P[prime]) % MOD
    ans *= k
    ans %= MOD

print(ans)

Solution (Python):
from math import sqrt


def prime_facts(n: int) -> dict:
    res = {}
    d = 2
    while d * d <= n:
        if n % d == 0:
            res[d] = 1
            n //= d

            while n % d == 0:
                res[d] += 1
                n //= d

        if d == 2:
            d += 1
        else:
            d += 2

    if n > 1:
        res[n] = 1

    return res


def factorization(N: int, M: int) -> int:
    """以下の説明において、F(N, M) はこの関数と同値。

    `a1 x a2 x ... x aN = M (式 1)`
    となる数列 {aN} の組み合わせ数を F(N, M) とする。

    まず、(式 1)より {aN} は全て M の約数であることは明らか。

    ここで、M の約数列を {dm} とする。今、aN = di とすると、
    `a1 x a2 x ... x a{N-1} = M // di`
    が成り立ち、これを満たす数列 {a{N-1}} の組み合わせ数は F(N-1, M//di) である。

    aN は任意の di を取れるので、結局、
    `F(N, M) = sigma{di} F(N-1, M//di) = sigma{di} F(N-1, M)` (式 2)
    が成り立つ。

    さらに、M を場合分けして考える。

    M = 1 のとき、(式 2)より
    `F(N, 1) = F(N-1, 1) = ... = F(1, 1) = 1` (式 3)
    が成り立つ。

    M = p (p は素数)のとき、(式 2)と(式 3)より、
    `F(N, p) = F(N-1, p) + F(N-1, 1) = F(N-1, p) + 1`
    が成り立つ。この漸化式をとけば、
    `F(N, p) = N`
    が成り立つ。

    M = p^k (p は素数)の時、めんどくさい計算の果てに
    `F(N, p^k) = PI{i=0}{k-1}(N+i) / k!`
    が成り立つ。

    M = p1...pk (pi は全て異なる素数)の時、めんどくさい計算の果てに
    `F(N,p1...pk) = N^k`

    M = p1^k1 ... pm^km (pi は全て異なる素数)の時、めんどくさい計算の果てに
    `F(N,p1^k1...pm^km) = F(N,p1^k1)...F(N,pm^km)`
    が成り立つ。
    """
    
    pi = [1] * 101
    fact = [1] * 101
    for i in range(1, 101):
        pi[i] = (N+i-1) * pi[i-1]
        fact[i] = i * fact[i-1]

    primes = prime_facts(M)
    ret = 1
    for k in primes.values():
        ret *= pi[k] // fact[k]

    return ret % 1000000007


if __name__ == "__main__":
    N, M = map(int, input().split())
    ans = factorization(N, M)
    print(ans)

Solution (Python):
ri = lambda: int(input())
rl = lambda: list(map(int,input().split()))
rr = lambda N: [ri() for _ in range(N)]
YN = lambda b: print('YES') if b else print('NO')
yn = lambda b: print('Yes') if b else print('No')
OE = lambda x: print('Odd') if x%2 else print('Even')
INF = 10**18

N,M=rl()
DIV = 10**9 + 7

def factorize(n):
    fct = []  
    b, e = 2, 0  
    while b * b <= n:
        while n % b == 0:
            n = n // b
            e = e + 1
        if e > 0:
            fct.append((b, e))
        b, e = b + 1, 0
    if n > 1:
        fct.append((n, 1))
    return fct

l = factorize(M)

ans = 1
for _, i in l:
    res = 1
    for j in range(i):
        res *=(N-1+i-j)
    for j in range(i):
        res = res//(j+1)
    ans *= res
    ans %= DIV

print(ans)

Solution (Python):
ri = lambda: int(input())
rl = lambda: list(map(int,input().split()))
rr = lambda N: [ri() for _ in range(N)]
YN = lambda b: print('YES') if b else print('NO')
yn = lambda b: print('Yes') if b else print('No')
OE = lambda x: print('Odd') if x%2 else print('Even')
INF = 10**18

N,M=rl()
DIV = 10**9 + 7

def factorize(n):
    fct = []  
    b, e = 2, 0  
    while b * b <= n:
        while n % b == 0:
            n = n // b
            e = e + 1
        if e > 0:
            fct.append((b, e))
        b, e = b + 1, 0
    if n > 1:
        fct.append((n, 1))
    return fct

l = factorize(M)

ans = 1
for _, i in l:
    res = 1
    for j in range(i):
        res *=(N-1+i-j)%DIV
    for j in range(i):
        res = res//(j+1)
    ans *= res
    ans %= DIV

print(ans)

Solution (Python):
N, M = [int(i) for i in input().split()]

import math
import random
from itertools import permutations, combinations

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):
        """
        prime test (hybrid)

        see also: https://qiita.com/gushwell/items/ff9ed83ba55350aaa369

        :param n:
        :return: boolean
        """
        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)
        else:
            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):
        """
        brute force prime test
        use with is_prime_common if you want to skip seed_primes

        :param n:
        :return: boolean
        """
        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):
        """
        miller rabin prime test
        use with is_prime_common if you want to skip seed_primes

        see also
            algorithm: https://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test
            implementation: https://qiita.com/srtk86/items/609737d50c9ef5f5dc59
            improvement: https://qiita.com/gushwell/items/ff9ed83ba55350aaa369

        :param n:
        :return: boolean
        """

        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 - 1 and y != 1 and y != n - 1:
                y = (y * y) % n
                d <<= 1

            if y != n - 1 and 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):
        """
        pseudo prime generator
        :param x:
        :param n:
        :param seed:
        :return: pseudo prime
        """
        p = Prime.seed_primes[seed % len(Prime.seed_primes)]
        return (p * x + seed) % n

    def find_factor(self, n, seed=1):
        """
        find one of factor of n
        this function is based to Pollard's rho algorithm

        see also
            algorithm: https://en.wikipedia.org/wiki/Pollard%27s_rho_algorithm
            implementation: https://qiita.com/gushwell/items/561afde2e00bf3380c98

        :param n:
        :param seed:
        :return: factor
        """
        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


prime = Prime()
fact_dict = prime.find_factors(M)

def cmb(n, r):
    if n - r < r: r = n - r
    if r == 0: return 1
    if r == 1: return n

    numerator = [n - r + k + 1 for k in range(r)]
    denominator = [k + 1 for k in range(r)]

    for p in range(2,r+1):
        pivot = denominator[p - 1]
        if pivot > 1:
            offset = (n - r) % p
            for k in range(p-1,r,p):
                numerator[k - offset] /= pivot
                denominator[k] /= pivot

    result = 1
    for k in range(r):
        if numerator[k] > 1:
            result *= int(numerator[k])

    return result

result = 1
for val in fact_dict.values():
    result *= cmb(N + val - 1, val)
print(result % (10**9+7))