# -*- coding: utf-8 -*-



"""

参考：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)

    # 終点はルート切り捨て+1

    end = int(sqrt(num)) + 1

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

        cnt = 0

        # 素因数分解：小さい方から割れるだけ割って素数をカウント

        while num % i == 0:

            num //= i

            d[i] += 1

        # 1まで来たら終了

        if num == 1:

            break

    # 最後までそのまま来たやつはnumが素数(ただし1^1は1^0なので数に入れない)

    if num != 1:

        d[num] += 1

    return d



# とりあえずv+N-1が収まればいいはず

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)

# powに第三引数入れると冪乗のmod付計算を高速にやってくれる

inverse[MAX-1] = pow(factorial[MAX-1], MOD-2, MOD)

for i in range(MAX-2, 0, -1):

    # 最後から戻っていくこのループならH+W回powするより処理が速い

    inverse[i] = inverse[i+1] * (i+1) % MOD



# 組み合わせの数

def nCr(n, r):

    # 10C7 = 10C3

    r = min(r, n-r)

    # 分子の計算

    numerator = factorial[n]

    # 分母の計算

    denominator = inverse[r] * inverse[n-r] % MOD

    return numerator * denominator % MOD



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



# d = fact_prime(M)

# print(d)

ans = 1

for k, v in list(fact_prime(M).items()):

    # 重複組み合わせ

    # v個のkとN-1個の仕切りから、v個を並べる(v+N-1個のマスからv個を選び出す組み合わせ)

    ans = (ans * nCr(v+N-1, v)) % MOD

print(ans)

# -*- coding: utf-8 -*-



import sys



def input(): return sys.stdin.readline().strip()

def list2d(a, b, c): return [[c] * b for i in range(a)]

def list3d(a, b, c, d): return [[[d] * c for j in range(b)] for i in range(a)]

def list4d(a, b, c, d, e): return [[[[e] * d for j in range(c)] for j in range(b)] for i in range(a)]

def ceil(x, y=1): return int(-(-x // y))

def INT(): return int(eval(input()))

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

def LIST(N=None): return list(MAP()) if N is None else [INT() for i in range(N)]

def Yes(): print('Yes')

def No(): print('No')

def YES(): print('YES')

def NO(): print('NO')

sys.setrecursionlimit(10 ** 9)

INF = float('inf')

MOD = 10 ** 9 + 7



def factorize(num: int) -> dict:

    """ 素因数分解 """

    from math import sqrt

    from collections import Counter



    d = Counter()

    # 終点はルート切り捨て+1

    for i in range(2, int(sqrt(num))+1):

        # 素因数分解：小さい方から割れるだけ割って素数をカウント

        while num % i == 0:

            num //= i

            d[i] += 1

        # 1まで分解したら終了

        if num == 1:

            break

    # 最後に残ったnumは素数(ただし1^1は1^0なので数に入れない)

    if num != 1:

        d[num] += 1

    return d



class FactInvMOD:

    """ 階乗たくさん使う時用のテーブル準備 """



    def __init__(self, MAX, MOD):

        """ MAX：階乗に使う数値の最大以上まで作る """

        

        MAX += 1

        self.MAX = MAX

        self.MOD = MOD

        # 階乗テーブル

        factorial = [1] * MAX

        factorial[0] = factorial[1] = 1

        for i in range(2, MAX):

            factorial[i] = factorial[i-1] * i % MOD

        # 階乗の逆元テーブル

        inverse = [1] * MAX

        # powに第三引数入れると冪乗のmod付計算を高速にやってくれる

        inverse[MAX-1] = pow(factorial[MAX-1], MOD-2, MOD)

        for i in range(MAX-2, 0, -1):

            # 最後から戻っていくこのループならMAX回powするより処理が速い

            inverse[i] = inverse[i+1] * (i+1) % MOD

        self.fact = factorial

        self.inv = inverse

    

    def nCr(self, n, r):

        """ 組み合わせの数 (必要な階乗と逆元のテーブルを事前に作っておく) """



        if n < r: return 0

        # 10C7 = 10C3

        r = min(r, n-r)

        # 分子の計算

        numerator = self.fact[n]

        # 分母の計算

        denominator = self.inv[r] * self.inv[n-r] % self.MOD

        return numerator * denominator % self.MOD



    def nPr(self, n, r):

        """ 順列 """



        if n < r: return 0

        return self.fact[n] * self.inv[n-r] % self.MOD



    def nHr(self, n, r):

        """ 重複組み合わせ """



        # r個選ぶところにN-1個の仕切りを入れる

        return self.nCr(r+n-1, r)



N, M = MAP()



d = factorize(M)



# 例外処理

if not d:

    print((1))

    exit()



MAX = N + max(d.values())

fim = FactInvMOD(MAX, MOD)

ans = 1

for k, v in list(d.items()):

    ans *= fim.nHr(N, v)

    ans %= MOD

print(ans)

# -*- coding: utf-8 -*-
"""
参考：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)
    # 終点はルート切り捨て+1
    end = int(sqrt(num)) + 1
    for i in range(2, end + 1):
        cnt = 0
        # 素因数分解：小さい方から割れるだけ割って素数をカウント
        while num % i == 0:
            num //= i
            d[i] += 1
        # 1まで来たら終了
        if num == 1:
            break
    # 最後までそのまま来たやつはnumが素数(ただし1^1は1^0なので数に入れない)
    if num != 1:
        d[num] += 1
    return d


