fun main(args: Array<String>) {
    val (n,m) = readLine()!!.split(" ").map { it.toInt() }
    if(m==1){ println(1); return }
    val p = primeFact(m).groupBy { it }.map { it.value.size }
    val (f,g) = mFactTable( n + p.max()!! )
    val ans = p.fold(1){acc, i ->
        acc.mMul(f[n-1+i]).mMul(g[i]).mMul(g[n-1])
    }
    println(ans)

}

fun primeFact(a:Int):List<Int>{
    if(a==1) return listOf(1)
    val primes= mutableListOf<Int>()
    var x=a
    val rtx=Math.sqrt(x.toDouble()).toInt()
    for(p in 2..a){
        if(p>rtx && primes.isEmpty()) return listOf(a)
        if(x==1) return primes
        while(x%p==0){
            primes.add(p)
            x/=p
        }
    }
    return primes
}

const val mod = 1000000007
fun Int.mAdd(a : Int) = if(this+a<mod) this+a else this+a-mod
fun Int.mSub(a : Int) = if(this-a>=0 ) this-a else this-a+mod
fun Int.mMul(a : Int) = (this*a.toLong()%mod).toInt()
fun Int.mInv() = this.mPow(mod-2)
fun Int.mPow(a : Int) :Int {
    var x=this; var y=a; var ret = 1
    while (y>0) {
        if(y.and(1)==1) ret=ret.mMul(x)
        x=x.mMul(x)
        y=y.shr(1)
    }
    return ret
}

fun mFactTable(n:Int) : Pair<IntArray,IntArray>{
    val fact1 = IntArray(n+1)
    val fact2 = IntArray(n+1)
    fact1[0] = 1
    for (i in 1..n) fact1[i] = fact1[i-1].mMul(i)
    for (i in 0..n) fact2[i] = fact1[i].mInv()
    return Pair(fact1,fact2)
}

