CodeEff/ECCO huggingface dataset:
# Original solution
N = int(eval(input()))
A = [int(a) for a in input().split()]
def fact(n):
    if n==0:
        return 1
    else:
        return n*fact(n-1) % p
    
def mod_combination(n, k, mod):
    # nCk (mod m)
    def mod_permutation(n, k, mod):
        if n<=k:
            return 1
        else:
            return (n * mod_permutation(n-1,k,mod))%mod

    def mod_inv_permutation(k, mod):
        k, mod = int(k), int(mod)
        if k<=1:
            return 1
        else:
            return (pow(k,mod-2,mod) * mod_inv_permutation(k-1, mod))%mod

    return (mod_permutation(n,n-k,mod) * mod_inv_permutation(k, mod))%mod

X = [[0,0],[0,1,0]]
p = 10**9 + 7
for i in range(2, N+1):
#    print ("i=",i)
    s = [0] * (i+2)
    for j in range(i):
        a = j + 1 - 1
        b = i - (j + 1)
#        print (i, j, a, b)
#        print ("Bef", s)
        for k in range(a):
#            print ("s[", k+1, "] +=", X[a][k+1]*mod_combination(a+b,a,p)*fact(b)+fact(i-1))
            s[k+1] += ((X[a][k+1]*mod_combination(a+b,a,p) % p)*fact(b) % p +fact(i-1)) % p
        for k in range(b):
#            print ("s[", i-k, "] +=", X[b][k+1]*mod_combination(a+b,a,p)*fact(a)+fact(i-1))
            s[i-k] += ((X[b][k+1]*mod_combination(a+b,a,p) % p) *fact(a) % p +fact(i-1)) % p
#        print ("s[", j+1, "] +=", fact(i-1))
        s[j+1] += fact(i-1)
#        print ("Aft", s)
    X.append(s)
#    print (X)

ans = 0
for i in range(N):
    ans += X[N][i+1] * A[i]
    ans %= p
print (ans)

# Optimized solution
def mod_inv(n,p):
    if n<0:
        return - mod_inv(-n,p) % p
    if n>p:
        return mod_inv(n % p, p)
    
    def mod_inv_calc(a,b):
        if b==0:
            return (a,1)
        else:
            s,t = mod_inv_calc(b, a % b)
            d = a//b
            return (t, -t*d+s)

    return mod_inv_calc(p,n)[1] % p

N = int(eval(input()))
A = [int(a) for a in input().split()]
p = 10**9+7
inv_list = [mod_inv(i+1,p) for i in range(N+2)]

fact_list = [1]
for i in range(N):
    fact_list.append(fact_list[i] * (i+1) % p)
s = 0
sum_list = [inv_list[i] * fact_list[N] % p for i in range(N+2)]

for i in range(N):
    s += inv_list[i]
    
s *= fact_list[N]
s %= p
ans = 0
for i in range(N):
    ans += A[i]*s
    ans %= p
    s += (sum_list[i+1] - sum_list[N-i-1])
    s %= p
    
print (ans)
# Original solution
N = int(eval(input()))
A = list(map(int,input().split(" ")))
mod = 10**9+7

fact = 1
for i in range(2,N+1):
    fact *= i
    fact %= mod

rev = [ pow((i),mod-2,mod) for i in range(1,N+1) ]
for i in range(N-1):
    rev[i+1] += rev[i]

ans = 0
for i in range(N):
    ans += A[i] * (fact * (rev[i] + rev[N-1-i] - rev[0])) % mod
    ans %= mod

print(ans)



# Optimized solution
N = int(eval(input()))
A = list(map(int,input().split(" ")))
mod = 10**9+7

fact = 1
for i in range(2,N+1):
    fact *= i
    fact %= mod

rev = [ (pow((i),mod-2,mod)*fact)%mod for i in range(1,N+1) ]
for i in range(N-1):
    rev[i+1] += rev[i]
    rev[i+1] %= mod

ans = 0
for i in range(N):
    ans += A[i] * (rev[i] + rev[N-1-i] - rev[0]) % mod
    ans %= mod

