#include <bits/stdc++.h>
using namespace std;
int main(void)
{
	int a, b;
	cin >> a >> b;
	int maxv = max(a, b);
	int minv = min(a, b);
	int c = minv - 1;
	int d = maxv - c;

	int count = 0;
	bool da[100][100];
	fill(da[0], da[0]+100*100, false);
	for (int i = 0; i < 25; i++) {
		for (int j = 0; j < 25; j++) {
			if (!(count < c))
				goto end;
			int ox = j*4;
			int oy = i*4;
			da[oy+0][ox+0] = true;
			da[oy+0][ox+1] = true;
			da[oy+0][ox+2] = true;
			da[oy+1][ox+0] = true;
			da[oy+1][ox+2] = true;
			da[oy+2][ox+0] = true;
			da[oy+2][ox+1] = true;
			da[oy+2][ox+2] = true;
			count++;
		}
	}
end:

	count = 0;
	for (int i = 0; i < 10; i++) {
		for (int j = 0; j < 50; j++) {
			if (!(count < d))
				goto end2;
			int oy = 80+i*2;
			int ox = j*2;
			da[oy][ox] = true;
			count++;
		}
	}
end2:

  
  	printf("100 100\n");
	for (int y = 0; y < 100; y++) {
		for (int x = 0; x < 100; x++) {
			if (minv == maxv) {
				if (da[y][x])
					putchar('#');
				else
					putchar('.');
			} else {
				if (maxv == b) {
					if (da[y][x])
						putchar('#');
					else
						putchar('.');
				} else {
					if (da[y][x])
						putchar('.');
					else
						putchar('#');
				}
			}
		}
		cout << endl;
	}

	return 0;
}
#include <bits/stdc++.h>
using namespace std;

// 型定義
typedef long long ll;
typedef pair<ll, ll> P;

// forループ
#define REP(i,n) for(ll i=0; i<(ll)(n); ++i)

// 定数宣言
const int INF = 1e9;
const int MOD = 1e9+7;
const ll LINF = 1e18;

// グラフ表現
using Graph = vector<vector<int>>;

// グラフの辺表現
using Edge = map<pair<int,int>,int>;

// n次元配列の初期化。第２引数の型のサイズごとに初期化していく。
template<typename A, size_t N, typename T>
void Fill(A (&array)[N], const T &val){
    std::fill( (T*)array, (T*)(array+N), val );
}

// 最大公約数
ll gcd(ll a,ll b){
   if (a%b == 0) return(b);
   else return(gcd(b, a%b));
}

// 最小公倍数
ll lcm(ll a, ll b){
    return a*b/gcd(a, b);
}

const int MAX = 1000000;
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;
    }
}

// 二項係数計算
long long COM(int n, int k){
    if (n < k) return 0;
    if (n < 0 || k < 0) return 0;
    return fac[n] * (finv[k] * finv[n - k] % MOD) % MOD;
}

map<ll, ll> prime_factor(ll n) {
  map<ll, ll> ret;
  for(ll i = 2; i * i <= n; i++) {
    while(n % i == 0) {
      ret[i]++;
      n /= i;
    }
  }
  if(n != 1) ret[n] = 1;
  return ret;
}

int main()
{
    cout << fixed << setprecision(15);
    ll N, M;
    cin >> N >> M;

    // for(auto p : prime_factor(N)) {
    //     while(p.second--) cout << " " << p.first;
    // }
    // cout << endl;

    map<ll, ll> PR;
    PR = prime_factor(M);

    // 前処理
    COMinit();

    ll ans = 1;
    for(auto p:PR){
        // cout << p.second << endl;
        ans = (ans * COM(p.second + N - 1, p.second)) % MOD;
        ans = ans % MOD;
    }
    cout << ans << endl;
    return 0;
}