CodeEff/ECCO huggingface dataset:
# Original solution
N, M = list(map(int, input().split()))

import math

def prime_fac(n):
  p_lis = []
  temp = n

  for i in range(2, int(math.sqrt(n)) + 1):
    if temp % i == 0:
      cnt = 0
      while temp % i == 0:
        cnt += 1
        temp //= i
      p_lis.append([i, cnt])
  if temp != 1:
    p_lis.append([temp, 1])
  if p_lis == []:
    p_lis.append([n, 1])

  return p_lis

mod = 10 ** 9 + 7
MAX = 10 ** 6
fac = [1, 1]
finv = [1, 1]
inv = [0, 1]

def comb(n, r):
  if n < r:
    return 0
  else:
    return fac[n] * ( finv[r] * finv[n-r] % mod ) % mod
 
for i in range(2, MAX + 1):
  fac.append( ( fac[-1] * i ) % mod )
  inv.append( mod - ( inv[mod % i] * (mod // i) % mod ) )
  finv.append( finv[-1] * inv[-1]  % mod )

ans = 1

for p, a in prime_fac(M):
  if a == p == 1:
    break
  ans *= comb(N+a-1, a)
  ans %= mod

print(ans)

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

import math

def prime_fac(n):
  p_lis = []
  temp = n

  for i in range(2, int(math.sqrt(n)) + 1):
    if temp % i == 0:
      cnt = 0
      while temp % i == 0:
        cnt += 1
        temp //= i
      p_lis.append([i, cnt])
  if temp != 1:
    p_lis.append([temp, 1])
  if p_lis == []:
    p_lis.append([n, 1])

  return p_lis

mod = 10 ** 9 + 7
MAX = N + 50
fac = [1, 1]
finv = [1, 1]
inv = [0, 1]

def comb(n, r):
  if n < r:
    return 0
  else:
    return fac[n] * ( finv[r] * finv[n-r] % mod ) % mod
 
for i in range(2, MAX + 1):
  fac.append( ( fac[-1] * i ) % mod )
  inv.append( mod - ( inv[mod % i] * (mod // i) % mod ) )
  finv.append( finv[-1] * inv[-1]  % mod )

ans = 1

for p, a in prime_fac(M):
  if a == p == 1:
    break
  ans *= comb(N+a-1, a)
  ans %= mod

print(ans)
# Original solution
import copy

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

#x以下の素数の列挙   
import math
x=math.floor(math.sqrt(10**9))
L=math.floor(math.sqrt(x))#平方根を求める
Primelist=[i for i in range(x+1)]
Primelist[1]=0#素数でないものは0にする.
for i in Primelist:
    if i>L:
        break
    if i==0:
        continue
    for j in range(2*i,x+1,i):
        Primelist[j]=0
Primes=[Primelist[j] for j in range(x+1) if Primelist[j]!=0]

def fact(M):#約数の列挙
    if M==1:
        return {1}
    
    DICT=dict()#素因数分解
    i=0
    while M!=1 and i<len(Primes):
        if M%Primes[i]==0:
            DICT[Primes[i]]=DICT.get(Primes[i],0)+1
            M=M//Primes[i]
        else:
            i+=1

    if M!=1:
        DICT[M]=1

    VALUES=list(DICT.values())
    KEYS=list(DICT.keys())

    LIST=[1]

    for i in range(len(DICT)):
        NOWLIST=copy.copy(LIST)
        for l in NOWLIST:
            for j in range(0,VALUES[i]+1):
                LIST.append(l*KEYS[i]**j)

    return set(LIST)

def Combi2(a,b):#aは大きいが、bは小さいとき
    if b>a:
        return 0
    ANS=1
    for i in range(min(b,a-b)):
        ANS=ANS*(a-i)%mod*pow(min(b,a-b)-i,mod-2,mod)%mod

    return ANS%mod



SET=fact(M)
factor=dict()

for j in SET:
    factor[j]=fact(j)

DP=dict()
defaultans=[0 for i in range(40)]
defaultans[1]=1
defaultans=tuple(defaultans)

def dp(m):
    ANS=[0 for i in range(40)]
    if m==1:
        return defaultans
    
    for j in factor[m]:
        #print(j,factor[m])

        if j==1:
            continue
        else:
            if DP.get(m//j,-1)!=-1:
                NEXT=DP[m//j]
            else:
                NEXT=dp(m//j)

            for k in range(39):
                ANS[k+1]=(ANS[k+1]+NEXT[k])%mod

            #print(m//j,ANS,NEXT)

        DP[m]=ANS
    return ANS
            
LIST=dp(M)
ANS=0
for i in range(40):
    if LIST[i]!=0:
        ANS=ANS+Combi2(N,i-1)*LIST[i]%mod

print((ANS%mod))


# Optimized solution
N,M=list(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):#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 list(X.values()):
    ANS=(ANS*Combi2(x+N-1,x))%mod

print(ANS)
# Original solution
import math
import collections
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[n] += 1

    return prime_count
def pc(n, r):
    return math.factorial(n) // (math.factorial(n - r)  * math.factorial(r))
s=0
x,N = list(map(int,input().split()))

li = trial_division_sqrt(N)
li = li.most_common()
ans = 1
for i in range(0, len(li)):
    ans *= pc(li[i][1] + x-1, x-1)
print((ans % (pow(10, 9)+7)))

# Optimized solution
import math
import collections
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[n] += 1

    return prime_count
def pc(n, r):
    return math.factorial(n) // (math.factorial(n - r)  * math.factorial(r))
nCr = {}
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;
s=0
x,N = list(map(int,input().split()))

li = trial_division_sqrt(N)
li = li.most_common()
ans = 1
for i in range(0, len(li)):
    ans *= cmb(li[i][1] + x-1, x-1)
print((ans % (pow(10, 9)+7)))
# Original solution
import sys
input = sys.stdin.readline

from collections import *

def prime_fact(n):
    prime = Counter()
    m = 0

    while not n % 2: 
        prime[2] += 1
        n //= 2
        m += 1

    x = 3
    while x**2 <= n: 
        c = 0
        while not n % x: 
            prime[x] += 1
            n //= x
            c += 1
        m = max(m, c)
        x += 2

    if n > 1: prime[n] += 1

    return prime, m

MOD = 10**9+7

class Comb:
    def __init__(self, N):
        self.fac = [1] * (N+5)
        for i in range(2, N+5): self.fac[i] = self.fac[i-1] * i % MOD

    def pow(self, a, b):
        res = 1
        while b:
            if b & 1: res = res * a % MOD
            a = a**2 % MOD
            b >>= 1
        return res

    def comb(self, n, r):
        if r < 0 or r > n: return 0
        return (self.fac[n] * self.pow(self.fac[r], MOD-2)) % MOD * self.pow(self.fac[n-r], MOD-2) % MOD

def main():
    N, M = list(map(int, input().split()))
    prime, m = prime_fact(M)

    comb = Comb(N-1+m)
    ans = 1

    for v in list(prime.values()):
        ans = ans * comb.comb(N-1+v, v) % MOD

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

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

MOD = 10**9+7

class Comb:
    def __init__(self, N):
        self.fac = [1] * (N+1)
        for i in range(2, N+1): self.fac[i] = self.fac[i-1] * i % MOD

    def pow(self, a, b):
        res = 1
        while b:
            if b & 1: res = res * a % MOD
            a = a**2 % MOD
            b >>= 1
        return res

    def comb(self, n, r):
        if r < 0 or r > n: return 0
        return (self.fac[n] * self.pow(self.fac[r], MOD-2)) % MOD * self.pow(self.fac[n-r], MOD-2) % MOD

    def permutation(self, n, r):
        if r == 0: return 1
        return self.fac[n] * self.pow(self.fac[n-r], MOD-2) % MOD

from collections import *
import sys
def get_prime(n):
    c = Counter()

    while not n % 2:
        c[2] += 1
        n //= 2
    i = 3

    while i**2 <= n:
        while not n % i:
            c[i] += 1
            n //= i
        i += 2

    if n > 1: 
        c[n] += 1

    return c

prime = get_prime(M)
if not prime: print((1)); sys.exit()

comb = Comb(N+max([m for m in list(prime.values())]))

ans = 1

for n in list(prime.values()):
    ans = ans * comb.comb(N+n-1, n) % MOD
print((ans % MOD))
# Original solution
import math
def factorize(m):
    fct = []
    b = 2
    while b * b <= m:
        cnt = 0
        while m % b == 0:
            m //= b
            cnt += 1
        if b > 0:
            fct.append([b, cnt])
        b += 1 
    if m > 1:
        fct.append([m, 1])
    return fct

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

N, M = list(map(int, input().split()))
ans = 1
M_fct = factorize(M)

for mf in M_fct:
    #mf[1]個をN通りに分ける→comb(mf[1]+N-1,mf[1])
    ans *= comb(N + mf[1] - 1, mf[1])
print((ans% (10 ** 9 + 7)))

# Optimized solution
import math
def factorize(m):
    fct = []
    b = 2
    while b * b <= m:
        cnt = 0
        while m % b == 0:
            m //= b
            cnt += 1
        if cnt > 0:
            fct.append(cnt)
        b += 1
    if m > 1:
        fct.append(1)
    return fct

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

N, M = list(map(int, input().split()))
ans = 1
M_fct = factorize(M)

for mf in M_fct:
    #mf[1]個をN通りに分ける→comb(mf[1]+N-1,mf[1])
    ans *= comb(N + mf - 1, mf)
    ans %= 10**9+7
print(ans)
# Original solution
# encoding: utf-8
import math
N, M = list(map(int, input().split()))

def distribute(pos, full, tmp):
    return memo[tmp][pos]

# define search range
p_max = M // 2 # M is prime if M has a factor p (> p_max)
ip_up = max((1, int(math.log2(M)))) # MDE

#### O(MlogM) below (if M has a very large prime factor)
M_tmp = M
ips = []
for p in range(2, p_max + 1):
    if M_tmp % p > 0: continue
    # how many times M_tmp can be divided
    p_tmp = p
    for i_p in range(ip_up + 1):
        if M_tmp % p_tmp > 0: break
        p_tmp = p_tmp * p
    # calculate later
    ips.append(i_p)
    # next
    M_tmp = M_tmp // (p_tmp // p)
    if M_tmp == 1: break
#### O(Mlog M) above

#### O(N) below
# create memo
## init
if len(ips) > 0: ip_max = max(ips)
else: ip_max = 0
memo = [[None] * N for i in range(ip_max + 1)] # max ip
for j in range(N): memo[0][j] = 1
for i in range(1, ip_max + 1): memo[i][N - 1] = 1
## fill
for i in range(1, ip_max + 1):
    sum_tmp = 0
    vals = list(memo[i - 1])[::-1]
    p_memo = memo[i]
    for j, val in enumerate(vals):
        sum_tmp += val
        p_memo[N - 1 - j] = sum_tmp
#### O(N) above
        
# calculate ans
ans = 1
for i_p in ips: ans = (ans * distribute(0, i_p, i_p)) % (10 ** 9 + 7)

if M == 1: print((1))
elif ip_max < 1: print(N)
else: print(ans)

# Optimized solution
# encoding: utf-8
import math
N, M = list(map(int, input().split()))

ips = []
M_tmp = M
for p in range(2, int(math.sqrt(M)) + 1):
    if M_tmp % p > 0: continue
    for i_p in range(1, 33):
        if M_tmp % (p ** (i_p + 1)) > 0: break
    ips.append(i_p)
    M_tmp = M_tmp // (p ** i_p)
    if M_tmp == 1: break
else:
    ips.append(1)

#### O(NlogM) below ?
# create memo
## init
if len(ips) > 0: ip_max = max(ips)
else: ip_max = 0
memo = [[None] * N for i in range(ip_max + 1)] # max ip
for j in range(N): memo[0][j] = 1
for i in range(1, ip_max + 1): memo[i][N - 1] = 1
## fill
for i in range(1, ip_max + 1):
    sum_tmp = 0
    vals = list(memo[i - 1])[::-1]
    ptr_memo = memo[i]
    for j, val in enumerate(vals):
        sum_tmp += val
        ptr_memo[N - 1 - j] = sum_tmp
#### O(NlogM) above ?
        
# calculate ans
ans = 1
for i_p in ips:
    ans = (ans * memo[i_p][0]) % (10 ** 9 + 7)

if M == 1: print((1))
elif ip_max < 1: print(N)
else: print(ans)
# Original solution
#!/usr/bin/env python
import collections
from operator import mul
from functools import reduce
N, M = list(map(int, input().split()))

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

ps = []
tmp = M
for m in range(2, M+1):
    while tmp % m == 0:
        tmp /= m
        ps.append(m)
    if int(tmp) == 1:
        break
ps = collections.Counter(ps)

ans = 1
mod = 10**9+7
for c in list(ps.values()):
    ans *= cmb(c+N-1, c) % mod
    if ans > mod:
        ans %= mod

print(ans)


# Optimized solution
#!/usr/bin/env python
import collections
from operator import mul
from functools import reduce
N, M = list(map(int, input().split()))

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

ps = []
tmp = M
for m in range(2, M+1):
    while tmp % m == 0:
        tmp /= m
        ps.append(m)
    if int(tmp) == 1:
        break
    if m*m > M:
        if N > 1:
            ps.append(M)
        break

ps = collections.Counter(ps)

ans = 1
mod = 10**9+7
for c in list(ps.values()):
    ans *= cmb(c+N-1, c) % mod
    if ans > mod:
        ans %= mod

print(ans)
# Original solution
# coding:utf-8

INF = float('inf')
MOD = 10 ** 9 + 7


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


# nの素因数分解を求めるアルゴリズム
def p_factorization(n):
    tmp = []
    i = 2
    cnt = 0
    while n > 1:
        if n % i == 0:
            cnt += 1
            n //= i
        else:
            tmp.append([i, cnt])
            i += 1
            cnt = 0
    tmp.append([i, cnt])
    return tmp


# aのp乗を求めるアルゴリズム
# MOD版
# O(logp)
def pow_mod(a, p):
    if p == 0: return 1
    if p % 2 == 0:
        half_p = p // 2
        half = pow_mod(a, half_p)

        return half * half % MOD
    else:
        return a * pow_mod(a, p - 1) % MOD


# 組み合わせnCrを求めるアルゴリズム
# 逆元を使って計算
# MOD版
def cmb_mod(n, r):
    # 5C3 -> 5C2
    if r > n - r: return cmb_mod(n, n - r)
    ans_mul = 1
    ans_div = 1
    for i in range(r):
        ans_mul *= n - i
        ans_div *= i + 1
        ans_mul %= MOD
        ans_div %= MOD

    # ans_mul / ans_divをしたい
    # ans_divの逆元を使って求める
    ans = ans_mul * pow_mod(ans_div, MOD - 2) % MOD
    return ans


N, M = inpl()

fact = p_factorization(M)
ans = 1
for n, p in fact:
    ans *= cmb_mod(N - 1 + p, p)
    ans %= MOD

print(ans)


# Optimized solution
# coding:utf-8

INF = float('inf')
MOD = 10 ** 9 + 7


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


# aのp乗を求めるアルゴリズム
# MOD版
# O(logp)
def pow_mod(a, p):
    if p == 0: return 1
    if p % 2 == 0:
        half_p = p // 2
        half = pow_mod(a, half_p)

        return half * half % MOD
    else:
        return a * pow_mod(a, p - 1) % MOD


# 組み合わせnCrを求めるアルゴリズム
# 逆元を使って計算
# MOD版
def cmb_mod(n, r):
    # 5C3 -> 5C2
    if r > n - r: return cmb_mod(n, n - r)
    ans_mul = 1
    ans_div = 1
    for i in range(r):
        ans_mul *= n - i
        ans_div *= i + 1
        ans_mul %= MOD
        ans_div %= MOD

    # ans_mul / ans_divをしたい
    # ans_divの逆元を使って求める
    ans = ans_mul * pow_mod(ans_div, MOD - 2) % MOD
    return ans


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

if M != 1:
    ans *= cmb_mod(N - 1 + 1, 1)
    ans %= MOD
print(ans)
# Original solution
N,M = list(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 list(factors.values()):
    ans *= nhr(N,v)
    ans %= MOD
print(ans)


# Optimized solution
N,M = list(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 list(factors.values()):
    ans *= nhr(N,v)
    ans %= MOD
print(ans)
# Original solution
N,M = list(map(int,input().split()))
MOD = 10**9+7
MAXN = N+200
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)

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

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

# Optimized solution
N,M = list(map(int,input().split()))
MOD = 10**9+7

MAXN = N+100
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 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

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

ans = 1
f = factorize(M)
for v in list(f.values()):
    c = comb(N+v-1, v)
    ans *= c
    ans %= MOD
print(ans)
# Original solution
n,m=list(map(int, input().split()))

def combination(n,r):
    r=min(r,n-r)
    result=1
    for i in range(n-r+1,n+1):
        result*=i
    for i in range(1,r+1):
        result//=i
    return result

def factorize(n):
    i=2
    result={}
    while True:
        if i**2>n:
            break
        count=0
        while n%i==0:
            n//=i
            count+= 1
        if count!=0:
            result[i]=count
        i+=1
    if n>1:
        result[n]=1
    return result

ans=1
mod=10**9+7
f=factorize(m)
for i in list(f.values()):
    ci=combination(i+n-1,i)%mod
    ans=ans*ci%mod
print(ans)

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

def combination(n,r):
    r=min(r,n-r)
    result=1
    for i in range(n-r+1,n+1):
        result*=i
    for i in range(1,r+1):
        result//=i
    return result

def factorize(n):
    f=[]
    p=2
    cnt=0
    while p**2<=n:
        while n%p==0:
            cnt+=1
            n=n//p
        if cnt!=0:
            f.append([p,cnt])
            cnt=0
        p+=1
    if n!=1:
        f.append([n,1])
    return f

ans=1
mod=10**9+7
f=factorize(m)
for i in range(len(f)):
    k=f[i][1]
    ci=combination(k+n-1,k)%mod
    ans=ans*ci%mod
print(ans)
# Original solution
N, M = list(map(int, input().split()))

MOD = 10 ** 9 + 7


def prime_counter(n):
    ret = []
    for i in range(2, int(n / 2) + 2):
        count = 0
        while n % i == 0:
            n /= i
            count += 1
        if 0 < count:
            ret.append(count)
        if n == 1:
            break
    if 1 < n:
        ret.append(1)
    return ret


def comb(n, r):
    r = min(r, n - r)
    if r == 0:
        return 1
    elif r == 1:
        return n
    return (n % MOD) * pow(r, MOD - 2, MOD) * comb(n - 1, r - 1) % MOD


factnum = prime_counter(M)
ans = 1

for p in factnum:
    ans *= comb(p + N - 1, p)

ans %= MOD
print(ans)


# Optimized solution
MOD = 10 ** 9 + 7

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

f = []
p = 2
while p * p <= M:
    if M % p != 0:
        p += 1
        continue
    c = 0
    while M % p == 0:
        c += 1
        M //= p
    f.append(c)
    p += 1
if M != 1:
    f.append(1)

ans = 1
for i in f:
    c = 1
    for j in range(i):
        c = c * (N + j) // (j + 1)
    ans = ans * c % MOD
print(ans)
# Original solution
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):
    return factorial(num_object) // (factorial(num_object - num_bar) * 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 = list(map(int, input().split()))
    factor_count_list = Prime_Factorization(M)

    if (factor_count_list == 1):
        print(N)
    else:
        print((all_comb(N, factor_count_list)))

if __name__ == "__main__":
    main()

# Optimized solution
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 = list(map(int, input().split()))
    factor_count_list = Prime_Factorization(M)

    print((all_comb(N, factor_count_list)))

if __name__ == "__main__":
    main()
# Original solution
from math import factorial

def comb(n, r):
    return factorial(n) // factorial(r) // factorial(n - r)

n, m= [int(i) for i in input().split(" ")]

c = []
i = 2
mt = m

while i * i <= mt:
    ci = 0
    while mt % i == 0:
        mt = mt // i
        ci += 1
    if ci > 0:
        c.append(ci)
    i += 1
if mt > 1:
    c.append(1)
    
p = 1
for j in range(0, len(c)):
    p *= comb(n - 1 + c[j], c[j])

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

# Optimized solution
from operator import mul
from functools import reduce

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

n, m= [int(i) for i in input().split(" ")]

c = []
i = 2
mt = m

while i * i <= mt:
    ci = 0
    while mt % i == 0:
        mt = mt // i
        ci += 1
    if ci > 0:
        c.append(ci)
    i += 1
if mt > 1:
    c.append(1)
    
p = 1
for j in range(0, len(c)):
    p *= comb(n - 1 + c[j], c[j])

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