# とりあえずv+N-1が収まればいいはず
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)
# powに第三引数入れると冪乗のmod付計算を高速にやってくれる
inverse[MAX - 1] = pow(factorial[MAX - 1], MOD - 2, MOD)
for i in range(MAX - 2, 0, -1):
    # 最後から戻っていくこのループならH+W回powするより処理が速い
    inverse[i] = inverse[i + 1] * (i + 1) % MOD
# 組み合わせの数
def nCr(n, r):
    # 10C7 = 10C3
    r = min(r, n - r)
    # 分子の計算
    numerator = factorial[n]
    # 分母の計算
    denominator = inverse[r] * inverse[n - r] % MOD
    return numerator * denominator % MOD


N, M = list(map(int, input().split()))
# d = fact_prime(M)
# print(d)
ans = 1
for k, v in list(fact_prime(M).items()):
    # 重複組み合わせ
    # v個のkとN-1個の仕切りから、v個を並べる(v+N-1個のマスからv個を選び出す組み合わせ)
    ans = (ans * nCr(v + N - 1, v)) % MOD
print(ans)

# -*- coding: utf-8 -*-
import sys


def input():
    return sys.stdin.readline().strip()


def list2d(a, b, c):
    return [[c] * b for i in range(a)]


def list3d(a, b, c, d):
    return [[[d] * c for j in range(b)] for i in range(a)]


def list4d(a, b, c, d, e):
    return [[[[e] * d for j in range(c)] for j in range(b)] for i in range(a)]


