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 C (GCC 5.4.1) (judge verdict: Time Limit Exceeded)

#include <stdio.h>
#include <stdlib.h>
#include <math.h>


#define LIMIT 1000000007

typedef enum {false, true} bool;


int main(void)
{
    int N, M;
    int i, j, k;
    int *factor;  // related to factor_ctr
    int factor_ctr;
    int *factor_num;  // related to factor_ctr
    bool **factor_matrix;  // factor_ctr x factor_ctr
    int ctr, ctr_bk;
    long long sum;
    //long long *iterative_array;  // related to factor_ctr
    long long **iterative_matrix;
    
    
    scanf("%d %d", &N, &M);
    
    /**/
    
    factor_ctr = 0;
    
    
    for(i=1; i<(int)sqrt(M); i++)
    {
        if(M%i == 0)
        {
            factor_ctr += 2;
        }
    }
    
    if(M%i == 0)
    {
        if(M == i*i)
            factor_ctr++;
        else
            factor_ctr += 2;
    }
    //printf("factor_ctr: %d\n", factor_ctr);
    
    
    factor = (int*)malloc(sizeof(int)*factor_ctr);
    factor_num = (int*)malloc(sizeof(int)*factor_ctr);
    
    factor_matrix = (bool**)malloc(sizeof(bool*)*factor_ctr);
    for(i=0; i<factor_ctr; i++)
        factor_matrix[i] = (bool*)malloc(sizeof(bool)*factor_ctr);
    
    
    for(i=0; i<factor_ctr; i++)
    {
        factor_num[i] = 0;
    }
    
    ctr = 0;
    ctr_bk = factor_ctr;
    
    for(i=1; i<(int)sqrt(M); i++)
    {
        if(M%i == 0)
        {
            factor[ctr++] = i;
            //printf("%d  ", i);
            factor[--ctr_bk] = M/i;
            //printf("%d\n", M/i);
        }
    }
    
    if(M%i == 0)
    {
        if(M == i*i)
        {
            factor[ctr] = i;
            //printf("%d\n", i);
        }
        else
        {
            factor[ctr] = i;
            //printf("%d  ", i);
            factor[--ctr_bk] = M/i;
            //printf("%d\n", M/i);
        }
    }
    //system("pause");
    
    /**/
    
    for(i=0; i<factor_ctr; i++)
    {
        for(j=0; j<=i; j++)
        {
            if(factor[i]%factor[j] == 0)
                factor_num[i]++;
        }
        //printf("factor_num[%d]: %d\n", i, factor_num[i]);
    }
    //system("pause");
    
    /**/
    
    for(i=0; i<factor_ctr; i++)
    {
        //printf("factor_matrix[%d][]:\n", i);
        
        for(j=0; j<factor_ctr; j++)
        {
            if(factor[j]%factor[i] == 0 && j>i)
                factor_matrix[i][j] = true;
            else
                factor_matrix[i][j] = false;
            
            //printf("%d ", factor_matrix[i][j]);
        }
        //printf("\n");
    }
    //system("pause");
    
    /**/
    
    //iterative_array = (long long*)malloc(sizeof(long long)*factor_ctr);
    iterative_matrix = (long long**)malloc(sizeof(long long*)*factor_ctr);
    
    
    for(i=0; i<factor_ctr; i++)
    {
        iterative_matrix[i] = (long long*)malloc(sizeof(long long)*N);
        
        iterative_matrix[i][0] = 0;
    }
    
    for(i=0; i<N; i++)
        iterative_matrix[factor_ctr-1][i] = 1;
    
    /*for(i=0; i<factor_ctr-1; i++)
    {
        iterative_array[i] = 0;
    }
    iterative_array[i] = 1;
    */
    
    if(N == 1)
        printf("1\n");
    else
    {
        /*for(i=2; i<N; i++)
        {
            for(j=0; j<factor_ctr-1; j++)
            {
                for(k=j+1; k<factor_ctr; k++)
                {
                    if(factor_matrix[j][k])
                        iterative_array[j] = (iterative_array[j]+iterative_array[k])%LIMIT;
                }
            }
        }
        */
        for(i=factor_ctr-2; i>=0; i--)
        {
            for(j=1; j<N-1; j++)
            {
                iterative_matrix[i][j] = iterative_matrix[i][j-1];
                
                for(k=i+1; k<factor_ctr; k++)
                {
                    if(factor_matrix[i][k])
                        iterative_matrix[i][j] = (iterative_matrix[i][j]+iterative_matrix[k][j-1])%LIMIT;
                }
            }
        }
        
        
        sum = 0;
        
        for(i=0; i<factor_ctr; i++)
        {
            /*sum = (sum+iterative_array[i]*factor_num[i])%LIMIT;
            //printf("iterative_array[%d]: %lld\n", i, iterative_array[i]);
            */
            sum = (sum+iterative_matrix[i][N-2]*factor_num[i])%LIMIT;
            //printf("iterative_matrix[%d][N-1]: %lld\n", i, iterative_matrix[i][N-2]);
        }
        
        printf("%lld\n", sum);
    }
    
    
    free(factor);
    free(factor_num);
    
    for(i=0; i<factor_ctr; i++)
        free(factor_matrix[i]);
    free(factor_matrix);
    
    //free(iterative_array);
    for(i=0; i<factor_ctr; i++)
        free(iterative_matrix[i]);
    free(iterative_matrix);
    
    
    //system("pause");
    
    return 0;
}