using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;

class Program
{
    static int N, M;

    public static void Main(string[] args)
    {
        N = Input.NextInt();
        M = Input.NextInt();

        var primes = new Dictionary<int, int>();
        foreach (var lprime in PrimeNumber.EnumeratePrimeFactors(M))
        {
            var prime = (int)lprime;
            if (!primes.ContainsKey(prime))
            {
                primes[prime] = 0;
            }
            primes[prime]++;
        }

        int ans = 1;
        foreach (var n_prime in primes.Values)
        {
            var n_posibility = NumberOfCombination_SeparateBallsToBoxes(n_prime, N);
            ans = Modulo.Mul(ans, n_posibility);
        }

        Console.WriteLine(ans);
    }

    public static int NumberOfCombination_SeparateBallsToBoxes(int n_ball, int n_box)
    {
        return Modulo.Ncr(n_ball + n_box - 1, n_ball);
    }
}

public static class PrimeNumber
{
    static readonly long[] seedPrimes =
        {
            2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,
        };
    static readonly long[] seedPrimesSkip3Take8 = seedPrimes.Skip(3).Take(8).ToArray();

    /// <summary>
    /// Check prime number or not.
    /// </summary>
    /// <param name="num">Number to check.</param>
    /// <returns><see langword="true"/> if <paramref name="num"/> is prime number.</returns>
    public static bool IsPrime(long num)
    {
        if (num == 1)
            return false;
        if (seedPrimes.Contains(num))
            return true;
        if (seedPrimes.Any(x => num % x == 0))
            return false;

        long i = 0;
        while (true)
        {
            foreach (var p in seedPrimesSkip3Take8)
            {
                // 30m+2, 30m+3, 30m+4, 30m+5, 30m+6、30m+8、30m+9、30m+12... are not required to divide.
                var primeCandidte = p + i;
                if (primeCandidte > Math.Sqrt(num))
                    return true;
                if (num % (primeCandidte) == 0)
                    return false;
            }
            i += 30;
        }
    }

    /// <summary>
    /// Prime factorization.
    /// </summary>
    /// <param name="n">Number to factorize.</param>
    /// <returns><see cref="IEnumerable{T}"/> of prime numbers.</returns>
    public static IEnumerable<long> EnumeratePrimeFactors(long n)
    {
        while (n > 1)
        {
            long factor = GetFactor(n);
            yield return factor;
            n = n / factor;
        }
    }

    private static readonly int[] seeds357111317 = new int[] { 3, 5, 7, 11, 13, 17 };

    private static long Func(long xx, long nn, int sseed)
    {
        return (seeds357111317[sseed % 6] * xx + sseed) % nn;
    }

    private static long GetFactor(long n, int seed = 1)
    {
        if (n % 2 == 0)
            return 2;
        if (IsPrime(n))
            return n;
        long x = 2;
        long y = 2;
        long d = 1;
        long count = 0;
        while (d == 1)
        {
            count++;
            x = Func(x, n, seed);
            y = Func(Func(y, n, seed), n, seed);
            d = MathLib.Gcd(Math.Abs(x - y), n);
        }
        if (d == n)
            return GetFactor(n, seed + 1);
        return GetFactor(d);
    }
}

public class MathLib
{
    /// <summary>
    /// Calculate greatest common divisor.
    /// </summary>
    /// <param name="a"></param>
    /// <param name="b"></param>
    /// <returns>Greatest common divisor calculated.</returns>
    public static long Gcd(long a, long b)
    {
        return (a < b) ? Gcd(b, a)
             : (b > 0) ? Gcd(b, a % b)
                       : a;
    }

    /// <summary>
    /// Calculate least common multiple.
    /// </summary>
    /// <param name="a"></param>
    /// <param name="b"></param>
    /// <returns>Least common multiple calculated.</returns>
    public static long Lcm(long a, long b)
    {
        return a / Gcd(a, b) * b;
    }

    /// <summary>
    /// Enumerate divisors. The order is <b>not</b> sorted.
    /// </summary>
    /// <param name="n">Number to get divisors.</param>
    /// <returns><paramref name="n"/><see cref="IEnumerable{T}"/> of divisors.</returns>
    public static IEnumerable<int> GetDivisors(int n)
    {
        for (int i = 1; i < (int)Math.Sqrt(n) + 1; i++)
        {
            if ((n % i) == 0)
            {
                yield return i;
                if (i != n / i)
                {
                    yield return n / i;
                }
            }
        }
        yield break;
    }
}

public static class Modulo
{
    private const int M = 1000000007;
    private static readonly List<int> m_facs = new List<int>() { 1, };

    public static int Mul(int a, int b)
    {
        return (int)(Math.BigMul(a, b) % M);
    }

    public static int Fac(int n)
    {
        if (m_facs.Count <= n)
        {
            for (int i = m_facs.Count; i <= n; i++)
            {
                var facs_i = Mul(m_facs[i - 1], i);
                m_facs.Add(facs_i);
            }
        }
        return m_facs[n];
    }

    public static int Pow(int a, int m)
    {
        switch (m)
        {
            case 0:
                return 1;
            case 1:
                return a;
            default:
                int p1 = Pow(a, m / 2);
                int p2 = Mul(p1, p1);
                return ((m % 2) == 0) ? p2 : Mul(p2, a);
        }
    }

    public static int Div(int a, int b)
    {
        return Mul(a, Pow(b, M - 2));
    }

    public static int Ncr(int n, int r)
    {
        if (n < r) { return 0; }
        if (n == r) { return 1; }
        int res = Fac(n);
        res = Div(res, Fac(r));
        res = Div(res, Fac(n - r));
        return res;
    }

    public static int Plus(int a, int b)
    {
        a += b;
        a %= M;
        return a;
    }

    public static int Minus(int a, int b)
    {
        a -= b;
        if (a < 0)
            a += M;
        a %= M;
        return a;
    }
}

public static class Input
{
    private static Queue<string> q = new Queue<string>();
    private static void Confirm() { if (q.Count == 0) foreach (var s in Console.ReadLine().Split(' ')) q.Enqueue(s); }
    public static int NextInt() { Confirm(); return int.Parse(q.Dequeue()); }
    public static long NextLong() { Confirm(); return long.Parse(q.Dequeue()); }
    public static string NextString() { Confirm(); return q.Dequeue(); }
    public static double NextDouble() { Confirm(); return double.Parse(q.Dequeue()); }
    public static int[] LineInt() { return Console.ReadLine().Split(' ').Select(int.Parse).ToArray(); }
    public static long[] LineLong() { return Console.ReadLine().Split(' ').Select(long.Parse).ToArray(); }
    public static string[] LineString() { return Console.ReadLine().Split(' ').ToArray(); }
    public static double[] LineDouble() { return Console.ReadLine().Split(' ').Select(double.Parse).ToArray(); }
}


Measured memory_bytes: 14560