#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <string>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <iomanip>
#include <utility>
#include <tuple>
#include <functional>
#include <bitset>
#include <cassert>
#include <complex>
#include <stdio.h>
#include <time.h>
#include <numeric>
#include <random>
#include <unordered_set>
#include <unordered_map>
#define all(a) a.begin(), a.end()
#define rep(i, n) for (ll i = 0; i < (n); i++)
#define rrep(i, n) for (ll i = (n) - 1; i >= 0; i--)
#define range(i, a, b) for (ll i = (a); i < (b); i++)
#define rrange(i, a, b) for (ll i = (b) - 1; i >= (a); i--)
#define pb push_back
#define debug(x) cerr << __LINE__ << ' ' << #x << ':' << (x) << '\n'
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<ll, ll> P;
typedef complex<ld> com;
template<class T> using pri_s = priority_queue<T, vector<T>, greater<T>>;
template<class T> using pri_b = priority_queue<T>;
constexpr int inf = 1000000010;
constexpr ll INF = 1000000000000000010;
constexpr int mod1e9 = 1000000007;
constexpr int mod998 = 998244353;
constexpr ld eps = 1e-12;
constexpr ld pi = 3.141592653589793238;
constexpr ll ten(int n) { return n ? 10 * ten(n - 1) : 1; };
int dx[] = { 1,0,-1,0,1,1,-1,-1 }; int dy[] = { 0,1,0,-1,1,-1,1,-1 };
void fail() { cout << "-1\n"; exit(0); } void no() { cout << "No\n"; exit(0); }
template<class T> void er(T a) { cout << a << '\n'; exit(0); }
template<class T, class U> inline bool chmax(T &a, const U &b) { if (a < b) { a = b; return true; } return false; }
template<class T, class U> inline bool chmin(T &a, const U &b) { if (a > b) { a = b; return true; } return false; }
template<class T> istream &operator >> (istream &s, vector<T> &v) { for (auto &e : v) s >> e; return s; }
template<class T> ostream &operator << (ostream &s, const vector<T> &v) { for (auto &e : v) s << e << ' '; return s; }
template<class T, class U> ostream &operator << (ostream &s, const pair<T, U> &p) { s << p.first << ' ' << p.second; return s; }

struct fastio {
	fastio() {
		cin.tie(0); cout.tie(0);
		ios::sync_with_stdio(false);
		cout << fixed << setprecision(20);
		cerr << fixed << setprecision(20);
	}
}fastio_;

class unionfind {
	vector<int> par;
	vector<int> sz;
public:
	unionfind(int n) {
		par = vector<int>(n);
		for (int i = 0; i < n; i++) par[i] = i;
		sz = vector<int>(n, 1);
	}
	int find(int x) {
		if (par[x] == x) return x;
		else return par[x] = find(par[x]);
	}
	int size(int x) { return sz[find(x)]; }
	bool same(int x, int y) { return find(x) == find(y); }
	void unite(int x, int y) {
		x = find(x);
		y = find(y);
		if (x == y) return;
		if (sz[x] < sz[y]) {
			par[x] = y;
			sz[y] += sz[x];
		}
		else {
			par[y] = x;
			sz[x] += sz[y];
		}
	}
};

int main() {
	int h, w;
	cin >> h >> w;
	vector<vector<char>> a(h, vector<char>(w));
	rep(i, h) rep(j, w) cin >> a[i][j];
	unionfind uni(h + w);
	uni.unite(0, h);
	uni.unite(0, h + w - 1);
	uni.unite(h - 1, h);
	uni.unite(h - 1, h + w - 1);
	rep(i, h) rep(j, w) if (a[i][j] == '#') uni.unite(i, h + j);
	set<int> x, y;
	rep(i, h) x.insert(uni.find(i));
	for (int i = h; i < h + w; i++) y.insert(uni.find(i));
	int ans = min(x.size(), y.size());
	cout << ans - 1 << '\n';
}
#include <bits/stdc++.h>
#define ll long long
#define fi first
#define se second
#define pb push_back
#define me memset
#define rep(a,b,c) for(int a=b;a<=c;++a)
#define per(a,b,c) for(int a=b;a>=c;--a)
const int N = 1e6 + 10;
const int mod = 998244353;
const int INF = 0x3f3f3f3f;
using namespace std;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b) {return a/gcd(a,b)*b;}

ll f[N],invf[N];
ll fpow(ll a,ll k){
	ll res=1;
	while(k){
		if(k&1) res=(res*a)%mod;
		k>>=1;
		a=a*a%mod;
		//cout<<1<<endl;
	}
	return res;
}
 
void init(int n){
	f[0]=1;
	for(int i=1;i<=n;++i){
		f[i]=f[i-1]*i%mod;
	}
	invf[n]=fpow(f[n],mod-2);
	for(int i=n-1;i>=0;--i){
		invf[i]=invf[i+1]*(i+1)%mod;
	}
}
 
ll C(int n,int k){
	if(k<0 || k>n) return 0;
	return f[n]*invf[k]%mod*invf[n-k]%mod;
}
 
ll dp[25][N];
 
int main(){
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    init(2e5+10);
    int n,m;
    cin>>n>>m;

    rep(i,1,m) dp[1][i]=1;

    rep(i,1,19){
        rep(j,1,m){
            for(int k=2;k*j<=m;++k){
                dp[i+1][k*j]+=dp[i][j];
            }
        }
    }

    ll ans=0;
    rep(i,1,19){
        rep(j,1,m){
            ans=(ans+C(n-1,i-1)*dp[i][j]%mod)%mod;
        }
    }

    cout<<ans<<'\n';
 
return 0;
}