#include <bits/stdc++.h>
using namespace std;
/* nichijou */
template<class T,class U>
bool cmax(T & a, const U & b) {return a < b ? a = b, 1 : 0;}
template<class T,class U>
bool cmin(T & a, const U & b) {return b < a ? a = b, 1 : 0;}
/* data type */
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
#define F first
#define S second
/* STL container */
typedef vector<int> vi;
typedef vector<ll> vll;
#define SZ(a) ((int)(a).size())
#define ALL(a) begin(a), end(a)
#define CLR(a) (a).clear()
#define BK(a) ((a).back())
#define FT(a) ((a).front())
#define DB(a) (a).pop_back()
#define DF(a) (a).pop_front()
#define PB push_back
#define EB emplace_back
/* I gave you my heart and then you turned around. */
void _BG(const char * s) {cerr<<s<<endl;}
template<class T, class ... TT>
void _BG(const char * s,T a, TT...b)
{
    for (size_t c = 0; *s && (c || *s != ','); cerr << *s++)
        c += count(ALL("([{"),*s) - count(ALL(")]}"),*s);
    cerr << " = " << a;
    if (*s) {
        cerr << ", ";
        ++s;
    }
    _BG(s,b...);
}
#ifdef PR3PONY
#define BG(...) do { \
    cerr << __PRETTY_FUNCTION__ << ':' << __LINE__ << ": "; \
    _BG(#__VA_ARGS__,__VA_ARGS__); \
} while(0)
#else
#define BG(...)
#endif
/* Good Luck && Have Fun ! */
struct SCC {
  int n, num_;
  vector< vector< int > > G, rG;
  vector< int > ord, num;
  vector< bool > vis;
  void dfs( int u ) {
    if ( vis[ u ] ) return;
    vis[ u ] = 1;
    for ( int v : G[ u ] ) dfs( v );
    ord.push_back( u );
  }
  void rdfs( int u ) {
    if ( vis[ u ] ) return;
    num[ u ] = num_;
    vis[ u ] = 1;
    for ( int v : rG[ u ] ) rdfs(v);
  }
  inline void init( int n_ ) {
    n = n_, num_ = 0;
    G.clear(); G.resize( n );
    rG.clear(); rG.resize( n );
    vis.clear(); vis.resize( n );
    num.resize( n );
  }
  inline void add_edge( int st, int ed ) {
    G[ st ].push_back( ed );
    rG[ ed ].push_back( st );
  }
  void solve() {
    fill( vis.begin(), vis.end(), 0 );
    for ( int i = 0 ; i < n ; ++ i )
      if ( not vis[ i ] ) dfs( i );
    reverse( ord.begin(), ord.end() );
    fill( vis.begin(), vis.end(), 0 );
    for ( int i : ord ) {
      if( not vis[ i ] ) {
        rdfs( i ); num_++;
      }
    }
  }
  inline int get_id( int x ) { return num[ x ]; }
  inline int count() { return num_; }
} scc;
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    int n, m;
    cin >> n >> m;
    vector<string> g(n);
    vector<vector<int>> idx(n, vector<int>(m, -1));
    int tot = 0;
    for (int i = 0; i < n; ++i) {
        cin >> g[i];
        for (int j = 0; j < m; ++j)
            if (g[i][j] == '#') {
                idx[i][j] = tot++;
            }
    }
    scc.init(tot);
    vector<int> tp(m, -1);
    for (int i = n - 1; i >= 0; --i) {
        for (int j = 0; j < m; ++j)
            if (idx[i][j] >= 0) {
                if (tp[j] >= 0)
                    scc.add_edge(idx[i][j], tp[j]);
                if (i - 1 >= 0 && idx[i - 1][j] >= 0)
                    scc.add_edge(idx[i][j], idx[i - 1][j]);
                tp[j] = idx[i][j];
            }
        for (int j = 0; j < m; ++j)
            if (idx[i][j] >= 0) {
                if (j > 0 && tp[j - 1] >= 0)
                    scc.add_edge(idx[i][j], tp[j - 1]);
                if (j + 1 < m && tp[j + 1] >= 0)
                    scc.add_edge(idx[i][j], tp[j + 1]);
            }
    }
    scc.solve();
    int ans = scc.count();
    vector<bool> in(ans);
    for (int i = 0; i < tot; ++i)
        for (int j : scc.G[i])
            if (scc.get_id(i) != scc.get_id(j) && !in[scc.get_id(j)]) {
                in[scc.get_id(j)] = 1;
                --ans;
            }
    cout << ans << '\n';
}
