using System;
using System.Linq;//リストの使用
using System.Collections.Generic;
using System.Text;//テキストの高速出力に必要
class Program
{
static bool[] isPrimes = makePrimeList(100000);//i-1が素数かどうか
static long factMax = 200000;//nCkにおけるnの最大値
static long[] factorials = new long[factMax+1];//i!(mod p)を先にメモ
static long[] factorialRs = new long[factMax+1];//i!^-1(mod p), pは素数

	static void Main()
	{
		long p = 1000000007;
		string[] input = Console.ReadLine().Split(' ');
		long m = long.Parse(input[0]);
		int n = int.Parse(input[1]);
		long answer = 1;
    factorials[0] = 1;
		factorialRs[factMax] = DivideModFactorial(factMax,p);
		for(long i = 1; i <= factMax; i++)
		{
		factorials[i] = (factorials[i-1]*i)%p;//i!(mod p)
		factorialRs[factMax-i] = (factorialRs[factMax+1-i]*(factMax+1-i))%p;//逆元も先にメモ
		}

    List<long> factList = Factoring(n);
    int countMemo = 0;
    for(int i = 0; i < factList.Count(); i++)
    {
      if(i == 0) countMemo++;
      else if(factList[i] == factList[i-1]) countMemo++;
      else
      {
        answer *= factorials[countMemo+(m-1)];
        answer %= p;
        answer *= factorialRs[countMemo];
        answer %= p;
        answer *= factorialRs[m-1];
        answer %= p;
        countMemo = 1;
      }
    }

    if(countMemo > 0)
    {
      answer *= factorials[countMemo+(m-1)];
      answer %= p;
      answer *= factorialRs[countMemo];
      answer %= p;
      answer *= factorialRs[m-1];
      answer %= p;
    }

    //Console.WriteLine(answer+"a");
    long answerMulMemo = 0;
    if(n > 0)
    {
      for(int i = 0; i <= m; i+=2)
      {
        //Console.WriteLine(answer);
        answerMulMemo += Comb(m,i,p);
        answerMulMemo %= p;
      }
    }else
    {
      for(int i = 1; i <= m; i+=2)
      {
        answerMulMemo += Comb(m,i,p);
        answerMulMemo %= p;
      }
    }
    //answer *= answerMulMemo;
    answer %= p;

		Console.WriteLine(answer);
	}

  static List<long> Factoring(long originalNum)
  {//makePrimeListによるisPrimesを用いて、引数をO(√n)で素因数分解。リストには同じ数も含む。
  //例えば1は{},12は{2,2,3},17は{17}を返す。
    List<long> answers = new List<long>();
    for(long i = 2; i <= Math.Sqrt(originalNum); i++)
    {
      if(!isPrimes[i-1]) continue;//素数でないとき
      else
      {
        while(originalNum % i == 0)
        {
          originalNum /= i;
          answers.Add(i);
        }
      }
    }
    if(originalNum != 1) answers.Add(originalNum);
    return answers;
  }

  static bool[] makePrimeList(long maxPrime)
  {//「引数1以上」max以下の素数判定を、エラトステネスの篩を用いてO(n)。
    bool[] isPrimes = new bool[maxPrime];//素数リスト
    isPrimes[0] = false;//1は素数でないのでfalse
    for(long i = 1; i < maxPrime; i++) isPrimes[i] = true;//素数と仮定してtrue
    
    for(long i = 2; i <= Math.Sqrt(maxPrime); i++)
    {
      if(isPrimes[i-1])
      {
        for (long j = i*2; j <= maxPrime; j+=i)
        {
          isPrimes[j-1] = false;//素数でないのでfalse
        }
      }
    }

    return isPrimes;
  }

  static long MathPow(long x, long a)//戻り値はx^a。O(loga)
  {
    long num = 2;
    long answer = 1;
    long check = a;
    long memo = x;
  
    while(check > 0)
    {
      if(check % num == num / 2)
      {
        check -= num / 2;
        answer *= memo;
      }
    memo *= memo;
    num *= 2;
    }
    return answer;
  }

  static long DivideMod(long x, long a, long p)//戻り値はx^a(mod p)。O(loga)
  {
    long num = 2;
    long answer = 1;
    long check = a;
    long memo = x%p;
    
    while(check > 0)
    {
      if(check % num == num / 2)
      {
        check -= num / 2;
        answer *= memo;
        answer %= p;
      }
    memo *= memo;
    memo %= p;
    num *= 2;
    }
    return answer;
  }

  static long DivideModReverse(long x, long p)//戻り値はx^-1(mod p), pは素数。O(logp)
  {
    long answer = DivideMod(x, p-2, p);
    return answer;
  }

  static long ModFactorial(long x, long p)//戻り値はx!(mod p)
  {
    long answer = 1;
    for(int i = 2; i <= x; i++)
    {
      answer *= i;
      answer %= p;
    }
    return answer;
  }

  static long DivideModFactorial(long x, long p)//戻り値はx!^-1(mod p), pは素数
  {
    long answer = 1;
    for(long i = x; i >= 2; i--)
    {
      answer *= DivideModReverse(i, p);
      answer %= p;
    }
    return answer;
  }

  static long Comb(long a, long b, long p)//戻り値は組み合わせC(a,b)のmod p
  {
    if(a-b < 0) return 0;//引数a-bが負なら0を返す
    long answer = 1;
    answer *= factorials[a];
    answer %= p;
    answer *= factorialRs[a-b];
    answer %= p;
    answer *= factorialRs[b];
    answer %= p;
    return answer;
  }

  
}

Measured memory_bytes: 16468