CodeEff/ECCO huggingface dataset:
# Original solution
from collections import defaultdict


def prepare(n, MOD):
    f = 1
    factorials = [1] * (n + 1)
    for m in range(1, n + 1):
        f *= m
        f %= MOD
        factorials[m] = f
    inv = pow(f, MOD - 2, MOD)
    invs = [1] * (n + 1)
    invs[n] = inv
    for m in range(n, 1, -1):
        inv *= m
        inv %= MOD
        invs[m - 1] = inv

    return factorials, invs


def prime_factorize(n):
    f = defaultdict(lambda: 0)
    f[2] = len(bin(n & -n)) - 3
    i = 3
    k = n >> f[2]
    while k > 1:
        while True:
            d, m = divmod(k, i)
            if m == 0:
                f[i] += 1
                k = d
            else:
                break
        i += 2
    return f


MOD = 1000000007
n, m = list(map(int, input().split()))
pf = prime_factorize(m)
mx = max(pf.values())
f, r = prepare(n + mx - 1, MOD)
ans = 1
for p, e in list(pf.items()):
    ans *= f[n + e - 1]
    ans %= MOD
    ans *= r[n - 1]
    ans %= MOD
    ans *= r[e]
    ans %= MOD
print(ans)


# Optimized solution
from collections import defaultdict


def prepare(n, MOD):
    f = 1
    factorials = [1] * (n + 1)
    for m in range(1, n + 1):
        f *= m
        f %= MOD
        factorials[m] = f
    inv = pow(f, MOD - 2, MOD)
    invs = [1] * (n + 1)
    invs[n] = inv
    for m in range(n, 1, -1):
        inv *= m
        inv %= MOD
        invs[m - 1] = inv

    return factorials, invs


def prime_factorize(n):
    f = defaultdict(lambda: 0)
    f[2] = len(bin(n & -n)) - 3
    i = 3
    k = n >> f[2]
    limit = k ** 0.5
    while 1 < k and i <= limit:
        while True:
            d, m = divmod(k, i)
            if m == 0:
                f[i] += 1
                k = d
            else:
                break
        i += 2
    if k > 1:
        f[k] = 1
    return f


MOD = 1000000007
n, m = list(map(int, input().split()))
pf = prime_factorize(m)
mx = max(pf.values())
f, r = prepare(n + mx - 1, MOD)
ans = 1
for p, e in list(pf.items()):
    ans *= f[n + e - 1]
    ans %= MOD
    ans *= r[n - 1]
    ans %= MOD
    ans *= r[e]
    ans %= MOD
print(ans)
# Original solution
from collections import defaultdict


def prepare(n, MOD):
    f = 1
    factorials = [1] * (n + 1)
    for m in range(1, n + 1):
        f *= m
        f %= MOD
        factorials[m] = f
    inv = pow(f, MOD - 2, MOD)
    invs = [1] * (n + 1)
    invs[n] = inv
    for m in range(n, 1, -1):
        inv *= m
        inv %= MOD
        invs[m - 1] = inv

    return factorials, invs


def prime_factorize(n):
    f = defaultdict(lambda: 0)
    f[2] = len(bin(n & -n)) - 3
    i = 3
    k = n >> f[2]
    limit = k ** 0.5
    while 1 < k and i <= limit:
        while True:
            d, m = divmod(k, i)
            if m == 0:
                f[i] += 1
                k = d
            else:
                break
        i += 2
    if k > 1:
        f[k] = 1
    return f


MOD = 1000000007
n, m = list(map(int, input().split()))
pf = prime_factorize(m)
mx = max(pf.values())
f, r = prepare(n + mx - 1, MOD)
ans = 1
for p, e in list(pf.items()):
    ans *= f[n + e - 1]
    ans %= MOD
    ans *= r[n - 1]
    ans %= MOD
    ans *= r[e]
    ans %= MOD
print(ans)


# Optimized solution
from collections import defaultdict


def prepare(n, MOD):
    f = 1
    factorials = [1] * (n + 1)
    for m in range(1, n + 1):
        f *= m
        f %= MOD
        factorials[m] = f
    inv = pow(f, MOD - 2, MOD)
    invs = [1] * (n + 1)
    invs[n] = inv
    for m in range(n, 1, -1):
        inv *= m
        inv %= MOD
        invs[m - 1] = inv

    return factorials, invs


