import sys



mod = 10 ** 9 + 7

sys.setrecursionlimit(mod)



def modpow(a, p):

    if p == 0:

        return 1

    if p % 2 == 0:

        half = modpow(a, p // 2)

        return half * half % mod

    else:

        return a * modpow(a, p - 1) % mod



def combinations(a, b):

    if 2 * b > a:

        return combinations(a, a - b)

    mul = 1

    div = 1

    for i in range(b):

        mul *= (a - i)

        div *= (i + 1)

        mul %= mod

        div %= mod

    return mul * modpow(div, mod - 2) % mod



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

i = 2

ans = 1

while i * i <= M:

    if M % i == 0:

        c = 0

        while M % i == 0:

            c += 1

            M /= i

        ans *= combinations(N + c - 1, N - 1)

        ans %= mod

    i += 1



if M != 1:

    ans *= combinations(N + 1 - 1, N - 1)

    ans %= mod



print(ans)
from collections import defaultdict



def sieve_of_eratosthenes(n):

    sr_n = int(n ** 0.5)

    f = [True] * (sr_n + 1)

    res = []

    for i in range(2, sr_n+1):

        if f[i]:

            res.append(i)

            for j in range(2*i, sr_n+1, i):

                f[j] = False

    return res



def trial_division(n):

    pn = sieve_of_eratosthenes(n)

    res = defaultdict(lambda: 0)

    for p in pn:

        while n % p == 0:

            res[p] += 1

            n //= p

    if n > 1:

        res[n] += 1

    return res



def nCr(n, r):

    r = min(r, n-r)

    fact = 1

    inv = 1

    for i in range(r):

        fact *= (n - i)

        fact %= MOD

        inv *= (i + 1)

        inv %= MOD

    return fact * pow(inv, MOD-2, MOD) % MOD



MOD = 10 ** 9 + 7

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

n_pf = list(trial_division(M).values())

ans = 1

for r in n_pf:

    ans *= nCr(N-1+r, r)

    ans %= MOD

print(ans)
import sys

mod = 10**9 + 7
sys.setrecursionlimit(mod)


def modpow(a, p):
    if p == 0:
        return 1
    if p % 2 == 0:
        half = modpow(a, p // 2)
        return half * half % mod
    else:
        return a * modpow(a, p - 1) % mod


def combinations(a, b):
    if 2 * b > a:
        return combinations(a, a - b)
    mul = 1
    div = 1
    for i in range(b):
        mul *= a - i
        div *= i + 1
        mul %= mod
        div %= mod
    return mul * modpow(div, mod - 2) % mod


N, M = list(map(int, input().split()))
i = 2
ans = 1
while i * i <= M:
    if M % i == 0:
        c = 0
        while M % i == 0:
            c += 1
            M /= i
        ans *= combinations(N + c - 1, N - 1)
        ans %= mod
    i += 1
if M != 1:
    ans *= combinations(N + 1 - 1, N - 1)
    ans %= mod
print(ans)

from collections import defaultdict


def sieve_of_eratosthenes(n):
    sr_n = int(n**0.5)
    f = [True] * (sr_n + 1)
    res = []
    for i in range(2, sr_n + 1):
        if f[i]:
            res.append(i)
            for j in range(2 * i, sr_n + 1, i):
                f[j] = False
    return res


def trial_division(n):
    pn = sieve_of_eratosthenes(n)
    res = defaultdict(lambda: 0)
    for p in pn:
        while n % p == 0:
            res[p] += 1
            n //= p
    if n > 1:
        res[n] += 1
    return res


def nCr(n, r):
    r = min(r, n - r)
    fact = 1
    inv = 1
    for i in range(r):
        fact *= n - i
        fact %= MOD
        inv *= i + 1
        inv %= MOD
    return fact * pow(inv, MOD - 2, MOD) % MOD


MOD = 10**9 + 7
N, M = list(map(int, input().split()))
n_pf = list(trial_division(M).values())
ans = 1
for r in n_pf:
    ans *= nCr(N - 1 + r, r)
    ans %= MOD
print(ans)

-import sys - -mod = 10**9 + 7 -sys.setrecursionlimit(mod) +from collections import defaultdict -def modpow(a, p): -    if p == 0: -        return 1 -    if p % 2 == 0: -        half = modpow(a, p // 2) -        return half * half % mod -    else: -        return a * modpow(a, p - 1) % mod +def sieve_of_eratosthenes(n): +    sr_n = int(n**0.5) +    f = [True] * (sr_n + 1) +    res = [] +    for i in range(2, sr_n + 1): +        if f[i]: +            res.append(i) +            for j in range(2 * i, sr_n + 1, i): +                f[j] = False +    return res -def combinations(a, b): -    if 2 * b > a: -        return combinations(a, a - b) -    mul = 1 -    div = 1 -    for i in range(b): -        mul *= a - i -        div *= i + 1 -        mul %= mod -        div %= mod -    return mul * modpow(div, mod - 2) % mod +def trial_division(n): +    pn = sieve_of_eratosthenes(n) +    res = defaultdict(lambda: 0) +    for p in pn: +        while n % p == 0: +            res[p] += 1 +            n //= p +    if n > 1: +        res[n] += 1 +    return res +def nCr(n, r): +    r = min(r, n - r) +    fact = 1 +    inv = 1 +    for i in range(r): +        fact *= n - i +        fact %= MOD +        inv *= i + 1 +        inv %= MOD +    return fact * pow(inv, MOD - 2, MOD) % MOD + + +MOD = 10**9 + 7 -i = 2 +n_pf = list(trial_division(M).values()) -while i * i <= M: -    if M % i == 0: -        c = 0 -        while M % i == 0: -            c += 1 -            M /= i -        ans *= combinations(N + c - 1, N - 1) -        ans %= mod -    i += 1 -if M != 1: -    ans *= combinations(N + 1 - 1, N - 1) -    ans %= mod +for r in n_pf: +    ans *= nCr(N - 1 + r, r) +    ans %= MOD