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 in PyPy3 (2.4.0) (judge verdict: Wrong Answer)

import sys
stdin = sys.stdin

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 bisect import bisect_right

# nの逆元のリスト
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
       
# nの階乗のリスト
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

# nの階乗の逆元のリスト
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
        

from collections import Counter

n,m = li()

MOD = 10**9+7

# 二項係数の準備
inv = inv_mod(n,MOD)
fac = fact(n,MOD)
facInv = fact_inv(n,inv,MOD)


# Mの素因数リストを作る

def cd(n:int):
    m = 2
    cds = set([n])
    while m*m <= n:
        if n%m == 0:
            cds.add(m)
            cds.add(n//m)
            
        m += 1

    return sorted(list(cds))
    
cds = cd(m)

memo = []

def dfs(m: int, cds: list, res:int,st:list):
    if res == 1:
        memo.append(st)
        
    else:
        idx = bisect_right(cds,st[-1])
        for cdi in cds[:idx]:
            if cdi > st[-1]:
                pass
            else:
                if res%cdi == 0:
                    dfs(m,cds,res//cdi,st+[cdi])
                

# 辞書順にmを作れるオリジナルなセットを作る
for cdi in cds:
    dfs(m,cds,m//cdi,[cdi])

print(len(memo))

ans = 0
for memoi in memo:
    cnt = Counter(memoi)
    cnt_v = list(cnt.values())
    temp = fac[n]
    if len(memoi) <= n:
        for cnt_vi in cnt_v:
            if cnt_vi > 1:
                temp = (temp*facInv[cnt_vi]) % MOD
        temp = (temp*facInv[n-len(memoi)]) % MOD
    
    ans = (ans+temp) % MOD
        
if m==1 or n==1:
    print(1)
else:
    print(ans%MOD)