def prime_factorize(n):
    f = defaultdict(lambda: 0)
    f[2] = len(bin(n & -n)) - 3
    i = 3
    k = n >> f[2]
    limit = k ** 0.5
    while 1 < k and i <= limit:
        while True:
            d, m = divmod(k, i)
            if m == 0:
                f[i] += 1
                k = d
                limit = k ** 0.5
            else:
                break
        i += 2
    if k > 1:
        f[k] = 1
    return f


MOD = 1000000007
n, m = list(map(int, input().split()))
pf = prime_factorize(m)
mx = max(pf.values())
f, r = prepare(n + mx - 1, MOD)
ans = 1
for p, e in list(pf.items()):
    ans *= f[n + e - 1]
    ans %= MOD
    ans *= r[n - 1]
    ans %= MOD
    ans *= r[e]
    ans %= MOD
print(ans)
# Original solution
n,m=list(map(int,input().split()))

def c(n,m):
    import math
    if n-m<0:
        return 0
    return(math.factorial(n)//math.factorial(n-m)//math.factorial(m))

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)
mod=10**9+7
ans=1
for i,j in l:
    ans*=c(j+n-1,j)
    ans=ans%mod

print(ans)

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

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)
mod=10**9+7
ans=1

def inv(x):
    return pow(x, mod - 2, mod)
 
cms = 10**5 + 100
cm = [0] * cms
 
def comb_init():
    cm[0] = 1
    for i in range(1, cms):
        cm[i] = cm[i-1] * i % mod
 
def c(a, b):
    return (cm[a] * inv(cm[a-b]) % mod) * inv(cm[b]) % mod

mod=10**9+7
comb_init()

for i,j in l:
    ans*=c(j+n-1,j)
    ans=ans%mod

print(ans)
# Original solution
def soin(num):
    re = []
    div = 2
    while 1:
        lim = int(num ** 0.5) + 1
        while num % div:
            div += 1
            if div > lim:
                re += [1]
                return re
        sisu = 0
        while num % div == 0:
            num //= div
            sisu += 1
        re += [sisu]
        if num == 1:
            return re


def com(a, b):
    if a == b:
        return 1
    t = (a, b)
    if (a, b) in com_memo:
        return com_memo[t]
    re = com(a - 1, b) * a // (a - b)
    com_memo[t] = re
    return re


def f(n, m):
    sisus = soin(m)
    ans = 1
    for s in sisus:
        ans = ans * com(s + n - 1, n - 1) % md
    print(ans)


md = 10 ** 9 + 7
n, m = list(map(int, input().split()))
if m==1:
    print((1))
    exit()
com_memo = {}
f(n, m)


# Optimized solution
def soin(num):
    re = []
    div = 2
    while 1:
        lim = int(num ** 0.5) + 1
        while num % div:
            div += 1
            if div > lim:
                re += [1]
                return re
        sisu = 0
        while num % div == 0:
            num //= div
            sisu += 1
        re += [sisu]
        if num == 1:
            return re


def com(a, b):
    if a == b:
        return 1
    t = (a, b)
    if (a, b) in com_memo:
        return com_memo[t]
    re = com(a - 1, b) * a // (a - b)
    com_memo[t] = re
    return re


def f(n, m):
    if m == 1:
        print((1))
        return
    sisus = soin(m)
    ans = 1
    for s in sisus:
        ans = ans * com(s + n - 1, n - 1) % md
    print(ans)


md = 10 ** 9 + 7
n, m = list(map(int, input().split()))
com_memo = {}
f(n, m)
# Original solution
import sys
readline = sys.stdin.buffer.readline
from collections import Counter
n,m = list(map(int,readline().split()))
mod = 10**9+7

"""素因数分解"""
def factrize(n):
    b = 2
    fct = []
    while b*b <= n:
        while n % b == 0:
            n //= b
            #もし素因数を重複させたくないならここを加えてfct.append(b)を消す
            """
            if not b in fct:
                fct.append(b)
            """
            fct.append(b)
        b = b+1
    if n > 1:
        fct.append(n)
    return fct #リストが帰る
def pow(n,p,mod=10**9+7): #繰り返し二乗法(nのp乗)
    res = 1
    while p > 0:
        if p % 2 == 0:
            n = n ** 2 % mod
            p //= 2
        else:
            res = res * n % mod
            p -= 1
    return res % mod
def factrial_memo(n=20**5+1,mod=10**9+7):
    fact = [1, 1]
    for i in range(2, n + 1):
        fact.append((fact[-1] * i) % mod)
    return fact
