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 math
from collections import defaultdict

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

def prime_factors(n):
    i = 2
    factors = []
    while i * i <= n:
        if n % i:
            i += 1
        else:
            n //= i
            factors.append(i)
    if n > 1:
        factors.append(n)
    return factors

pr = prime_factors(m)
di = {}
di = defaultdict(int)
for i in pr:
    while m % i == 0:
        m = m // i
        di[i] += 1

"""def comb(n, r):
    return math.factorial(n) // (math.factorial(n - r) * math.factorial(r))"""
mod = 10 ** 9 + 7
MAX_N = 10 ** 5 + 100
factorial = [1] * MAX_N
def calc_factorial():
    for i in range(1, MAX_N):
        factorial[i] = i * factorial[i - 1] % mod

def comb(n, k):
    a = factorial[n] % mod
    b = (factorial[k] * factorial[n - k]) % mod
    b_ = pow(b, mod - 2, mod)
    return (a * b_) % mod



calc_factorial()

ans = 1

for i in di:
    ans = ans * comb(di[i] + n - 1, di[i]) % mod
print(ans)

Solution (Python):


"""
参考：http://drken1215.hatenablog.com/entry/2018/09/23/224100
　　　http://tutuz.hateblo.jp/entry/2018/09/24/121248
・素因数分解と重複組み合わせ
・毎回階乗やると死ぬから階乗と逆元のテーブル作る(忘れてた)
"""

from collections import defaultdict
from math import sqrt

MOD = 10 ** 9 + 7

def fact_prime(num):
    d = defaultdict(int)
    
    end = int(sqrt(num)) + 1
    for i in range(2, end+1):
        cnt = 0
        
        while num % i == 0:
            num //= i
            d[i] += 1
        
        if num == 1:
            break
    
    if num != 1:
        d[num] += 1
    return d


MAX = 10 ** 5 * 2

factorial = [1] * (MAX)
factorial[0] = factorial[1] = 1
for i in range(2, MAX):
    factorial[i] = factorial[i-1] * i % MOD

inverse = [1] * (MAX)

inverse[MAX-1] = pow(factorial[MAX-1], MOD-2, MOD)
for i in range(MAX-2, 0, -1):
    
    inverse[i] = inverse[i+1] * (i+1) % MOD


def nCr(n, r):
    
    r = min(r, n-r)
    
    numerator = factorial[n]
    
    denominator = inverse[r] * inverse[n-r] % MOD
    return numerator * denominator % MOD

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



ans = 1
for k, v in fact_prime(M).items():
    
    
    ans = (ans * nCr(v+N-1, v)) % MOD
print(ans)

Solution (Python):
mod = 10 ** 9 + 7
N, M = [int(_) for _ in input().split()]

MAX_N = 10 ** 5 + 100

factorize_result = {}
def factorization(n):
    for i in range(2, int(n ** 0.5) + 1):
        if n % i == 0:
            factorize_result[i] = 1
            n = n // i
            while n % i == 0:
                factorize_result[i] += 1
                n = n // i
    if n > 1:
        factorize_result[n] = 1


factorial = [1] * MAX_N
def calc_factorial():
    for i in range(1, MAX_N):
        factorial[i] = i * factorial[i - 1] % mod


def comb(n, k):
    a = factorial[n] % mod
    b = (factorial[k] * factorial[n - k]) % mod
    b_ = pow(b, mod - 2, mod)
    return (a * b_) % mod



factorization(M)


calc_factorial()

ans = 1
for k, v in factorize_result.items():
    ans *= comb(N + v - 1, v) % mod

print(ans % mod)

Solution (Python):
import math
import copy


def prime_decomposition(n):
  i = 2
  X = {}
  while i * i <= n:
    while n % i == 0:
      n /= i
      if i in X:
        X[i] = X[i] + 1
      else:
        X[i] = 1
    i += 1
  if n > 1:
    X[n] = 1
  return X

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;


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

X = prime_decomposition(M)
       
sum = 1
for i in X.values():
  sum = (sum * cmb(i + N - 1, i) % 1000000007) % 1000000007
  
print(sum)