print(ans)
# Original solution
# -*- coding: utf-8 -*-
from sys import stdin
from itertools import accumulate

s_in = lambda: stdin.readline()[:-1] # s = s_in()
d_in = lambda: int(stdin.readline()) # N = d_in()
ds_in = lambda: list(map(int, stdin.readline().split())) # List = ds_in()

MOD = 10**9 + 7

N = d_in()
A_list = ds_in()

def factorial(N):
    val = 1
    for i in range(1, N+1):
        val = (val * i) % MOD
    return val

def recursive_square(n, m, p):
    """ n**p (mod m) """
    if p == 0:
        return 1 % m
    if p % 2 == 0:
        root = recursive_square(n, m, p//2) % m 
        return (root ** 2) % m
    else:
        return ((n % m) * recursive_square(n, m, p-1)) % m


N_factorial = factorial(N)

Coefs = []
for i in range(1, N+1):
    Coefs.append((N_factorial * recursive_square(i, MOD, MOD-2)) % MOD)

def CumSum(x):
    c = []
    last = 0
    for i in range(len(x)):
        last = (last + x[i]) % MOD
        c.append(last)
    return c
        
Cum_Coefs = CumSum(Coefs)

if N == 1:
    print((A_list[0]))
else: 
    ans = 0
    for i in range(N):
        ans = (ans + A_list[i] * (Cum_Coefs[i] + Cum_Coefs[N-i-1] - Cum_Coefs[0])) % MOD 
    print(ans)





# Optimized solution
# -*- coding: utf-8 -*-
from sys import stdin
from itertools import accumulate

s_in = lambda: stdin.readline()[:-1] # s = s_in()
d_in = lambda: int(stdin.readline()) # N = d_in()
ds_in = lambda: list(map(int, stdin.readline().split())) # List = ds_in()

MOD = 10**9 + 7

N = d_in()
A_list = ds_in()

def factorial(N):
    val = 1
    for i in range(1, N+1):
        val = (val * i) % MOD
    return val

def recursive_square(n, m, p):
    """ n**p (mod m) """
    if p == 0:
        return 1 % m
    if p % 2 == 0:
        root = recursive_square(n, m, p//2) % m 
        return (root ** 2) % m
    else:
        return ((n % m) * recursive_square(n, m, p-1)) % m
        
def factorize(n):
    if n == 1:
        return [(1, 1)]
    fct = []
    b, e = 2, 0
    while b * b <= n:
        while n % b == 0:
            n //= b
            e += 1
        if e > 0:
            fct.append((b, e))
        b, e = b + 1, 0
    if n > 1:
        fct.append((n, 1))
    return fct

N_factorial = factorial(N)

Coefs = []
lastval = 0
Inv = dict()
for i in range(1, N+1):
    fac = factorize(i)
    temp = N_factorial
    for f in fac:
        if f[0] not in list(Inv.keys()):
            Inv[f[0]] = recursive_square(f[0], MOD, MOD-2)
        for _ in range(f[1]):
            temp = (temp * Inv[f[0]]) % MOD
    lastval = (lastval + temp) % MOD
    Coefs.append(lastval)

if N == 1:
    print((A_list[0]))
else: 
    ans = 0
    for i in range(N):
        ans = (ans + A_list[i] * (Coefs[i] + Coefs[N-i-1] - Coefs[0])) % MOD 
    print(ans)
# Original solution
# -*- coding: utf-8 -*-
from sys import stdin
from itertools import accumulate

s_in = lambda: stdin.readline()[:-1] # s = s_in()
d_in = lambda: int(stdin.readline()) # N = d_in()
ds_in = lambda: list(map(int, stdin.readline().split())) # List = ds_in()

MOD = 10**9 + 7

N = d_in()
A_list = ds_in()

def factorial(N):
    val = 1
    for i in range(1, N+1):
        val = (val * i) % MOD
    return val

def recursive_square(n, m, p):
    """ n**p (mod m) """
    if p == 0:
        return 1 % m
    if p % 2 == 0:
        root = recursive_square(n, m, p//2) % m 
        return (root ** 2) % m
    else:
        return ((n % m) * recursive_square(n, m, p-1)) % m
        
def factorize(n):
    if n == 1:
        return [(1, 1)]
    fct = []
    b, e = 2, 0
    while b * b <= n:
        while n % b == 0:
            n //= b
            e += 1
        if e > 0:
            fct.append((b, e))
        b, e = b + 1, 0
    if n > 1:
        fct.append((n, 1))
    return fct

N_factorial = factorial(N)

Coefs = []
lastval = 0
Inv = dict()
for i in range(1, N+1):
    fac = factorize(i)
    temp = N_factorial
    for f in fac:
        if f[0] not in list(Inv.keys()):
            Inv[f[0]] = recursive_square(f[0], MOD, MOD-2)
        for _ in range(f[1]):
            temp = (temp * Inv[f[0]]) % MOD
    lastval = (lastval + temp) % MOD
    Coefs.append(lastval)

if N == 1:
    print((A_list[0]))
else: 
    ans = 0
    for i in range(N):
        ans = (ans + A_list[i] * (Coefs[i] + Coefs[N-i-1] - Coefs[0])) % MOD 
    print(ans)



# Optimized solution
# -*- coding: utf-8 -*-
from sys import stdin
from itertools import accumulate

s_in = lambda: stdin.readline()[:-1] # s = s_in()
d_in = lambda: int(stdin.readline()) # N = d_in()
ds_in = lambda: list(map(int, stdin.readline().split())) # List = ds_in()

MOD = 10**9 + 7

N = d_in()
A_list = ds_in()

def factorial(N):
    val = 1
    for i in range(1, N+1):
        val = (val * i) % MOD
    return val

N_factorial = factorial(N)

Coefs = []
lastval = 0
for i in range(1, N+1):
    temp = (N_factorial * pow(i, MOD-2, MOD)) % MOD
    lastval = (lastval + temp) % MOD
    Coefs.append(lastval)

if N == 1:
    print((A_list[0]))
else: 
    ans = 0
    for i in range(N):
        ans = (ans + A_list[i] * (Coefs[i] + Coefs[N-i-1] - Coefs[0])) % MOD 
    print(ans)
# Original solution
# Sum Difference
N, X, D = list(map(int, input().split()))
if D < 0:
    X, D = -X, -D
# D>=0 として一般性を失わない
if D == 0:
    Sets = set()
    for i in range(N+1):
        Sets.add(i*X)
    print((len(Sets)))
    exit()

# D>0
ans = 0
Sets = set()

#TLE O(N**3)
for j in range(N+1):
    for k in range((j-1)*j//2, (2*N-1-j)*j//2+1):
        Sets.add(X*j+D*k)
print((len(Sets)))

# Optimized solution
# Sum Difference
from collections import defaultdict
N, X, D = list(map(int, input().split()))
if D < 0:
    X, D = -X, -D

if D == 0:
    Sets = set()
    for i in range(N+1):
        Sets.add(i*X)
    print((len(Sets)))
    exit()

# D>0
ans = 0
Mode = defaultdict(list)
for i in range(N+1):
    L = (i*X+D*i*(i-1)//2-i*X % D)//D
    R = (i*X+D*i*(2*N-1-i)//2-i*X % D)//D
    Mode[i*X % D].append((L, 1))
    Mode[i*X % D].append((R+1, -1))
Data = []
for key in list(Mode.keys()):
    Mode[key].sort()
    cnt = 1
    sums = Mode[key][0][0]
    for num, which in Mode[key][1:]:
        Data.append((sums, num, cnt))
        cnt += which
        sums = num
ans = 0
for l, r, v in Data:
    if v > 0:
        ans += r-l
print(ans)
# Original solution
from collections import defaultdict
from math import factorial

MOD = 10 ** 9 + 7


def factorize(n):
    facts = defaultdict(int)
    while n % 2 == 0:
        n //= 2
        facts[2] += 1
    m = 3
    while m * m <= n:
        while n % m == 0:
            facts[m] += 1
            n //= m
        m += 2
    if 1 < n:
        facts[n] += 1
    return facts


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


N, M = list(map(int, input().split()))
factors = factorize(M)
ans = 1
for p, e in list(factors.items()):
    ans = ans * nCr(N - 1 + e, e) % MOD
print(ans)

# Optimized solution
from collections import defaultdict


def factorize(n):
    facts = defaultdict(int)
    while n % 2 == 0:
        n //= 2
        facts[2] += 1
    m = 3
    while m * m <= n:
        while n % m == 0:
            facts[m] += 1
            n //= m
        m += 2
    if 1 < n:
        facts[n] += 1
    return facts


MOD = 10 ** 9 + 7  # should be a prime number
MAX = 10 ** 5 + 100
FACTS = [1] * (MAX + 1)
for i in range(1, MAX + 1):
    FACTS[i] = FACTS[i - 1] * i % MOD
FACTINVS = [1] * (MAX + 1)
INVS = [1] * (MAX + 1)
for i in range(2, MAX + 1):
    q, r = divmod(MOD, i)
    INVS[i] = -INVS[r] * q % MOD
    FACTINVS[i] = FACTINVS[i - 1] * INVS[i] % MOD


def nCr(n, r):
    return FACTS[n] * FACTINVS[r] * FACTINVS[n - r]


N, M = list(map(int, input().split()))
factors = factorize(M)
ans = 1
for p, e in list(factors.items()):
    ans = ans * nCr(N - 1 + e, e) % MOD
print(ans)
# Original solution
import math

def getPrimeFactorsDict(num):
  pn = 2 #素数は2から
  pfdict = {} #素因数のリスト
  while pn * pn <= num: #√numまで調べる
    while num % pn == 0: #現在の素数で割り切れる範囲でループ
      num = num / pn
      pfdict[pn] = pfdict.get(pn, 0) + 1
    pn += 1 #割り切れなくなったら次の素数へ
  if num > 1:
    pfdict[int(num)] = pfdict.get(int(num), 0) + 1
    
  return pfdict


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

d = getPrimeFactorsDict(M)

ans = 1
for key in list(d.keys()):

  if d[key] == 1:
    ans *= N
  else:
    ans *= math.factorial(N+d[key]-1) // (math.factorial(N-1) *  math.factorial(d[key]))

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

# Optimized solution
from collections import defaultdict

N,M = list(map(int, input().split()))
MOD = 10**9+7
# 素因数分解
d = defaultdict(int)
i = 2
while i*i <= M:
    if M % i == 0:
        d[i] += 1
        M //= i
    else:
        i += 1
if M > 1:
    d[M] += 1

# 素因数をN個に分配する方法
def nCr(n,r):
    if n < 0 or r < 0 or n < r: return 0
    if n - r < r: r = n - r
    if r == 0: return 1
    if r == 1: return n
    
    # 分子のn*(n-1)*...がr個分続くやつ
    numerator = [n-r+k+1 for k in range(r)]
    # 分母：r!=r*(r-1)*...*3*2の要素
    denominator = [k+1 for k in range(r)]
    
    # 分母の要素で割れる部分を割っていく部分
    for p in range(2, r+1):
        # 分母は1,2,3,...rのようになっており、1は意味がないのでスキップした形か
        pivot = denominator[p-1]
        if pivot > 1:
        # 分子のX番目と分母のX-offset番目が共通の約数を持つということだと思う。piv分ずれているのだから、pivの倍数というところか
            offset = (n-r) % p
            for k in range(p-1, r, p):
                # 約分できる要素について割る
                numerator[k - offset]  /= pivot
                denominator[k] /= pivot
            
    ret = 1
    for k in range(r):
        if numerator[k] > 1: ret *= int(numerator[k])
        
    return ret
"""
それぞれの素数についてどの用意分配するか考える
例：2が5個あり、3箇所に分ける（２を受け取らない場所があってもよい）とは
並んでいる５つの２の間にしきりを二つ入れる、のと同じ
なので、5つの２と２つの仕切りの重複順列といえる。
上の例は3H5と表せて、
nHr = (n+r-1)Crとなる
"""
ans = 1
for k in list(d.keys()):
    ans *= nCr((N+d[k]-1), d[k])
    ans %= MOD

print(ans)
# Original solution
num = (10 ** 9) + 7

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

prime_upper = int(m ** (1/2) + 10)
prime_dict = {}

check = [False] * prime_upper
prime = [2]

while m % 2 == 0:
    m //= 2
    if not 2 in list(prime_dict.keys()):
        prime_dict[2] = 0
    prime_dict[2] += 1

for j in range(2, prime_upper, 2):
    check[j] = True

for i in range(3, prime_upper, 2):
    if not check[i]:
        prime.append(i)
        while m % i == 0:
            m //= i
            if not i in list(prime_dict.keys()):
                prime_dict[i] = 0
            prime_dict[i] += 1

        for j in range(i, prime_upper, i):
            check[j] = True

com2 = [[0] * 50 for _ in range(n + 1)]
for i in range(1, n + 1):
    for j in range(1, 50):
        if i == 1:
            com2[i][j] = 1
        elif j == 1:
            com2[i][j] = i
        else:
            com2[i][j] = (com2[i][j - 1] + com2[i - 1][j]) % num
if m != 1:
    ans = n
else:
    ans = 1
for key, value in list(prime_dict.items()):
    ans = (ans * com2[n][value]) % num

print(ans)

# Optimized solution
num = (10 ** 9) + 7

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

if m == 1:
    print((1))
    exit()

prime_upper = int(m ** (1/2) + 50)
prime_dict = {}

check = [False] * prime_upper
prime = [2]

while m % 2 == 0:
    m //= 2
    if not 2 in list(prime_dict.keys()):
        prime_dict[2] = 0
    prime_dict[2] += 1

for j in range(2, prime_upper, 2):
    check[j] = True

for i in range(3, prime_upper, 2):
    if not check[i]:
        prime.append(i)
        while m % i == 0:
            m //= i
            if not i in list(prime_dict.keys()):
                prime_dict[i] = 0
            prime_dict[i] += 1

        for j in range(i, prime_upper, i):
            check[j] = True

if len(list(prime_dict.values())) != 0:
    value_max = max(prime_dict.values())
    com2 = [[0] * (value_max + 1) for _ in range(n + 1)]
    for i in range(1, n + 1):
        for j in range(1, value_max + 1):
            if i == 1:
                com2[i][j] = 1
            elif j == 1:
                com2[i][j] = i
            else:
                com2[i][j] = (com2[i][j - 1] + com2[i - 1][j]) % num
    if m != 1:
        ans = n
    else:
        ans = 1
    for key, value in list(prime_dict.items()):
        ans = (ans * com2[n][value]) % num
    print(ans)
else:
    print(n)
# Original solution
import collections
import math
n, m = [int(item) for item in input().split()]

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[int(n)] += 1
 
    return prime_count

cnt = trial_division_sqrt(m)

ans = 1
for item in cnt:
  ans *= int(math.factorial(n + cnt[item] - 1) // int(math.factorial(cnt[item]) * math.factorial(n-1)))
  ans = int(ans) % (1000000000 + 7)
print(ans)

# Optimized solution
import collections
import math
n, m = [int(item) for item in input().split()]

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[int(n)] += 1
    return prime_count

cnt = trial_division_sqrt(m)

ans = 1
for item in cnt:
  h = 1
  k_fact = 1
  for i in range(cnt[item]):
    h *= n + cnt[item] - 1 - i
    k_fact *= (i+1)
  ans *= h
  ans = ans // k_fact
  ans = ans % (1000000000 + 7)
print(ans)
# Original solution
from collections import Counter
def cmb(n, r, mod):
    if ( r<0 or r>n ):
        return 0
    r = min(r, n-r)
    return g1[n] * g2[r] * g2[n-r] % mod

mod = 10**9+7 #出力の制限
N = 10**5+1000
g1 = [1, 1] # 元テーブル
g2 = [1, 1] #逆元テーブル
inverse = [0, 1] #逆元テーブル計算用テーブル

for i in range( 2, N + 1 ):
    g1.append( ( g1[-1] * i ) % mod )
    inverse.append( ( -inverse[mod % i] * (mod//i) ) % mod )
    g2.append( (g2[-1] * inverse[-1]) % mod )

n,m=list(map(int, input().split()))
mb=[]
while m>1:
    for i in range(2,m+1):
        if m%i==0:
            mb.append(i)
            m//=i
            break

mb2=Counter(mb)
    
mblist=list()
for i in mb2:
    a = cmb(mb2[i]+n-1,mb2[i],mod)
    mblist.append(a)
ans=1
for i in mblist:
    ans=(ans*i)%mod
print(ans)

# Optimized solution
from collections import Counter
def cmb(n, r, mod):
    if ( r<0 or r>n ):
        return 0
    r = min(r, n-r)
    return g1[n] * g2[r] * g2[n-r] % mod

mod = 10**9+7 #出力の制限
N = 10**5+1000
g1 = [1, 1] # 元テーブル
g2 = [1, 1] #逆元テーブル
inverse = [0, 1] #逆元テーブル計算用テーブル

for i in range( 2, N + 1 ):
    g1.append( ( g1[-1] * i ) % mod )
    inverse.append( ( -inverse[mod % i] * (mod//i) ) % mod )
    g2.append( (g2[-1] * inverse[-1]) % mod )

n,m=list(map(int, input().split()))
mb=[]
while m>1:
    for i in range(2,int(m**0.5)+1):
        if m%i==0:
            mb.append(i)
            m//=i
            break
    else:
        mb.append(m)
        m//=m
mb2=Counter(mb)
    
mblist=list()
for i in mb2:
    a = cmb(mb2[i]+n-1,mb2[i],mod)
    mblist.append(a)
ans=1
for i in mblist:
    ans=(ans*i)%mod
print(ans)
# Original solution
from math import sqrt, ceil, factorial
from collections import defaultdict


def prime_factors(n):
    i = 2
    factors = defaultdict(int)
    while i * i <= n:
        if n % i:
            i += 1
        else:
            n //= i
            factors[i] += 1
    if n > 1:
        factors[n] += 1
    return factors


N, M = [int(elem) for elem in input().split(' ')]

# 素因数分解
prime_numbers = prime_factors(M)
sum = 1
fac_N_m1 = factorial(N - 1)

for value in list(prime_numbers.values()):
    bunshi = 1
    saisho = value + N - 1
    for _ in range(value):
        bunshi *= saisho
        saisho -= 1
    sum *= (bunshi // factorial(value))
print((sum % (10**9 + 7)))


# Optimized solution
from collections import defaultdict


def prime_factorize(num):
    prime_numbers = defaultdict(int)
    i = 2
    while i * i <= num:
        if num % i == 0:
            while num % i == 0:
                prime_numbers[i] += 1
                num //= i
        i += 1
    if num != 1:
        prime_numbers[num] += 1
    return prime_numbers


MOD = 10**9 + 7
N, M = [int(elem) for elem in input().split()]

prime_numbers = prime_factorize(M)

num_sequences = 1
for exponent in list(prime_numbers.values()):
    denomimator = 1
    numerator = 1
    for i in range(1, exponent + 1):
        denomimator *= (N + exponent - i)
        numerator *= i
    num_sequences *= denomimator // numerator
    num_sequences %= MOD

print(num_sequences)
# Original solution
import sys

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

factor = {}
tmp = 2
while(M // tmp >= 1):
    if(M % tmp != 0):
        if(tmp == 2):
            tmp += 1
        else:
            tmp += 2
        continue

    M = M // tmp
    factor[tmp] = factor.get(tmp, 0) + 1

if(factor == {}):
    print((1))
    sys.exit()

ans = 1
max_a = 7 + 10 ** 9
max_value = max(list(factor.values()))
aho = {0: 1}
fact = {0: 1}
abc = {}
for i in range(1, max_value + 1):
    # print(i)
    aho[i] = ((aho[i - 1] * (i + N - 1)))
    fact[i] = (fact[i - 1] * i)
    abc[i] = (aho[i] // fact[i]) % max_a


# print(factor)
# print(aho, fact)
for i in list(factor.values()):
    # print(i)
    ans = (ans * abc[i]) % max_a
print(ans)

# Optimized solution
import sys

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

factor = {}
tmp = 2
while(M // tmp >= 1):
    if(M % tmp != 0):
        if(tmp == 2):
            tmp += 1
        elif(M // tmp < tmp):
            tmp = M
        else:
            tmp += 2
        continue

    M = M // tmp
    factor[tmp] = factor.get(tmp, 0) + 1

if(factor == {}):
    print((1))
    sys.exit()

ans = 1
max_a = 7 + 10 ** 9
max_value = max(list(factor.values()))
aho = {0: 1}
fact = {0: 1}
abc = {}
for i in range(1, max_value + 1):
    # print(i)
    aho[i] = ((aho[i - 1] * (i + N - 1)))
    fact[i] = (fact[i - 1] * i)
    abc[i] = (aho[i] // fact[i]) % max_a


# print(factor)
# print(aho, fact)
for i in list(factor.values()):
    # print(i)
    ans = (ans * abc[i]) % max_a
print(ans)
# Original solution
M = 10 ** 9 + 7

def main():
    n, m = [int(s) for s in input().split()]

    print((solve(m, n)))

def solve(m, n):

    fs = list(factors(m))
    table = dict()
    table[1] = dict()

    for f in fs:
        table[1][f] = 1

    h = 1
    for _ in range(1, n.bit_length()):
        row = dict()
        for f in fs:
            for g in fs:
                if f * g > m:
                    break
                row[f * g] = (row.get(f * g, 0) + table[h][f] * table[h][g]) % M
        table[h * 2] = row
        h *= 2

    prev = { 1: 1 }
    result = None
    h = 1
    for _ in range(n.bit_length()):
        if n & h:
            result = dict()
            for f in list(prev.keys()):
                for g in list(table[h].keys()):
                    if f * g <= m:
                        result[f * g] = (result.get(f * g, 0) + prev[f] * table[h][g]) % M
            prev = result
        h *= 2
    return result[m]

def factors(n):
    import itertools

    tail = []
    for i in itertools.count(1):
        if i * i > n:
            break

        m, r = divmod(n, i)
        if r == 0:
            yield i
            if m != i:
                tail.append(m)
    
    for i in tail[::-1]:
        yield i

main()


# Optimized solution
import sys

MOD = 10 ** 9 + 7

def main():
    n, m = [int(s) for s in input().split()]
    print((solve(m, n)))

def solve(m, n):
    factors = list(get_prime_factors(m))
    h = max((c for f, c in factors), default=0)

    table = dict()
    table[1] = [1 for _ in range(h + 1)]

    i = 1
    while i < n:
        j = n & (i - 1)
        table[i * 2] = [0 for _ in range(h + 1)]
        if n & i != 0 and j != 0:
            table[i + j] = [0 for _ in range(h + 1)]
        for x in range(h + 1):
            for y in range(h + 1 - x):
                table[i * 2][x + y] = (table[i * 2][x + y] + table[i][x] * table[i][y]) % MOD
                if n & i != 0 and j != 0:
                    table[i + j][x + y] = (table[i + j][x + y] + table[i][x] * table[j][y]) % MOD

        if n & i == 0:
            del table[i]
        if n & i != 0 and j != 0:
            del table[i]
            del table[j]

        i *= 2

    ans = 1
    for f, c in factors:
        ans = ans * table[n][c] % MOD
    return ans

def get_prime_factors(n):
    import itertools

    m = n
    for i in itertools.count(2):
        if i * i > m:
            break

        c = 0
        while True:
            x, y = divmod(m, i)
            if y != 0:
                break
            c += 1
            m = x
        if c != 0:
            yield i, c

    if m != 1:
        yield m, 1


main()