fact = factrial_memo()
def fermat_cmb(n, r, mod=10**9+7): #needs pow,factrial_memo(only fact). return nCk
    return fact[n] * pow(fact[r],mod-2) * pow(fact[n-r],mod-2) %mod

lst1 = factrize(m)

c = Counter(lst1)

ans = 1
for i in list(c.values()):
    ans *= fermat_cmb(n+i-1,i)
    ans %= mod

print(ans)
    

# Optimized solution
import sys
readline = sys.stdin.buffer.readline
def even(n): return 1 if n%2==0 else 0
"""
1*1*1*1*m = mなども含める
4をそのまま使う場合と2*2に分ける場合などの場合分けが必要
約数列挙からどうこうする？

"""
n,m = list(map(int,readline().split()))
mod = 10**9+7

def pow(n,p,mod=10**9+7): #繰り返し二乗法(nのp乗)
    res = 1
    while p > 0:
        if p % 2 == 0:
            n = n ** 2 % mod
            p //= 2
        else:
            res = res * n % mod
            p -= 1
    return res % mod
def factrial_memo(n=10**6,mod=10**9+7):
    fact = [1, 1]
    for i in range(2, n + 1):
        fact.append((fact[-1] * i) % mod)
    return fact
fact = factrial_memo()

"""素因数分解"""
def factrize(n):
    b = 2
    fct = []
    while b*b <= n:
        while n % b == 0:
            n //= b
            #もし素因数を重複させたくないならここを加えてfct.append(b)を消す
            """
            if not b in fct:
                fct.append(b)
            """
            fct.append(b)
        b = b+1
    if n > 1:
        fct.append(n)
    return fct #リストが帰る

prime = factrize(m)

from collections import defaultdict
dic1 = defaultdict(int)

for i in prime:
    dic1[i] += 1

ans = 1

for i in list(dic1.values()):
    ans *= fact[n+i-1]*pow(fact[n-1],mod-2)*pow(fact[i],mod-2)
    ans %= mod
print(ans)
# Original solution
# https://atcoder.jp/contests/abc110/tasks/abc110_d

def get_prime_dic(n):
    dic = {}

    while n % 2 == 0:
        if 2 in dic:
            dic[2] += 1
        else:
            dic[2] = 1
        n = n // 2

    i = 3
    while i <= n:
        while n % i == 0:
            n //= i
            if i in dic:
                dic[i] += 1
            else:
                dic[i] = 1
        i += 2
    if n > 1:
        dic[n] = 1
    return dic


# Calculate count of combination
def combination(n, r):
    a = 1
    b = 1
    for i in range(r):
        a *= (n - i)
        b *= (i + 1)
    return a // b


def main():
    N, M = list(map(int, input().split()))
    d = get_prime_dic(M)
    # print(d)

    ans = 1
    for k, v in list(d.items()):
        ans *= combination(v + N - 1, v)
        ans %= 1000000007

    print(ans)


main()


# Optimized solution
N, M = [int(i) for i in input().split()]
mod = 10 ** 9 + 7
def func(M):
  res = []
  i = 2
  while i * i <= M:
    c=0
    while M % i == 0:
      M /= i
      c += 1
    if c > 0:
      res.append(c)
    i += 1
  if M > 1:
    res.append(1)
  return res

def conb(n, r):
  N, R = n, r
  for i in range(1, r):
    N *= n-i
    R *= r-i
  return N // R

res = func(M)
ans = 1
for i in res:
  ans = (ans * conb(i+N-1, i)) % mod
print(ans)
# Original solution
from math import factorial as fact
import sys
input = sys.stdin.readline

N, M = list(map(int, input().split()))
num = []
p_flag = [True]*(int(M**0.5)+2)

for i in range(2, int(M**0.5)+2):
    if p_flag:
        for j in range(2*i, int(M**0.5)+2, i):
            p_flag[j] = False

        cnt = 0
        while M % i == 0:
            cnt += 1
            M //= i
        if cnt > 0:
            num.append(cnt)
        if M == 1:
            break
else:
    num.append(1)

