#include <iostream>
#include <map>
#include <math.h>
#include <vector>
using namespace std;

const int MAX = 510000;
const int MOD = 1000000007;

long long fac[MAX], finv[MAX], inv[MAX];

// テーブルを作る前処理
void COMinit() {
    fac[0] = fac[1] = 1;
    finv[0] = finv[1] = 1;
    inv[1] = 1;
    for (int i = 2; i < MAX; i++){
        fac[i] = fac[i - 1] * i % MOD;
        inv[i] = MOD - inv[MOD%i] * (MOD / i) % MOD;
        finv[i] = finv[i - 1] * inv[i] % MOD;
    }
}

int main(){
    int N,M;
    cin >> N >> M;
    int r= 2;
    int count=0;//素因数の数
    map<long long  ,int  > insuu;
    vector<int > prime;
    COMinit();
    //因数分解部
    int pM=M;
    while(M>1){
        if(M%r!=0){//割り切れないなら次の因数を検索
            while(true){
                if(r==2){
                    r++;
                }else{
                    r+=2;
                }
                if(M%r==0){
                    break;
                }
                if(r>sqrt(pM)){
                    prime.push_back(M);
                    insuu[M]++;
                    M=1;
                    break;
                }
            }
        }else{
            M=M/r;
            if(insuu[r]<1){
                prime.push_back(r);
            }
            count++;
            insuu[r]++;
        }   
    }
    //出力計算部
    long long ans=1;
    for(auto v :prime){
        ans*=fac[N+insuu[v]-1]*((finv[insuu[v]])*finv[N-1]%MOD)%MOD;
        ans=ans%MOD;
    }
    cout << ans << endl;
    return 0;
}
#include <cstdio>
#include <algorithm>
#include <vector>
#include <set>
#include <cstdlib>
#include <utility>
#include <cmath>
#include <queue>
#include <stack>
#include <cstring>

using namespace std;

#define ll long long

#ifndef ONLINE_JUDGE
#define debug(format, ...) fprintf(stderr, \
    "%s:%d: " format "\n", __func__, __LINE__,##__VA_ARGS__)
#else
#define debug(format, ...)
#define NDEBUG
#endif

int n, m;

bool vis[1005][1005];
char s[1005];
int dist[1005][1005];

int dx[] = {1, 0, -1, 0};
int dy[] = {0, 1, 0, -1};

int main()
{
    scanf("%d%d", &n, &m);
    queue<pair<int, int> > bfs;
    for (int i = 1; i <= n; i++) {
        scanf("%s", s + 1);
        for (int j = 1; j <= m; j++) {
            if (s[j] == '#') {
                bfs.push(make_pair(i, j));
                vis[i][j] = true;
            }
        }
    }
    while (!bfs.empty()) {
        pair<int, int> cur = bfs.front();
        bfs.pop();
        for (int i = 0; i < 4; i++) {
            pair<int, int> newpos = make_pair(cur.first
                + dx[i], cur.second + dy[i]);
            if (newpos.first < 1 || newpos.first > n ||
                newpos.second < 1 || newpos.second > m) continue;
            if (vis[newpos.first][newpos.second]) continue;
            bfs.push(newpos);
            dist[newpos.first][newpos.second] =
                dist[cur.first][cur.second] + 1;
            vis[newpos.first][newpos.second] = true;
        }
    }
    int ans = 0;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            ans = max(ans, dist[i][j]);
        }
    }
    printf("%d", ans);
    return 0;
}