Solution (Python):
import math
from scipy.misc import comb

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

def factorize(M):
    P = []
    F = []
    for m in range(2, int(math.sqrt(M))+1):
        n = 0
        while M % m == 0:
            M/= m
            n +=1
        if n != 0:
            P.append(m)
            F.append(n)
    if M != 1:
        P.append(M)
        F.append(1)
    return P,F

P, F = factorize(M)

X = 1
for f in F:
    X *= int(comb(N+f-1, f, exact=True))
    X %= int(pow(10,9)+7)

print(X)

Solution (Python):
import sys
input = sys.stdin.readline

N, M = (int(i) for i in input().split())

def soin(N):
	res = []
	i = 2
	while i < round(N**(1/2)) + 3:
		if N%i == 0:
			res.append(i)
			N = N//i
			i = 2
		else:
			i += 1
	if N != 1:
		res.append(N)
	return res

def power(a, b):
	if b == 0:
		return 0
	elif b == 1:
		return a % 1000000007
	elif b % 2 == 0:
		return (power(a, b//2) ** 2) % 1000000007
	else:
		return (power(a, b//2) ** 2 * a) % 1000000007

def divide(a, b):
	return (a * power(b, 1000000005)) % 1000000007

def combination(a, b):
	res = 1
	for i in range(b):
		res *= a - i
		res = res % 1000000007
	for i in range(b):
		res = divide(res, i+1)
	return res
if M == 1:
	res = 1
else:
	L = soin(M)
	cc = 1
	res = 1
	for i in range(len(L) -1):
		if L[i] == L[i+1]:
			cc += 1
		else:
			res *= combination(N + cc -1, cc)
			res = res % 1000000007
			cc = 1
	res *= combination(N+cc -1, cc)
	res = res % 1000000007
print(res)

Solution (Python):
def prf(m):
    pf = {}
    for i in range(2, int(m**0.5)+1):
        while m % i == 0:
            pf[i] = pf.get(i, 0)+1
            m //= i
    if m > 1:
        pf[m] = 1
    return pf
def inpl(): return [int(i) for i in input().split()]
def comb(n, k):
    k = min(k, n - k)
    result = 1
    for i in range(n, n - k, -1):
        result *= i
    for i in range(1, k + 1):
        result //= i 
    return result

mod = 10**9+7
N, M = inpl()

ans = 1
for i in prf(M).values():
    ans = ans*comb(N+i-1, i)%mod
print(ans)

Solution (Python):


from math import sqrt, floor

PRIME = 1000000007

def mul(a, b):
    return (a * b) % PRIME

def div(n, d):
    return int(n / d)

def multiDiv(n, d):
    count = 0

    while n % d == 0:
        count += 1
        n = div(n, d)

    return (n, count)

def factoring(n):
    m = floor(sqrt(n))

    (n, f) = multiDiv(n, 2)
    ret = [f]

    for d in range(3, m+1, 2):
        (n, f) = multiDiv(n, d)
        if (f != 0):
            ret.append(f)

    if n != 1:
        ret.append(1)

    return ret

def pow(base, n):

    if n == 0:
        return 1

    if n % 2 == 0:
        return pow(mul(base, base), div(n, 2))
    else:
        return mul(base, pow(base, n - 1))

def reciprocal(n):
    return pow(n, PRIME - 2)

def com(n, k):
    if k == 0:
        return 1

    if (n - k) < k:
        return com(n, n - k)

    ret = 1

    for i in range(1, k + 1):
        ret = mul(ret, reciprocal(i))

    for i in range(n - k + 1, n + 1):
        ret = mul(ret, i)

    return ret


if __name__ == '__main__':

    line = [int(w) for w in input().split()]
    n = line[0]
    m = line[1]

    fs = factoring(m)

    def fun(x):
        return com(n + x - 1, x)
    cs = [fun(i) for i in fs]

    a = 1
    for i in cs:
        a = mul(a, i)

    print(a)

Solution (Python):


import math

const = 10 ** 9 + 7

def read_int_n():
    return list(map(int, input().split()))

def comb(n, m):
    return math.factorial(n) // (math.factorial(m) * math.factorial(n - m)) 

def power(x, y):
    """
        ２分累乗法
    """
    if      y == 0      :   return 1
    elif    y == 1      :   return x % const
    elif    y % 2 == 0  :   return power(x, y/2) ** 2 % const
    else                :   return power(x, math.floor(y/2)) ** 2 * x % const

if __name__ == "__main__":
    n, m = read_int_n()
    
    cnts = {}
    for i in range(2, math.ceil(math.sqrt(m)) + 1):
        while m % i == 0:
            if i not in cnts:
                cnts[i] = 1
            else:
                cnts[i] += 1
            m //= i
    else:
        if m > 1:
            if m not in cnts:
                cnts[m] = 1
            else:
                cnts[m] += 1
    ans = 1
    for key, value in cnts.items():
        num = 1
        for i in range(value):
            num *= (n + value - 1 - i)
        num //= math.factorial(value)
        
        ans *= num % const
        ans = ans % const
    print(ans)

Solution (Python):
import math

N, M = [int(x) for x in input().split()]
MOD = 10 ** 9 + 7

divisor = []
dict = {}

m = M
d = 2
while d*d <= m:
    while m % d == 0:
        m //= d
        dict[d] = dict.get(d, 0) + 1
    d += 1
if m > 1:
    dict[d] = dict.get(m, 0) + 1

C = dict.values()
ret = 1





def combinations_count(n, r):
    a = max(r, n-r)
    b = min(r, n-r)
    r = 1
    for i in range(a+1, n+1):
        r *= i
    return r // math.factorial(b)


for c in C:
    ret *= combinations_count(c + N - 1, c)
    ret %= MOD

print(ret)

Solution (Python):
import math

N, M = [int(x) for x in input().split()]
MOD = 10 ** 9 + 7

divisor = []
dict = {}

m = M
d = 2
while m != 1:
    while m % d == 0:
        
        m //= d
        dict[d] = dict.get(d, 0) + 1
    d += 1
C = dict.values()
ret = 1





def combinations_count(n, r):
    a = max(r, n-r)
    b = min(r, n-r)
    r = 1
    for i in range(a+1, n+1):
        r *= i
    return r // math.factorial(b)


for c in C:
    ret *= combinations_count(c + N - 1, c)
    ret %= MOD

print(ret)

Solution (Python):
from math import *

def Prime_Factorization(M):
    factor_count_list = []
    root_M = int(sqrt(M))

    while root_M > 1:
        root_M = int(sqrt(M))

        for i in range(2, root_M + 1):
            e = 0
            while M % i == 0:
                e += 1
                M = M // i
            if e > 0:
                factor_count_list.append(e)
                break
        else:
            break

    if M > root_M:
        factor_count_list.append(1)

    return factor_count_list

def comb(num_object, num_bar):
    numerator = 1

    for i in range(num_bar):
        numerator = (numerator * (num_object - i))

    return  numerator // factorial(num_bar)

def all_comb(N, factor_count_list):
    ans = 1
    for factor in factor_count_list:
        ans = (ans * comb(factor + N - 1, factor)) % (10 ** 9 + 7)
    return ans

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

    print(all_comb(N, factor_count_list))

if __name__ == "__main__":
    main()

Solution (Python):
from math import floor, sqrt
from collections import Counter

MOD = 10 ** 9 + 7


def getPrimeFactor(x):
    ans = []
    for d in range(2, floor(sqrt(x)) + 1):
        while x % d == 0:
            ans.append(d)
            x //= d
    if x != 1:
        ans.append(x)
    return ans

def comb(n, k):
    k = min(k, n - k)
    ans = 1
    for i in range(n, n - k, -1):
        ans *= i
    for i in range(1, k + 1):
        ans //= i 
    return ans


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

PFs = getPrimeFactor(M)
cnt = Counter(PFs)

ans = 1
for num in cnt.values():
    ans *= comb(N + num - 1, num)
print(ans % MOD)

Solution (Python):
def combination(n, r):
    if r > n-r:
        r = n-r
    a = 1
    for i in range(n, n-r, -1):
        a = a * i
    d = 1
    for i in range(1, r+1):
        d = d*i
    return a//d


def generate_prime_map(n):
    m = {}
    b, e = 2, 0
    while b * b <= n:
        while n % b == 0:
            n = n // b
            e = e + 1
        if e > 0:
            m[b] = e
        b, e = b + 1, 0
    if n > 1:
        m[n] = 1
    return m


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

m = generate_prime_map(M)

ans = 1
mod = 10**9+7
for v in m.values():
    ans *= combination(v+N-1, v)
    ans %= mod
print(ans)

Solution (Python):



'''Snippets for prime.
Available functions:
- is_included: Determine whether it is a prime number.
- generate: Generate a list of prime numbers using sieve of Eratosthenes.
'''


class Prime(object):
    '''Represents a snippet for prime numbers.
    '''

    def __init__(self, number):
        self.number = number
        self._values = []

    def is_included(self) -> bool:
        '''Determine whether it is a prime number.
        Args:
            number: Int of number (greater than 0).
        Returns:
            True if the input number was prime.
            False if the input number was not prime.
        See:
            https://qiita.com/srtk86/items/874639e361917e5016d4
            https://docs.python.org/ja/3/library/2to3.html?highlight=isinstance
        '''

        from math import sqrt

        if (self.number <= 1) or (isinstance(self.number, float)):
            return False

        for i in range(2, int(sqrt(self.number)) + 1):
            if self.number % i == 0:
                return False

        return True

    def generate(self) -> list:
        '''Generate a list of prime numbers using sieve of Eratosthenes.
        Returns:
            A list of prime numbers that is eqaul to or less than the input
            number.
        Landau notation: O(n log log n)
        See:
            https://beta.atcoder.jp/contests/abc110/submissions/3254947
        '''

        if self._values:
            return self._values

        is_met = [True for _ in range(self.number + 1)]
        is_met[0] = False
        is_met[1] = False

        for i in range(2, self.number + 1):
            if is_met[i]:
                self._values.append(i)

                for j in range(2 * i, self.number + 1, i):
                    is_met[j] = False
        return self._values


def count_combinations(n, k, mod):
    ans = 1

    for i in range(1, k + 1):
        ans *= n - i + 1
        ans %= mod
        ans *= pow(i, mod - 2, mod)
        ans %= mod

    return ans


def main():
    from math import sqrt

    n, m = map(int, input().split())
    _prime = Prime(int(sqrt(m)) + 1)
    primes = _prime.generate()
    mod = 10 ** 9 + 7
    ans = 1

    for prime in primes:
        count = 0

        while m % prime == 0:
            count += 1
            m //= prime

        ans *= count_combinations(n + count - 1, count, mod)
        ans %= mod

    if m != 1:
        ans *= count_combinations(n, 1, mod)
        ans %= mod

    print(ans)


if __name__ == '__main__':
    main()

Solution (Python):
import math

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

sqrt_m = math.sqrt(m)
sqrt_m = int(sqrt_m) + 1

mod = 10**9 + 7
fac = [1, 1]
inv = [1, 1]
finv = [1, 1]
for i in range(2, n + 31):
    fac.append(fac[i-1] * i % mod)
    inv.append(mod - inv[mod%i] * (mod//i) % mod)
    finv.append(finv[i-1] * inv[i] % mod)

def nck(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


prime = []
for i in range(2, sqrt_m + 1):
    count = 0
    while m % i == 0:
        m = m // i
        count += 1
    if count > 0:
        prime.append(count)
if m > 1:
    prime.append(1)

ans = 1
for i in prime:
    ans *= nck(n-1+i, i)
    ans %= mod

print(ans)

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

import math 
L=math.floor(math.sqrt(M))

X=dict()

for i in range(2,L+2):
    while M%i==0:
        X[i]=X.get(i,0)+1
        M=M//i

if M!=1:
    X[M]=X.get(M,0)+1
    


def Combi2(a,b):
    if b>a:
        return 0
    ANS=1
    for i in range(min(b,a-b)):
        ANS=ANS*(a-i)*pow(min(b,a-b)-i,mod-2,mod)

    return ANS%mod

ANS=1
for x in X.values():
    ANS=(ANS*Combi2(x+N-1,x))%mod

print(ANS)

Solution (Python):
import sys
stdin = sys.stdin

sys.setrecursionlimit(10**5)

def li(): return map(int, stdin.readline().split())
def li_(): return map(lambda x: int(x)-1, stdin.readline().split())
def lf(): return map(float, stdin.readline().split())
def ls(): return stdin.readline().split()
def ns(): return stdin.readline().rstrip()
def lc(): return list(ns())
def ni(): return int(stdin.readline())
def nf(): return float(stdin.readline())

from collections import Counter

def factorize(n: int):
    d = Counter()
    m= 2
    
    while m*m <= n:
        while n%m == 0:
            n //= m
            d[m] += 1
            
        m += 1
        
    if n > 1:
        d[n] += 1
        
    return d


def inv_mod(n:int, mod:int) -> list:
    inv = [0,1]
    for i in range(2,n+1):
        inv.append(mod - ((mod//i)*inv[mod%i]) % mod)
    return inv
       

def fact(n:int, mod:int) -> list:
    fac = [1,1]
    res = 1
    for i in range(2,n+1):
        res = res*i%mod
        fac.append(res)
    return fac


def fact_inv(n:int, inv:list, mod:int) -> list:
    facInv = [1,1]
    for i in range(2,n+1):
        facInv.append(facInv[i-1]*inv[i] % mod)
    return facInv
        

def nCr(n:int, r:int, mod:int, fac:list, facInv:list) -> int:
    if not (0<=r and r<=n):
        return 0
    
    return ((fac[n]*facInv[r]) % mod) * facInv[n-r] % mod


def nHr(n:int, r:int, mod:int, fac:list, facInv:list) -> int:
    if r<0 or n<0:
        return 0
    
    else:
        return nCr(n+r-1,r,mod,fac,facInv)

n,m = li()
MOD = 10**9+7

inv = inv_mod(2*10**5, MOD)
fac = fact(2*10**5, MOD)
facinv = fact_inv(2*10**5,inv,MOD)

md = factorize(m)

ans = 1
for k,v in md.items():
    ans *= nHr(n,v,MOD,fac,facinv)
    ans %= MOD
    
print(ans)

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

from collections import Counter
def factorize(n):
    d = Counter()
    m = 2
    while m*m <= n:
        while n%m == 0:
            n //= m
            d[m] += 1
        m += 1
    if n > 1:
        d[n] += 1
    return d

MAXN = N+99
fac = [1,1] + [0]*MAXN
finv = [1,1] + [0]*MAXN
inv = [0,1] + [0]*MAXN
for i in range(2,MAXN+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 ncr(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

def nhr(n,r):
    return ncr(n+r-1, r)

factors = factorize(M)
ans = 1
for v in factors.values():
    ans *= nhr(N,v)
    ans %= MOD
print(ans)

Solution (Python):

import math


def C(n, r):
  a = 1
  b = 1
  for i in range(r):
    a = a*(n-i)
    b = b*(r-i)
  return((a//b))

from collections import Counter

N, M = map(int, input().split())
D = 1000000000 + 7

def primes(n):
    primfac = []
    d = 2
    while d*d <= n:
        while (n % d) == 0:
            primfac.append(d)  
            n //= d
        d += 1
    if n > 1:
       primfac.append(n)
    return primfac


f = primes(M)
cntr = Counter(f)

ans = 1
for k,v in cntr.items():
    ans *= C(v+N-1,v) %D

print(ans%D)

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

from collections import Counter
def factorize(n):
    d = Counter()
    m = 2
    while m*m <= n:
        while n%m == 0:
            n //= m
            d[m] += 1
        m += 1
    if n > 1:
        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 ncr(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
def nhr(n,r):
    return ncr(n+r-1, r)


factors = factorize(M)
ans = 1
for v in factors.values():
    ans *= nhr(N,v)
    ans %= MOD
print(ans)

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

def factorint(x):
  F={}
  i=2
  while i**2<=x:
    if x%i==0:
      c=0
      while x%i==0:
        x=x//i
        c+=1
      F[i]=c
    i+=1
  if x!=1:
    F[x]=1
  return F

def C(n,r):
  a=1
  b=1
  for i in range(r):
    a=a*(n-i)
    b=b*(r-i)
  return((a//b)%(10**9+7))

ans=1
for f in factorint(M):
  k=factorint(M)[f]
  ans*=C(N+k-1,k)        
print(ans%((10**9)+7))

Solution (Python):

import math
n,m=map(int,input().split())
factor=[]
c=0
mod=10**9+7


while m%2 == 0:
    m//=2
    c+=1
    '''
    if c>=20:
        c=0
        break
        '''
if c != 0:
    factor.append([2,c])

for i in range(3,m+1,2):
    c=0
    while m%i == 0:
        m//=i
        c+=1
    if c != 0:
        
        factor.append([i,c])
    if m == 1:
        break
    if i*i>=m:  
        factor.append([m,1])
        break
        


def C(n,k):
    ans=1
    for s in range(1,k+1):
        ans*=n
        ans//=s
        n-=1
    return ans

def funcount(length,rest,memo):
    a=0
    if length==1:
        
        memo[length][rest]=1
        return 1,memo
    elif rest <= 1:
        
        memo[length][rest]=0
        return 0,memo
    if memo[length][rest] != -1:
        return memo[length][rest],memo
    else:
        for i in range(1,rest):
            
            a+=funcount(length-1,rest-i,memo)[0]
            memo=funcount(length-1,rest-i,memo)[1]
            
        memo[length][rest]=a
        return a,memo
    

way=1
for f in factor:
    sum=0
    for k in range(1,f[1]+1):
        memo=[[-1 for r in range(f[1]+1)] for l in range(k+1)] 
        
        sum+=funcount(k,f[1],memo)[0]*C(n,k)
    way=(way*sum)%mod
    
print(way%mod)

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

mod = 10 ** 9 + 7
def comb(x, y):
    if y * 2 > x:
        y = x - y
    result = 1
    for j in range(1, y + 1):
        result *= (x + j - y) * pow(j, mod - 2, mod)
        result %= mod
    return result
def homoprod(x, y):
    return comb(x + y - 1, y)

ans = 1
i = 2
for i in range(2, int(M ** 0.5) + 2):
    count = 0
    while M % i == 0:
        count += 1 
        M //= i
    if count > 0:
        ans *= homoprod(N, count)
        ans %= mod
if M > 1:
    ans *= homoprod(N, 1)
    ans %= mod
print(ans)

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

mod = 10 ** 9 + 7
def comb(x, y):
    if y * 2 > x:
        y = x - y
    result = 1
    for j in range(1, y + 1):
        result *= (x + j - y)
        result //= j
    return result
def homoprod(x, y):
    return comb(x + y - 1, y)

ans = 1
i = 2
for i in range(2, int(M ** 0.5) + 2):
    count = 0
    while M % i == 0:
        count += 1 
        M //= i
    if count > 0:
        ans *= homoprod(N, count)
        ans %= mod
if M > 1:
    ans *= homoprod(N, 1)
    ans %= mod
print(ans)

Solution (Python):
import math

R = 10**9 + 7

def combination(n,k):
    if 2*k > n:
        k = n - k

    r = 1
    for i in range(n-k+1,n+1):
        r = (r*i)

    r = (r//math.factorial(k))

    return r

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

decomposition = []
i = 2
while i * i <= M:
    if M % i == 0:
        decomposition.append(0)
        while M % i ==0:
            decomposition[-1] = decomposition[-1] + 1
            M = M//i
    i = i + 1
if M > 1:
    decomposition.append(1)

H = [ combination(N+k-1,k) % R for k in decomposition]
r = 1
for h in H:
    r = (r*h) % R

print(r)

Solution (Python):



from collections import defaultdict


def prime_factorize(num):
    prime_numbers = defaultdict(int)
    i = 2
    while i * i <= num:
        if num % i == 0:
            while num % i == 0:
                prime_numbers[i] += 1
                num //= i
        i += 1
    if num != 1:
        prime_numbers[num] += 1
    return prime_numbers


MOD = 10**9 + 7
N, M = [int(elem) for elem in input().split()]

prime_numbers = prime_factorize(M)

num_sequences = 1
for exponent in prime_numbers.values():
    denomimator = 1
    numerator = 1
    for i in range(1, exponent + 1):
        denomimator *= (N + exponent - i)
        numerator *= i
    num_sequences *= denomimator // numerator
    num_sequences %= MOD

print(num_sequences)

Solution (Python):
from collections import defaultdict


def prime_factorize(num):
    prime_numbers = defaultdict(int)
    i = 2
    while i * i <= num:
        if num % i == 0:
            while num % i == 0:
                prime_numbers[i] += 1
                num //= i
        i += 1
    if num != 1:
        prime_numbers[num] += 1
    return prime_numbers


MOD = 10**9 + 7
N, M = [int(elem) for elem in input().split()]

prime_numbers = prime_factorize(M)

num_sequences = 1
for exponent in prime_numbers.values():
    denomimator = 1
    numerator = 1
    for i in range(1, exponent + 1):
        denomimator *= (N + exponent - i)
        numerator *= i
    num_sequences *= denomimator // numerator
    num_sequences %= MOD

print(num_sequences)

Solution (Python):
import math

def InvMod(i, pow, mod): 
    if pow == 1:
        return i % mod
    else:
        if pow % 2 == 0:
            return InvMod((i**2) % mod, pow//2, mod) % mod
        else:
            return InvMod((i**2) % mod, pow//2, mod) * i % mod

def Prime(i): 
    root = math.sqrt(i)
    j, div = 2, True
    while j <= root:
        if i % j == 0:
            div = False
            break
        j += 1
    return div

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

Pinv = [0]
Pfact = 1
for i in range(1, 31): 
    Pfact *= i
    Pfact %= mod
    Pinv.append(InvMod(Pfact, mod-2, mod))

P = []
for i in range(2, max+1): 
    if M % i == 0:
        if Prime(i):
            P.append(i)
        if Prime(M//i) and i**2 != M:
            P.append(M//i)

ans = 1
for p in P:
    C, pow = M, 0
    while C % p == 0: 
        pow += 1
        C //= p
    comb = Pinv[pow]  
    for i in range(pow): 
        comb *= (N+i)
        comb %= mod
    ans *= comb
    ans %= mod

print(ans)

Solution (Python):
import math

def InvMod(i, pow, mod): 
    if pow == 1:
        return i % mod
    else:
        if pow % 2 == 0:
            return InvMod((i**2) % mod, pow//2, mod) % mod
        else:
            return InvMod((i**2) % mod, pow//2, mod) * i % mod

def Prime(i): 
    root = math.sqrt(i)
    j, div = 2, True
    while j <= root:
        if i % j == 0:
            div = False
            break
        j += 1
    return div

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

Pinv = [0]
Pfact = 1
for i in range(1, 31): 
    Pfact *= i
    Pfact %= mod
    Pinv.append(InvMod(Pfact, mod-2, mod))

P = []
for i in range(2, max+1): 
    if M % i == 0:
        if Prime(i):
            P.append(i)
        if Prime(M//i) and i**2 != M:
            P.append(M//i)

ans = 1
for p in P:
    C, pow = M, 0
    while C % p == 0: 
        pow += 1
        C //= p
    comb = Pinv[pow]  
    for i in range(pow): 
        comb *= (N+i)
        comb %= mod
    ans *= comb
    ans %= mod

print(ans)

Solution (Python):
import math


def combinations_with_replacement_count(n, r):
    return math.factorial(n + r - 1) // (math.factorial(n - 1) * math.factorial(r))


nm = list(map(int, input().split()))
n = nm[0]
m = nm[1]
fact = {}
i = 2
while i * i <= m:
    while m % i == 0:
        m = m // i
        if i in fact:
            fact[i] += 1
        else:
            fact[i] = 1
    i += 1
if m > 1:
    fact[m] = 1
j = 2
ans = 1
for k in fact:
    ans = ans * combinations_with_replacement_count(n, fact[k])
print(ans % (10 ** 9 + 7))

Solution (Python):
def com(n,m):
    if(n-m < m):
        m=n-m
    result=1
    mylist=[i for i in range(1,m+1)]
    j=1
    for i in range(1,m+1):
        result*=(n+1-i)
        if(j<m):
            while(result%mylist[j]==0):
                result//=mylist[j]
                j+=1
                if(j>=m):
                    break
    return result

def yakusuu(i,m):
    _i=i
    while(i**2<=m):
        if(m%i==0):
            return i
        else:
            i+=1
    for j in range(_i-1,0,-1):
        if(m%j==0):
            break
    return m//j
    

N,M=map(int,input().split())
soinsuubunkai={}
tmp=2
i=2
_M=M
while(tmp <=M):
    tmp=yakusuu(tmp,M)

    if(tmp in soinsuubunkai):
        soinsuubunkai[tmp]+=1
    else:
        soinsuubunkai[tmp]=1
    M//=tmp
    if(M==1):
        break


tmp=1
for k in list(soinsuubunkai.values()):
    tmp*=com(k+N-1,k)
    tmp%=10**9+7
print(tmp)

Solution (Python):
N, M = map(int, input().split())
rec = []
MOD = 10 ** 9 + 7
K = M
for i in range(2, int(M ** 0.5) + 1):
    if K % i == 0:
        tmp = 0
        while K % i == 0:
            tmp += 1
            K //= i

        rec.append((i, tmp))

if K != 1:
    rec.append((K, 1))
Q = 10 ** 6 + 1
fact = [0] * Q
rfact = [0] * Q
fact[0] = 1
for i in range(1, Q):
    fact[i] = fact[i - 1] * i % MOD

rfact[Q - 1] = pow(fact[Q - 1], MOD - 2, MOD)
for i in range(Q - 2, -1, -1):
    rfact[i] = rfact[i + 1] * (i + 1) % MOD


def comb(n, r):
    return fact[n] * rfact[n - r] * rfact[r] % MOD


num = 1
for i in range(len(rec)):
    num *= comb(N + rec[i][1] - 1, rec[i][1])
    num %= MOD

print(num)

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


def algorithm(k):
    result = 1
    division = 1
    num = n + k - 1
    num2 = 1
    for i in range(min(k, n - 1)):
        result *= num
        num -= 1
        division *= num2
        num2 += 1
    return result / division

if m == 1:
    print 1
else:
    divs = []
    while m != 0:
        flag = 0
        for i in range(2, int(m**0.5)+1):
            if m % i == 0:
                flag = 1
                divs.append(i)
                break
        if flag == 1:
            m = m / i
        else:
            divs.append(m)
            break
    divs.sort()
    divs_num = []
    num = 0
    first = divs[0]
    divs.append(0)
    for i in range(len(divs)):
        if divs[i] == first:
            num += 1
        else:
            divs_num.append(num)
            num = 1
            first = divs[i]

    divs_num = map(algorithm, divs_num)

    result = 1
    for i in divs_num:
        result *= i
    print result % (10**9+7)

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


def algorithm(k):
    result = 1
    division = 1
    num = n + k - 1
    num2 = 1
    for i in range(min(k, n - 1)):
        result *= num
        num -= 1
        division *= num2
        num2 += 1
    return result / division

if m == 1:
    print 1
else:
    divs = []
    while m != 0:
        flag = 0
        for i in range(2, int(m**0.5)+1):
            if m % i == 0:
                flag = 1
                divs.append(i)
                break
        if flag == 1:
            m = m / i
        else:
            divs.append(m)
            break
    divs.sort()
    divs_num = []
    num = 0
    first = divs[0]
    divs.append(0)
    for i in range(len(divs)):
        if divs[i] == first:
            num += 1
        else:
            divs_num.append(num)
            num = 1
            first = divs[i]

    divs_num = map(algorithm, divs_num)

    result = 1
    for i in divs_num:
        result *= i
    print result % (10**9+7)