ans = 1
for i in num:
    ans = (ans * fact(N-1+i)//(fact(i)*fact(N-1))) % (10**9+7)
print(ans)

# Optimized solution
from math import factorial as fact
from operator import mul
from functools import reduce
import sys
input = sys.stdin.readline


def cmb(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 = list(map(int, input().split()))
num = []
p_flag = [True]*(int(M**0.5)+2)

for i in range(2, int(M**0.5)+2):
    if p_flag:
        for j in range(2*i, int(M**0.5)+2, i):
            p_flag[j] = False

        cnt = 0
        while M % i == 0:
            cnt += 1
            M //= i
        if cnt > 0:
            num.append(cnt)
        if M == 1:
            break
else:
    num.append(1)

ans = 1
for i in num:
    ans = (ans * cmb(N-1+i, i)) % (10**9+7)
print(ans)
# Original solution
import math
from collections import Counter
from functools import reduce
from operator import mul


def get_factors(n):
    """
    素因数分解
    :param int n:
    :type: list of int
    """
    if n <= 1:
        return []

    ret = []
    while n > 2 and n % 2 == 0:
        ret.append(2)
        n //= 2
    i = 3
    while i <= n / 2:
        if n % i == 0:
            ret.append(i)
            n //= i
        else:
            i += 2
    ret.append(n)
    return ret


def comb(n, r):
    """
    組み合わせの数 nCr
    :param n:
    :param r:
    :return:
    """
    r = min(n - r, r)
    if r == 0:
        return 1
    return reduce(mul, list(range(n, n - r, -1))) // reduce(mul, list(range(r, 0, -1)))


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

# divs = sorted(get_divisors(m))
# # dp[d]: 累積積が d となる数列の数
# dp = {d: 1 for d in divs}
# for _ in range(n - 1):
#     for i in reversed(range(len(divs))):
#         div = divs[i]
#         dp[div] = sum([dp[d] for d in divs if div % d == 0]) % MOD
#     print(dp)
# print(dp)
# おそい


factors = get_factors(m)
counts = Counter(factors)
# k**v を全部かけあわせたやつが m に一致する
# print(functools.reduce(operator.mul, [k ** v for k, v in counts.items()]))

# v 個の k を n 個の数に配分する組み合わせの数
# → v + (n-1) 個のスペースへの v の置き方の組み合わせの数
ans = 1
for k, v in list(counts.items()):
    ans *= comb(v + (n - 1), v)
    ans %= MOD
print(ans)


# Optimized solution
import math
from collections import Counter
from functools import reduce
from operator import mul


def get_factors(n):
    """
    素因数分解
    :param int n:
    :type: list of int
    """
    if n <= 1:
        return []

    ret = []
    while n > 2 and n % 2 == 0:
        ret.append(2)
        n //= 2
    i = 3
    while i <= math.sqrt(n):
        if n % i == 0:
            ret.append(i)
            n //= i
        else:
            i += 2
    ret.append(n)
    return ret


def comb(n, r):
    """
    組み合わせの数 nCr
    :param n:
    :param r:
    :return:
    """
    r = min(n - r, r)
    if r == 0:
        return 1
    return reduce(mul, list(range(n, n - r, -1))) // reduce(mul, list(range(r, 0, -1)))


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

# divs = sorted(get_divisors(m))
# # dp[d]: 累積積が d となる数列の数
# dp = {d: 1 for d in divs}
# for _ in range(n - 1):
#     for i in reversed(range(len(divs))):
#         div = divs[i]
#         dp[div] = sum([dp[d] for d in divs if div % d == 0]) % MOD
#     print(dp)
# print(dp)
# おそい


factors = get_factors(m)
counts = Counter(factors)
# k**v を全部かけあわせたやつが m に一致する
# print(functools.reduce(operator.mul, [k ** v for k, v in counts.items()]))

# v 個の k を n 個の数に配分する組み合わせの数
# → v + (n-1) 個のスペースへの v の置き方の組み合わせの数
ans = 1
for k, v in list(counts.items()):
    ans *= comb(v + (n - 1), v)
    ans %= MOD
print(ans)
# Original solution
import math
import os
import sys
from collections import Counter

if os.getenv("LOCAL"):
    sys.stdin = open("_in.txt", "r")

sys.setrecursionlimit(2147483647)
INF = float("inf")
IINF = 10 ** 18
MOD = 10 ** 9 + 7

N, M = list(map(int, sys.stdin.readline().split()))


def get_factors(n):
    """
    素因数分解
    :param int n:
    :rtype: list of int
    """
    if n <= 1:
        return []

    ret = []
    while n > 2 and n % 2 == 0:
        ret.append(2)
        n //= 2
    i = 3
    while i <= math.sqrt(n):
        if n % i == 0:
            ret.append(i)
            n //= i
        else:
            i += 2
    ret.append(n)
    return ret


def ncr(n, r, mod=None):
    """
    scipy.misc.comb または scipy.special.comb と同じ
    組み合わせの数 nCr
    :param int n:
    :param int r:
    :param int mod: 3 以上の素数であること
    :rtype: int
    """
    if n < r:
        return 0

    return math.factorial(n) // math.factorial(r) // math.factorial(n - r)


factors = get_factors(M)

ans = 1
for c in list(Counter(factors).values()):
    # N 個の箱から重複ありで c 個選ぶ
    ans = ans * ncr(N + c - 1, c) % MOD
print(ans)


# Optimized solution
import math
import os
import sys
from collections import Counter
from functools import reduce

from operator import mul

if os.getenv("LOCAL"):
    sys.stdin = open("_in.txt", "r")

sys.setrecursionlimit(2147483647)
INF = float("inf")
IINF = 10 ** 18
MOD = 10 ** 9 + 7

N, M = list(map(int, sys.stdin.readline().split()))


def get_factors(n):
    """
    素因数分解
    :param int n:
    :rtype: list of int
    """
    if n <= 1:
        return []

    ret = []
    while n > 2 and n % 2 == 0:
        ret.append(2)
        n //= 2
    i = 3
    while i <= math.sqrt(n):
        if n % i == 0:
            ret.append(i)
            n //= i
        else:
            i += 2
    ret.append(n)
    return ret


def ncr(n, r, mod=None):
    """
    scipy.misc.comb または scipy.special.comb と同じ
    組み合わせの数 nCr
    :param int n:
    :param int r:
    :param int mod: 3 以上の素数であること
    :rtype: int
    """
    if n < r:
        return 0
    r = min(n - r, r)
    if r == 0:
        return 1
    return reduce(mul, list(range(n, n - r, -1))) // reduce(mul, list(range(r, 0, -1)))


factors = get_factors(M)

ans = 1
for c in list(Counter(factors).values()):
    # N 個の箱から重複ありで c 個選ぶ
    ans = ans * ncr(N + c - 1, c) % MOD
print(ans)
# Original solution
from math import factorial as f
N, M = list(map(int, input().split()))
a1, a2 = 2, M
a = {}
while (a1 - 1) ** 2 <= a2 or a1 == a2:
    if a2 % a1 == 0:
        a2 //= a1
        if a1 in a:
            a[a1] += 1
        else:
            a[a1] = 1
    else:
        a1 += 1
p = 1
if a2 != 1:
    a[a2] = 1
for v in list(a.values()):
    p *= f(v + N - 1) // (f(v) * f(N - 1))
print((p % (10 ** 9 + 7)))

# Optimized solution
N, M = list(map(int, input().split()))
a1, a2 = 2, M
a = {}
while (a1 - 1) ** 2 <= a2 or a1 == a2:
    if a2 % a1 == 0:
        a2 //= a1
        if a1 in a:
            a[a1] += 1
        else:
            a[a1] = 1
    else:
        a1 += 1
p = 1
if a2 != 1:
    a[a2] = 1
for v in list(a.values()):
    tmp = 1
    for i in range(v):
        tmp = tmp * (v + N - 1 - i) // (i + 1)
    p *= tmp
print((p % (10 ** 9 + 7)))
# Original solution
import math

def prime_division(n):
    ans = []
    m = int(n ** 0.5)
    i = 2
    while i <= m:
        if n % i == 0:
            cnt = 0
            while n % i == 0:
                n //= i
                cnt += 1
            ans.append((i, cnt))
            m = int(n ** 0.5)
        i += 1
    if n != 1:
        ans.append((n, 1))
    return ans

#  aabaaba  count+(N-1) C (N-1)

N,M=list(map(int,input().split()))
pms=prime_division(M)
ans = 1
for pm in pms:
    #print(pm)
    ans *= math.factorial(pm[1]+(N-1)) // (math.factorial(pm[1]) * math.factorial(N-1))

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


# Optimized solution
import math

def prime_division(n):
    ans = []
    m = int(n ** 0.5)
    i = 2
    while i <= m:
        if n % i == 0:
            cnt = 0
            while n % i == 0:
                n //= i
                cnt += 1
            ans.append((i, cnt))
            m = int(n ** 0.5)
        i += 1
    if n != 1:
        ans.append((n, 1))
    return ans

def combination(n, r):
    ans = 1
    if n - r < r:
        r = n - r
    for i in range(r):
        ans *= n - i
    ans //= math.factorial(r)
    return ans

#  aabaaba  count+(N-1) C (N-1)

N,M=list(map(int,input().split()))
pms=prime_division(M)
ans = 1
for pm in pms:
    #print(pm)
    ans *= combination(pm[1]+(N-1), N-1)

print((ans % (10 ** 9 + 7)))
# Original solution
def prime_factorize(num):
    """
    This function performs prime factorization on the input natural number.
    The result is returned in the form of a dictionary with the prime number as the key
    and its number as the value.
    :param num:
    :return prime_factor: Dictionary with the prime number as the key and its number as the value.
    """
    prime_factor = {}
    i = 2
    while i ** 2 <= num:
        while num % i == 0:
            num //= i
            if i in list(prime_factor.keys()):
                prime_factor[i] += 1
            else:
                prime_factor[i] = 1
        i += 1
    if num > 1:
        prime_factor[num] = 1
    return prime_factor


from math import factorial


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


n, m = list(map(int, input().split()))
r = 1
prime_fac = prime_factorize(m)
for v in list(prime_fac.values()):
    r *= comb(v+n-1, v)
mod = 1000000000 + 7
print((r % mod))


# Optimized solution
def prime_factorize(num):
    """
    This function performs prime factorization on the input natural number.
    The result is returned in the form of a dictionary with the prime number as the key
    and its number as the value.
    :param num:
    :return prime_factor: Dictionary with the prime number as the key and its number as the value.
    """
    prime_factor = {}
    i = 2
    while i ** 2 <= num:
        while num % i == 0:
            num //= i
            if i in list(prime_factor.keys()):
                prime_factor[i] += 1
            else:
                prime_factor[i] = 1
        i += 1
    if num > 1:
        prime_factor[num] = 1
    return prime_factor


from math import factorial


def comb(n, r, R):
    if n not in R:
        a = factorial(n)
        R[n] = a
    else:
        a = R[n]

    if n - r not in R:
        b = factorial(n - r)
        R[n - r] = b
    else:
        b = R[n - r]

    if r not in R:
        c = factorial(r)
        R[r] = c
    else:
        c = R[r]
    return a // (b * c)


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

R = dict()
prime_fac = prime_factorize(m)
for v in list(prime_fac.values()):
    r *= comb(v + n - 1, v, R)
mod = 1000000000 + 7
print((r % mod))
# Original solution
def prime_factorize(num):
    """
    This function performs prime factorization on the input natural number.
    The result is returned in the form of a dictionary with the prime number as the key
    and its number as the value.
    :param num:
    :return prime_factor: Dictionary with the prime number as the key and its number as the value.
    """
    prime_factor = {}
    i = 2
    while i ** 2 <= num:
        while num % i == 0:
            num //= i
            if i in list(prime_factor.keys()):
                prime_factor[i] += 1
            else:
                prime_factor[i] = 1
        i += 1
    if num > 1:
        prime_factor[num] = 1
    return prime_factor


from math import factorial


def comb(n, r, R):
    if n not in R:
        a = factorial(n)
        R[n] = a
    else:
        a = R[n]

    if n - r not in R:
        b = factorial(n - r)
        R[n - r] = b
    else:
        b = R[n - r]

    if r not in R:
        c = factorial(r)
        R[r] = c
    else:
        c = R[r]
    return a // (b * c)


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

R = dict()
prime_fac = prime_factorize(m)
for v in list(prime_fac.values()):
    r *= comb(v + n - 1, v, R)
mod = 1000000000 + 7
print((r % mod))


# Optimized solution
def prime_factorize(num):
    """
    This function performs prime factorization on the input natural number.
    The result is returned in the form of a dictionary with the prime number as the key
    and its number as the value.
    :param num:
    :return prime_factor: Dictionary with the prime number as the key and its number as the value.
    """
    prime_factor = {}
    i = 2
    while i ** 2 <= num:
        while num % i == 0:
            num //= i
            if i in list(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 = list(map(int, input().split()))
r = 1

prime_fac = prime_factorize(m)
for v in list(prime_fac.values()):
    r *= combination(v + n - 1, v)
mod = 1000000000 + 7
print((r % mod))