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):
import sys
import math
sys.setrecursionlimit(1000000) 

def calc_combi(n, m, mod=1000000007):
    """ nCmの組み合わせ数を数える """
    if n - m < m:
        return calc_combi(n, n - m)

    ans_mull, ans_div = 1, 1
    for i in range(m):
        ans_mull *= (n - i)
        ans_div *= (i + 1)
        ans_mull %= mod
        ans_div %= mod
    ans = ans_mull * pow(ans_div, mod - 2, mod) % mod
    return ans

def main():
    input = sys.stdin.readline  
    N, M = map(int, input().rstrip().split())
    mod = 1000000007

    ans = 1
    for i in range(2, math.ceil(math.sqrt(M))):
        if M % i == 0:
            count = 0
            while M % i == 0:
                M /= i
                count += 1
            ans *= calc_combi(count + N - 1, N - 1, mod)
            ans %= mod
    if M != 1:
        ans *= calc_combi(N, 1, mod)
        ans %= mod
    print(ans)

if __name__ == '__main__':
    main()

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):
inf = 10**15
mod = 10**9+7




def ruijo(n, l, mod):
    a = n
    tmp = n - 1
    while (tmp >= l):
        a = a * tmp % mod
        tmp -= 1
    return a


def cmb(n, r, mod):
    if r == 1:
        return n
    elif (n == r or r == 0):
        return 1
    else:
        if (r < 0 or r > n):
            return 0
        r = min(r, n - r)
        return ruijo(n, n - r + 1, mod) * g2[r] % mod


mod = 10 ** 9 + 7  
N = 10 ** 6
g1 = [1, 1]  
g2 = [1, 1]  
inverse = [0, 1]  