def ceil(x, y=1):
    return int(-(-x // y))


def INT():
    return int(eval(input()))


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


def LIST(N=None):
    return list(MAP()) if N is None else [INT() for i in range(N)]


def Yes():
    print("Yes")


def No():
    print("No")


def YES():
    print("YES")


def NO():
    print("NO")


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


def factorize(num: int) -> dict:
    """素因数分解"""
    from math import sqrt
    from collections import Counter

    d = Counter()
    # 終点はルート切り捨て+1
    for i in range(2, int(sqrt(num)) + 1):
        # 素因数分解：小さい方から割れるだけ割って素数をカウント
        while num % i == 0:
            num //= i
            d[i] += 1
        # 1まで分解したら終了
        if num == 1:
            break
    # 最後に残ったnumは素数(ただし1^1は1^0なので数に入れない)
    if num != 1:
        d[num] += 1
    return d


class FactInvMOD:
    """階乗たくさん使う時用のテーブル準備"""

    def __init__(self, MAX, MOD):
        """MAX：階乗に使う数値の最大以上まで作る"""
        MAX += 1
        self.MAX = MAX
        self.MOD = MOD
        # 階乗テーブル
        factorial = [1] * MAX
        factorial[0] = factorial[1] = 1
        for i in range(2, MAX):
            factorial[i] = factorial[i - 1] * i % MOD
        # 階乗の逆元テーブル
        inverse = [1] * MAX
        # powに第三引数入れると冪乗のmod付計算を高速にやってくれる
        inverse[MAX - 1] = pow(factorial[MAX - 1], MOD - 2, MOD)
        for i in range(MAX - 2, 0, -1):
            # 最後から戻っていくこのループならMAX回powするより処理が速い
            inverse[i] = inverse[i + 1] * (i + 1) % MOD
        self.fact = factorial
        self.inv = inverse

    def nCr(self, n, r):
        """組み合わせの数 (必要な階乗と逆元のテーブルを事前に作っておく)"""
        if n < r:
            return 0
        # 10C7 = 10C3
        r = min(r, n - r)
        # 分子の計算
        numerator = self.fact[n]
        # 分母の計算
        denominator = self.inv[r] * self.inv[n - r] % self.MOD
        return numerator * denominator % self.MOD

    def nPr(self, n, r):
        """順列"""
        if n < r:
            return 0
        return self.fact[n] * self.inv[n - r] % self.MOD

    def nHr(self, n, r):
        """重複組み合わせ"""
        # r個選ぶところにN-1個の仕切りを入れる
        return self.nCr(r + n - 1, r)


N, M = MAP()
d = factorize(M)
# 例外処理
if not d:
    print((1))
    exit()
MAX = N + max(d.values())
fim = FactInvMOD(MAX, MOD)
ans = 1
for k, v in list(d.items()):
    ans *= fim.nHr(N, v)
    ans %= MOD
print(ans)

-""" -参考：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 +import sys + +def input(): +    return sys.stdin.readline().strip() + + +def list2d(a, b, c): +    return [[c] * b for i in range(a)] + + +def list3d(a, b, c, d): +    return [[[d] * c for j in range(b)] for i in range(a)] + + +def list4d(a, b, c, d, e): +    return [[[[e] * d for j in range(c)] for j in range(b)] for i in range(a)] + + +def ceil(x, y=1): +    return int(-(-x // y)) + + +def INT(): +    return int(eval(input())) + + +def MAP(): +    return list(map(int, input().split())) + + +def LIST(N=None): +    return list(MAP()) if N is None else [INT() for i in range(N)] + + +def Yes(): +    print("Yes") + + +def No(): +    print("No") + + +def YES(): +    print("YES") + + +def NO(): +    print("NO") + + +sys.setrecursionlimit(10**9) +INF = float("inf") -def fact_prime(num): -    d = defaultdict(int) +def factorize(num: int) -> dict: +    """素因数分解""" +    from math import sqrt +    from collections import Counter + +    d = Counter() -    end = int(sqrt(num)) + 1 -    for i in range(2, end + 1): -        cnt = 0 +    for i in range(2, int(sqrt(num)) + 1): -        # 1まで来たら終了 +        # 1まで分解したら終了 -    # 最後までそのまま来たやつはnumが素数(ただし1^1は1^0なので数に入れない) +    # 最後に残ったnumは素数(ただし1^1は1^0なので数に入れない) -# とりあえずv+N-1が収まればいいはず -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) -# powに第三引数入れると冪乗のmod付計算を高速にやってくれる -inverse[MAX - 1] = pow(factorial[MAX - 1], MOD - 2, MOD) -for i in range(MAX - 2, 0, -1): -    # 最後から戻っていくこのループならH+W回powするより処理が速い -    inverse[i] = inverse[i + 1] * (i + 1) % MOD -# 組み合わせの数 -def nCr(n, r): -    # 10C7 = 10C3 -    r = min(r, n - r) -    # 分子の計算 -    numerator = factorial[n] -    # 分母の計算 -    denominator = inverse[r] * inverse[n - r] % MOD -    return numerator * denominator % MOD +class FactInvMOD: +    """階乗たくさん使う時用のテーブル準備""" + +    def __init__(self, MAX, MOD): +        """MAX：階乗に使う数値の最大以上まで作る""" +        MAX += 1 +        self.MAX = MAX +        self.MOD = MOD +        # 階乗テーブル +        factorial = [1] * MAX +        factorial[0] = factorial[1] = 1 +        for i in range(2, MAX): +            factorial[i] = factorial[i - 1] * i % MOD +        # 階乗の逆元テーブル +        inverse = [1] * MAX +        # powに第三引数入れると冪乗のmod付計算を高速にやってくれる +        inverse[MAX - 1] = pow(factorial[MAX - 1], MOD - 2, MOD) +        for i in range(MAX - 2, 0, -1): +            # 最後から戻っていくこのループならMAX回powするより処理が速い +            inverse[i] = inverse[i + 1] * (i + 1) % MOD +        self.fact = factorial +        self.inv = inverse + +    def nCr(self, n, r): +        """組み合わせの数 (必要な階乗と逆元のテーブルを事前に作っておく)""" +        if n < r: +            return 0 +        # 10C7 = 10C3 +        r = min(r, n - r) +        # 分子の計算 +        numerator = self.fact[n] +        # 分母の計算 +        denominator = self.inv[r] * self.inv[n - r] % self.MOD +        return numerator * denominator % self.MOD + +    def nPr(self, n, r): +        """順列""" +        if n < r: +            return 0 +        return self.fact[n] * self.inv[n - r] % self.MOD + +    def nHr(self, n, r): +        """重複組み合わせ""" +        # r個選ぶところにN-1個の仕切りを入れる +        return self.nCr(r + n - 1, r) -N, M = list(map(int, input().split())) -# d = fact_prime(M) -# print(d) +N, M = MAP() +d = factorize(M) +# 例外処理 +if not d: +    print((1)) +    exit() +MAX = N + max(d.values()) +fim = FactInvMOD(MAX, MOD) -for k, v in list(fact_prime(M).items()): -    # 重複組み合わせ -    # v個のkとN-1個の仕切りから、v個を並べる(v+N-1個のマスからv個を選び出す組み合わせ) -    ans = (ans * nCr(v + N - 1, v)) % MOD +for k, v in list(d.items()): +    ans *= fim.nHr(N, v) +    ans %= MOD