for i in range(2, N + 1):
    g1.append((g1[-1] * i) % mod)
    inverse.append((-inverse[mod % i] * (mod // i)) % mod)
    g2.append((g2[-1] * inverse[-1]) % mod)

"""nを素因数分解"""
"""2以上の整数n => [[素因数, 指数], ...]の2次元リスト"""
def factorization(n):
    arr = []
    temp = n
    if n == 1:
        return arr

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

    if temp!=1:
        arr.append([temp, 1])

    if arr==[]:
        arr.append([n, 1])

    return arr

n,m = map(int, input().split())
if m == 1:
    print(1)
else:
    bpre = factorization(m)
    ans = 1
    for tmp in bpre:
        b = tmp[1]
        ans *= cmb(n-1+b, n-1, mod)
        ans = ans%mod
    print(ans)

Solution (Python):
import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines
sys.setrecursionlimit(10 ** 7)

from collections import Counter


class Combination:
    def __init__(self, n):
        self.fac = [1] * (n + 1)
        for i in range(1, n + 1):
            self.fac[i] = (self.fac[i - 1] * i) % mod
        self.invmod = [1] * (n + 1)
        self.invmod[n] = pow(self.fac[n], mod - 2, mod)
        for i in range(n, 0, -1):
            self.invmod[i - 1] = (self.invmod[i] * i) % mod

    def calc(self, n, k):  
        return self.fac[n] * self.invmod[k] % mod * self.invmod[n - k] % mod


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


n, m = map(int, read().split())
mod = 10 ** 9 + 7
comb = Combination(n + 30)
ans = 1
for v in Counter(prime_decomposition(m)).values():
    ans *= comb.calc(n + v - 1, v)
    ans %= mod
print(ans)

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

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

    if temp != 1:
        arr.append([temp, 1])

    if arr == []:
        arr.append([n, 1])

    return arr

kaijo_memo = []
def kaijo(n):
  if(len(kaijo_memo) > n):
    return kaijo_memo[n]
  if(len(kaijo_memo) == 0):
    kaijo_memo.append(1)
  while(len(kaijo_memo) <= n):
    kaijo_memo.append(kaijo_memo[-1] * len(kaijo_memo) % MOD)
  return kaijo_memo[n]
 
gyaku_kaijo_memo = []
def gyaku_kaijo(n):
  if(len(gyaku_kaijo_memo) > n):
    return gyaku_kaijo_memo[n]
  if(len(gyaku_kaijo_memo) == 0):
    gyaku_kaijo_memo.append(1)
  while(len(gyaku_kaijo_memo) <= n):
    gyaku_kaijo_memo.append(gyaku_kaijo_memo[-1] * pow(len(gyaku_kaijo_memo),MOD-2,MOD) % MOD)
  return gyaku_kaijo_memo[n]
 
def nCr(n,r):
  if(n == r):
    return 1
  if(n < r or r < 0):
    return 0
  ret = 1
  ret = ret * kaijo(n) % MOD
  ret = ret * gyaku_kaijo(r) % MOD
  ret = ret * gyaku_kaijo(n-r) % MOD
  return ret

if M == 1:
    print(1)
else:
    fac = factorization(M)
    ans = 1
    for i in fac:
        ans = (ans * nCr(i[1]+N-1,i[1]))%MOD
    print(ans)

Solution (Python):

from collections import Counter


def ncr(n, r, mod):
    ret = 1
    for i in range(1, r+1):
        ret = (ret * (n-i+1) * pow(i, mod-2, mod)) % mod
    return ret


def solve(*args: str) -> str:
    n, m = map(int, args[0].split())
    mod = 10**9+7
    C = Counter()

    i = 2
    r = -int(-m**(1/2)//1)
    while 1 < m:
        while m % i == 0:
            C[i] += 1
            m //= i
        if r < i:
            C[m] = 1
            break
        i += 1

    ret = 1
    for v, c in C.items():
        ret *= ncr(n+c-1, min(n-1, c), mod)
        ret %= mod

    return str(ret)


if __name__ == "__main__":
    print(solve(*(open(0).read().splitlines())))

Solution (Python):


import sys
import math





















def main():
    mod = 1000000007                
    inf = float('inf')              
    
    sys.setrecursionlimit(10**6)    
    def input(): return sys.stdin.readline().rstrip()
    def ii():    return int(input())
    def mi():    return map(int, input().split())
    def mi_0():  return map(lambda x: int(x)-1, input().split())
    def lmi():   return list(map(int, input().split()))
    def lmi_0(): return list(map(lambda x: int(x)-1, input().split()))
    def li():    return list(input())
    
        
    class Eratos:
        def __init__(self, num):
            assert(num >= 1)
            self.table_max = num
            
            self.table = [False if i == 0 or i == 1 else True for i in range(num+1)]
            for i in range(2, int(math.sqrt(num)) + 1):
                if self.table[i]:
                    for j in range(i ** 2, num + 1, i):    
                        self.table[j] = False
            
            self.prime_numbers = [2] if self.table_max >= 2 else []
            for i in range(3, self.table_max + 1, 2):
                if self.table[i]:
                    self.prime_numbers.append(i)
        
        def is_prime(self, num):
            """
            >>> e = Eratos(100)
            >>> [i for i in range(1, 101) if e.is_prime(i)]
            [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]
            """
            assert(num >= 1)
            if num > self.table_max:
                raise ValueError('Eratos.is_prime(): exceed table_max({}). got {}'.format(self.table_max, num))
            return self.table[num]
        
        def prime_factorize(self, num):
            """
            >>> e = Eratos(10000)
            >>> e.prime_factorize(6552)
            {2: 3, 3: 2, 7: 1, 13: 1}
            """
            assert(num >= 1)
            if int(math.sqrt(num)) > self.table_max:
                raise ValueError('Eratos.prime_factorize(): exceed prime table size. got {}'.format(num))
            factorized_dict = dict()    
            candidate_prime_numbers = [i for i in range(2, int(math.sqrt(num)) + 1) if self.is_prime(i)]
            
            
            for p in candidate_prime_numbers:
                
                if num == 1:
                    break
                while num % p == 0:
                    num //= p
                    try:
                        factorized_dict[p]
                    except KeyError:
                        factorized_dict[p] = 0
                    finally:
                        factorized_dict[p] += 1
            if num != 1:
                factorized_dict[num] = 1
            return factorized_dict
    

    n, m = mi()
    eratos = Eratos(max(int(math.sqrt(m)), n))
    d = eratos.prime_factorize(m)
    

    FACT = [1] * (n + int(math.log2(m)) + 1)
    for i in range(2, n + int(math.log2(m)) + 1):
        FACT[i] = (FACT[i-1] * i) % mod
    
    def comb(n, r, m):
        numerator = FACT[n]
        denominator = pow(FACT[n-r] * FACT[r], m - 2, m)
        return (numerator * denominator) % m

    ans = 1
    for _, k in d.items():
        ans = (ans * comb(k + n - 1, k, mod)) % mod
    print(ans)


if __name__ == "__main__":
    main()

Solution (Python):
from collections import Counter


def prime_factorize(n):
    a = []
    while n % 2 == 0:
        a.append(2)
        n //= 2
    f = 3
    while f * f <= n:
        if n % f == 0:
            a.append(f)
            n //= f
        else:
            f += 2
    if n != 1:
        a.append(n)
    return a

def main():
    N, M = map(int, input().split())

    MOD = 10**9 + 7
    

    MAX_N = 5 * (10 ** 5)
    
    fac = [0] *  MAX_N
    finv = [0] *  MAX_N 
    inv = [0] *  MAX_N

    fac[0] = 1; fac[1] = 1
    finv[0] = 1; finv[1] = 1
    inv[1] = 1

    for i in range(2, MAX_N):
        fac[i] = fac[i-1] * i % MOD
        inv[i] = -inv[MOD%i] * (MOD//i) % MOD
        finv[i] = finv[i-1] * inv[i] % MOD
    
    def COM(n, k):
        if n < k : return 0
        if n < 0 or k < 0 : return 0
        return (fac[n] * finv[n-k] % MOD) * finv[k] % MOD

    
    pf = prime_factorize(M)
    pc = Counter(pf)

    ans = 1
    for _, val in pc.items():
        ans *= COM(val + N - 1, N - 1)
        ans %= MOD
    print(ans)


if __name__ == "__main__":
    main()

Solution (Python):
from collections import defaultdict

def prime_factors(n):
    d = defaultdict(int)
    while n%2 == 0:
        d[2] += 1
        n //= 2
    i = 3
    while i*i <= n:
        while n%i == 0:
            d[i] += 1
            n //= i
        i += 2
    if n > 2:
        d[n] += 1
    return d


MOD = 10**9+7
MAX = 2*10**5
fac = [1,1] + [0]*MAX
finv = [1,1] + [0]*MAX
inv = [0,1] + [0]*MAX
for i in range(2,MAX+2):
    fac[i] = fac[i-1] * i % MOD
    inv[i] = -inv[MOD%i] * (MOD // i) % MOD
    finv[i] = finv[i-1] * inv[i] % MOD

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

N, M = map(int, input().split())
ans = 1
pf = prime_factors(M)
for k,v in pf.items():
    ans *= comb(v+N-1, N-1)
    ans %= MOD
print(ans)

Solution (Python):
from collections import Counter
import math
mod = 10**9+7
N,M = map(int,input().split())
factors = []
f = 2
while M%f==0:
    M//=2
    factors.append(f)
f = 3
while f*f<=M:
    if M%f==0:
        M//=f
        factors.append(f)
    else:
        f+=2
if M!=1:
    factors.append(M)
count = Counter(factors)

def choose(n,k):
    import math
    return math.factorial(n)//(math.factorial(n-k)*math.factorial(k))
ans = 1
for v in count.values():
    ans *= choose(N+v-1,N-1)
    ans %= mod
print(ans)

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

fac  = [None] * MOD_t_MAX
finv = [None] * MOD_t_MAX
inv  = [None] * MOD_t_MAX
def MOD_COM_init():
    fac[0] = fac[1] = 1
    finv[0] = finv[1] = 1
    inv[1] = 1
    for i in range(2, MOD_t_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 MOD_COM(n, k):
    if n < k:
        return 0
    if n < 0 or k < 0:
        return 0
    return fac[n] * (finv[k] * finv[n - k] % MOD) % MOD

def main():
    n, m = map(int, input().split())
    MOD_COM_init()
    dic = {}
    x = 2
    while m%x == 0:
        if x in dic:
            dic[x] += 1
        else:
            dic[x] = 1
        m //= x
    x = 3
    while x*x <= m:
        while m%x == 0:
            if x in dic:
                dic[x] += 1
            else:
                dic[x] = 1
            m //= x
        x += 2
    if 1 < m:
        if m in dic:
            dic[m] += 1
        else:
            dic[m] = 1
    ans = 1
    for v in dic.values():
        ans *= MOD_COM(n+v-1, v)
        ans %= MOD
    print(ans)

if __name__ == "__main__":
    main()

Solution (Python):

import sys
import numpy as np
from collections import Counter

sr = lambda: sys.stdin.readline().rstrip()
ir = lambda: int(sr())
lr = lambda: list(map(int, sr().split()))

MOD = 10 ** 9 + 7


def cmb(n, k):
    if k < 0 or k > n: return 0
    return fact[n] * fact_inv[k] % MOD * fact_inv[n-k] % MOD

def cumprod(arr, MOD):
    L = len(arr); Lsq = int(L**.5+1)
    arr = np.resize(arr, Lsq**2).reshape(Lsq, Lsq)
    for n in range(1, Lsq):
        arr[:, n] *= arr[:, n-1]; arr[:, n] %= MOD
    for n in range(1, Lsq):
        arr[n] *= arr[n-1, -1]; arr[n] %= MOD
    return arr.ravel()[:L]

def make_fact(U, MOD):
    x = np.arange(U, dtype=np.int64); x[0] = 1
    fact = cumprod(x, MOD)
    x = np.arange(U, 0, -1, dtype=np.int64); x[0] = pow(int(fact[-1]), MOD-2, MOD)
    fact_inv = cumprod(x, MOD)[::-1]
    return fact, fact_inv

U = 10 ** 5 + 100  
fact, fact_inv = make_fact(U, MOD)

def prime_factorize(n): 
    A = []
    while n % 2 == 0:
        A.append(2); n //= 2
    f = 3
    while f * f <= n:
        if n % f == 0:
            A.append(f); n //= f
        else:
            f += 2
    if n != 1:
        A.append(n)
    return A

N, M = lr()
primes = prime_factorize(M)
counter = Counter(primes)
answer = 1
for v in counter.values():
    cases = cmb(N-1+v, v)
    answer *= cases
    answer %= MOD

print(answer % MOD)

Solution (Python):

import sys
import numpy as np
from collections import Counter

sr = lambda: sys.stdin.readline().rstrip()
ir = lambda: int(sr())
lr = lambda: list(map(int, sr().split()))

MOD = 10 ** 9 + 7


def cmb(n, k):
    if k < 0 or k > n: return 0
    return fact[n] * fact_inv[k] % MOD * fact_inv[n-k] % MOD

def cumprod(arr, MOD):
    L = len(arr); Lsq = int(L**.5+1)
    arr = np.resize(arr, Lsq**2).reshape(Lsq, Lsq)
    for n in range(1, Lsq):
        arr[:, n] *= arr[:, n-1]; arr[:, n] %= MOD
    for n in range(1, Lsq):
        arr[n] *= arr[n-1, -1]; arr[n] %= MOD
    return arr.ravel()[:L]

def make_fact(U, MOD):
    x = np.arange(U, dtype=np.int64); x[0] = 1
    fact = cumprod(x, MOD)
    x = np.arange(U, 0, -1, dtype=np.int64); x[0] = pow(int(fact[-1]), MOD-2, MOD)
    fact_inv = cumprod(x, MOD)[::-1]
    return fact, fact_inv

U = 10 ** 6  
fact, fact_inv = make_fact(U, MOD)

def prime_factorize(n): 
    A = []
    while n % 2 == 0:
        A.append(2); n //= 2
    f = 3
    while f * f <= n:
        if n % f == 0:
            A.append(f); n //= f
        else:
            f += 2
    if n != 1:
        A.append(n)
    return A

N, M = lr()
primes = prime_factorize(M)
counter = Counter(primes)
answer = 1
for v in counter.values():
    cases = cmb(N-1+v, v)
    answer *= cases
    answer %= MOD

print(answer % MOD)

Solution (Python):
def factorization(n):
    from collections import Counter
    arr = Counter()
    temp = n
    for i in range(2, int(-(-n**0.5 // 1)) + 1):
        if temp % i == 0:
            cnt = 0
            while temp % i == 0:
                cnt += 1
                temp //= i
            arr[i] = cnt

    if temp != 1:
        arr[temp] = 1

    if len(arr.keys()) == 0 and n != 1:
        arr[n] = 1

    return arr


def solve(m, N):
    MOD = 10 ** 9 + 7
    dp = [[0] * (m + 1) for _ in range(N + 1)]
    dp[0][0] = 1
    for i in range(N):
        for j in range(m + 1):
            dp[i + 1][j] = dp[i + 1][j - 1] + dp[i][j]
            dp[i + 1][j] %= MOD
    return dp[-1][-1]


def main():
    
    
    
    MOD = 10 ** 9 + 7
    N, M = map(int, input().split())
    primes = factorization(M)

    ans = 1
    for p in primes.values():
        cnt = solve(p, N)
        ans *= cnt
        ans %= MOD
    
    print(ans)


if __name__ == "__main__":
    main()

Solution (Python):

import sys, math, itertools, collections, bisect
input = lambda: sys.stdin.buffer.readline().rstrip().decode('utf-8')
inf = float('inf') ;mod = 10**9+7
mans = inf ;ans = 0 ;count = 0 ;pro = 1

n,m = map(int,input().split())
class InverseTable:
    __slots__ = ['In', 'fac', 'Ifac']

    def __init__(self, mod, maxnum):
        self.In = [0, 1]; self.fac = [1, 1]; self.Ifac = [1, 1]
        for i in range( 2, maxnum + 1 ):
            self.In.append( ( -self.In[mod % i] * (mod//i) ) % mod )
            self.fac.append( ( self.fac[-1] * i ) % mod )
            self.Ifac.append( (self.Ifac[-1] * self.In[-1]) % mod )
        
    def cmb(self, n, r):
        if ( r<0 or r>n ): return 0
        r = min(r, n-r)
        return self.fac[n] * self.Ifac[r] * self.Ifac[n-r] % mod
    
    def per(self, n, r):
        if ( r<0 or r>n ): return 0
        return self.fac[n] * self.Ifac[n-r] % mod

invt = InverseTable(mod, 10**6)



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


ass = prime_factor(m)
ans = 1
for i, amount in ass:
  ans = ans * invt.cmb(amount+n-1,amount) % mod
print(ans)

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

def modInv(a,mod):
    return pow(a,mod-2,mod)

def nCr(n,r,mod):
    r=min(r,n-r)
    if r==0:
        return 1
    if r==1:
        return n
    numer=1
    denom=1
    for i in range(r):
        numer=(n-i)*numer%mod
        denom=(i+1)*denom%mod
    return numer*modInv(denom,mod)%mod

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

if M==1:
    print(1)
    exit()

prime_divisors=prime_factorizarion(M)
ans=1
for prime,num in prime_divisors:
    ans=(ans*nCr(num+N-1,num,mod))%mod
print(ans)

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

def comb(n, k):
  if k > n-k:
    return comb(n, n-k)
  mul, div = 1, 1
  for i in range(k):
    mul = mul * (n-i) % mod
    div = div * (k-i) % mod
  ret = mul * pow(div, mod-2, mod) % mod
  return ret

i = 2
ans = 1
tmp = M
while i * i <= M:
  if tmp % i == 0:
    cnt = 0
    while tmp % i == 0:
      tmp //= i
      cnt += 1
    ans = ans * comb(cnt+N-1, N-1) % mod
  i += 1
if tmp != 1:
  ans = ans * comb(1+N-1, N-1) % mod
print(ans)

Solution (Python):
def gen(n):
    x = n
    d = 2
    cnt = 0
    while x % d == 0:
        x //= d
        cnt += 1
    yield cnt

    d = 3
    while d * d <= n:
        cnt = 0
        while x % d == 0:
            x //= d
            cnt += 1
        yield cnt
        d += 2

    if x > 1:
        yield 1


def main():
    MOD = 10 ** 9 + 7

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

    ans = 1
    for cnt in gen(M):
        for d in range(cnt):
            ans = (ans * (N - 1 + cnt - d) % MOD) * pow(d + 1, MOD - 2, MOD) % MOD
            
    print(ans)


if __name__ == '__main__':
    main()

Solution (Python):
class Calc:
    def __init__(self, max_value, mod):
        """combination(max_value, all)"""
        fact = [-1] * (max_value + 1)
        fact[0] = 1
        fact[1] = 1
        for x in range(2, max_value + 1):
            fact[x] = x * fact[x - 1] % mod

        invs = [1] * (max_value + 1)
        invs[max_value] = pow(fact[max_value], mod - 2, mod)
        for x in range(max_value - 1, 0, -1):
            invs[x] = invs[x + 1] * (x + 1) % mod

        self.fact = fact
        self.invs = invs
        self.mod = mod

    def combination(self, n, r):
        if n - r < r:
            return self.combination(n, n - r)
        if r < 0:
            return 0
        if r == 0:
            return 1
        if r == 1:
            return n
        return self.fact[n] * self.invs[r] * self.invs[n - r] % self.mod


def gen(n):
    x = n
    d = 2
    cnt = 0
    while x % d == 0:
        x //= d
        cnt += 1
    yield cnt

    d = 3
    ma = d * d
    while ma <= n:
        cnt = 0
        while x % d == 0:
            x //= d
            cnt += 1
        yield cnt
        ma += d * 4 + 4
        d += 2

    if x > 1:
        yield 1


def main():
    MOD = 10 ** 9 + 7

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

    cal = Calc(max_value=N + 30, mod=MOD)

    ans = 1
    for cnt in gen(M):
        ans = (ans * cal.combination(N + cnt - 1, cnt)) % MOD
    print(ans)


if __name__ == '__main__':
    main()

Solution (Python):
class Calc:
    def __init__(self, max_value, mod):
        """combination(max_value, all)"""
        fact = [-1] * (max_value + 1)
        fact[0] = 1
        fact[1] = 1
        for x in range(2, max_value + 1):
            fact[x] = x * fact[x - 1] % mod

        invs = [1] * (max_value + 1)
        invs[max_value] = pow(fact[max_value], mod - 2, mod)
        for x in range(max_value - 1, 0, -1):
            invs[x] = invs[x + 1] * (x + 1) % mod

        self.fact = fact
        self.invs = invs
        self.mod = mod

    def combination(self, n, r):
        if n - r < r:
            return self.combination(n, n - r)
        if r < 0:
            return 0
        if r == 0:
            return 1
        if r == 1:
            return n
        return self.fact[n] * self.invs[r] * self.invs[n - r] % self.mod


def gen(n):
    x = n
    d = 2
    cnt = 0
    while x % d == 0:
        x //= d
        cnt += 1
    yield cnt

    d = 3
    while d * d <= n:
        cnt = 0
        while x % d == 0:
            x //= d
            cnt += 1
        yield cnt
        d += 2

    if x > 1:
        yield 1


def main():
    MOD = 10 ** 9 + 7

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

    cal = Calc(max_value=N + 30, mod=MOD)

    ans = 1
    for cnt in gen(M):
        ans = (ans * cal.combination(N + cnt - 1, cnt)) % MOD
    print(ans)


if __name__ == '__main__':
    main()

Solution (Python):
class Calc:
    def __init__(self, max_value, mod):
        """combination(max_value, all)"""
        fact = [-1] * (max_value + 1)
        fact[0] = 1
        fact[1] = 1
        for x in range(2, max_value + 1):
            fact[x] = x * fact[x - 1] % mod

        invs = [1] * (max_value + 1)
        invs[max_value] = pow(fact[max_value], mod - 2, mod)
        for x in range(max_value - 1, 0, -1):
            invs[x] = invs[x + 1] * (x + 1) % mod

        self.fact = fact
        self.invs = invs
        self.mod = mod

    def combination(self, n, r):
        if n - r < r:
            return self.combination(n, n - r)
        if r < 0:
            return 0
        if r == 0:
            return 1
        if r == 1:
            return n
        return self.fact[n] * self.invs[r] * self.invs[n - r] % self.mod


def main():
    MOD = 10 ** 9 + 7

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

    def decom(n) -> list:  
        ret = []

        x = n
        d = 2
        cnt = 0
        while x % d == 0:
            x //= d
            cnt += 1
        ret.append(cnt)

        d = 3
        while d * d <= n:
            cnt = 0
            while x % d == 0:
                x //= d
                cnt += 1
            ret.append(cnt)
            d += 2

        if x > 1:
            ret.append(1)

        return ret

    dlis = decom(M)

    cal = Calc(max_value=N + 30, mod=MOD)

    ans = 1
    for cnt in dlis:
        ans = (ans * cal.combination(N + cnt - 1, cnt)) % MOD
    print(ans)


if __name__ == '__main__':
    main()

Solution (Python):


import sys
import math
import collections
import itertools
import bisect
INF = 10 ** 13
MOD = 10 ** 9 + 7
def input() : return sys.stdin.readline().strip()
def lcm(x, y) : return (x * y) // math.gcd(x, y)
def I() : return int(input())
def LI() : return [int(x) for x in input().split()]
def RI(N) : return [int(input()) for _ in range(N)]
def LRI(N) : return [[int(x) for x in input().split()] for _ in range(N)]
def LS() : return input().split()
def RS(N) : return [input() for _ in range(N)]
def LRS(N) : return [input().split() for _ in range(N)]
def PL(L) : print(*L, sep="\n")
def YesNo(B) : print("Yes" if B else "No")
def YESNO(B) : print("YES" if B else "NO")

def ncr(n, r, p=MOD):
    a = 1
    b = 1
    for i in range(r):
        a = (a * (n - i) % p)
        b = (b * (r - i) % p)

    return a * pow(b, p - 2, p) % p

N, M = LI()

i = 1
ans = 1
while i * i <= M:
    i += 1

    if M % i == 0:
        cnt = 0
        while M % i == 0:
            cnt += 1
            M //= i
        
        ans = ans * ncr(cnt+(N-1), (N-1)) % MOD

if M != 1:
    ans = ans * ncr(1+(N-1), (N-1)) % MOD

print(ans)

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


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


def com(n, r):
    X = Y = 1
    if n-r < r:
        r = n-r
    for i in range(1, r+1):
        Y = Y*i % MOD
        X = X*(n-i+1) % MOD
    Y = pow(Y, MOD-2, MOD)
    return X*Y


fact = factorization(m)
ans = 1
for x, p in fact:
    ans *= com(n+p-1, n-1)
print(ans % MOD)

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


def factorization(n):
    retval = []
    tmp = n
    for i in range(2, int(-(-n**.5//1))+1):
        if tmp % i == 0:
            cnt = 0
            while tmp % i == 0:
                cnt += 1
                tmp //= i
            retval.append((i, cnt))
    if tmp != 1:
        retval.append((tmp, 1))
    if not retval:
        retval.append((n, 1))
    return retval


fact = factorization(m)


def com(n, r):
    X = Y = 1
    if n-r < r:
        r = n-r
    for i in range(1, r+1):
        Y = Y*i % MOD
        X = X*(n-i+1) % MOD
    Y = pow(Y, MOD-2, MOD)
    return X*Y


ans = 1
for f in fact:
    ans *= com(n+f[1]-1, n-1)
if m == 1:
    print(1)
else:
    print(ans % MOD)

Solution (Python):
n,m = map(int,input().split())
mod = 10**9 + 7
l = n+1000
fac = [1]*l
facr = [1]*l

for i in range(l-1):
    fac[i+1] = fac[i]*(i+1)%mod
facr[l-1] = pow(fac[l-1],mod - 2,mod)
for i in range(1,l)[::-1]:
    facr[i-1] = facr[i]*i%mod

def combi(N,K):
    return fac[N]*facr[N-K]%mod*facr[K]%mod

prime = {}
i = 2
x = m
while i*i <= m:
    if x%i == 0:
        prime[i] = 0
        while x%i == 0:
            x = x//i
            prime[i] += 1
    i += 1
if x > 1:
    prime[x] = 1
ans = 1
for q in prime.values():
    ans *= combi(q+n-1,n-1)
    ans %= mod
print(ans)

Solution (Python):
import sys

MOD = 10 ** 9 + 7

def make_tables(n=10 ** 9, r=2 * 10 ** 6, p=MOD):
  fac = [None] * (r + 1); fac[0] = 1
  for i in range(r): fac[i+1] = fac[i] * (i + 1) % p
  ifac = [None] * (r + 1); ifac[r] = pow(fac[r], p - 2, p)
  for i in range(r, 0, -1): ifac[i-1] = ifac[i] * i % p
  n_choose = [None] * (r + 1); n_choose[0] = 1
  for i in range(r): n_choose[i+1] = n_choose[i] * (n - i) % p
  for i in range(r + 1): n_choose[i] = n_choose[i] * ifac[i] % p
  return fac, ifac, n_choose

fac, ifac, n_choose = make_tables()

def mod_choose(n, r, p=MOD):
  if r > n or r < 0: return 0
  return fac[n] * ifac[r] % p * ifac[n-r] % p

def nHr(n, r, p=MOD):
  return fac[n-1+r] * ifac[n-1] % p * ifac[r] % p

def sieve_of_eratosthenes(n=10 ** 6):
  sieve = [1] * (n + 1); sieve[0] = sieve[1] = 0
  for i in range(2, int(n ** 0.5) + 1):
    if not sieve[i]: continue
    for j in range(i * 2, n + 1, i): sieve[j] = 0
  prime_numbers = [i for i in range(2, n + 1) if sieve[i]]
  return sieve, prime_numbers

is_prime, prime_numbers = sieve_of_eratosthenes()

def prime_factorize(n):
  res = dict()
  if n < 2: return res
  border = int(n ** 0.5)
  for p in prime_numbers:
    if p > border: break
    while n % p == 0: res[p] = res.get(p, 0) + 1; n //= p
    if n == 1: return res
  res[n] = 1
  return res

def prime_factorize_factorial(n):
  res = dict()
  for i in range(2, n + 1):
    for p, c in prime_factorize(i).items(): res[p] = res.get(p, 0) + c
  return res

n, m = map(int, sys.stdin.readline().split())

def main():
  res = 1
  for p, c in prime_factorize(m).items():
    res *= nHr(n, c)
    res %= MOD 
  print(res)

if __name__ == '__main__':
  main()