#include <iostream>
#include <numeric>
#include <algorithm>
#include <iterator>
#include <string>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <utility>
#define fore(i, l, r) for(int i = int(l); i < int(r); i++)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define vi vector<int>
#define vpi vector<pair<int, int>>
#define vl vector<long long>
#define vpl vector<pair<long long, long long>>
#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "
template<typename T>
void printVector(const T& t) {
    std::copy(t.cbegin(), t.cend(), std::ostream_iterator<typename T::value_type>(std::cout, ", "));
}
using namespace std;
using ll = long long;
const int mode = 0;

/* SCC stuff */
struct SCC {
    int V = 0;
    vector<vector<int>> adj;
    vector<int> tour_index, low_link;
    int tour;
 
    vector<int> stack;
    vector<bool> in_stack;
 
    vector<vector<int>> components;
    vector<int> which_component;
 
    SCC(int v = 0) {
        init(v);
    }
 
    SCC(const vector<vector<int>> &_adj) {
        init(_adj);
    }
 
    void init(int v) {
        V = v;
        adj.assign(V, {});
    }
 
    void init(const vector<vector<int>> &_adj) {
        adj = _adj;
        V = int(adj.size());
    }
 
    void add_edge(int a, int b) {
        adj[a].push_back(b);
    }
 
    // Tarjan's algorithm.
    void dfs(int node) {
        tour_index[node] = tour++;
        low_link[node] = tour_index[node];
        stack.push_back(node);
        in_stack[node] = true;
 
        for (int neighbor : adj[node])
            if (tour_index[neighbor] < 0) {
                // neighbor is part of our subtree.
                dfs(neighbor);
                low_link[node] = min(low_link[node], low_link[neighbor]);
            } else if (in_stack[neighbor]) {
                // neighbor is a candidate for low_link.
                low_link[node] = min(low_link[node], tour_index[neighbor]);
            }
 
        if (low_link[node] == tour_index[node]) {
            // node is the highest node in an SCC, which includes everything on the stack up to it.
            components.emplace_back();
            vector<int> &component = components.back();
            int x;
 
            do {
                x = stack.back();
                stack.pop_back();
                in_stack[x] = false;
                which_component[x] = int(components.size()) - 1;
                component.push_back(x);
            } while (x != node);
        }
    }
 
    void build() {
        tour_index.assign(V, -1);
        low_link.resize(V);
        which_component.assign(V, -1);
 
        stack.clear();
        stack.reserve(V);
        in_stack.assign(V, false);
        tour = 0;
 
        // Note that Tarjan's algorithm provides the SCCs in reverse topological order.
        components = {};
 
        for (int i = 0; i < V; i++)
            if (tour_index[i] < 0)
                dfs(i);
    }
};
/* SCC stuff */

void solve() {
  int h, w;
  cin >> h >> w;
  vector<string> grid(h);
  fore(i, 0, h) cin >> grid[i];
  vi row(h);
  fore(i, 0, h) cin >> row[i];

  
  vector<vector<int>> ids(h, vector<int>(w, -1));
  int id = 0;
  fore(i, 0, h) {
    fore(j, 0, w) {
      if (grid[i][j] == '#') {
        ids[i][j] = id;
        id++;
      }
    }
  }

  int n = id;
  vector<vector<int>> adj(n);
  vi top(w, -1);
  for (int i = h - 1; i >= 0; i--) {
    fore(j, 0, w) {
      if (grid[i][j] == '#') {
        // grain found
        int u = ids[i][j];
        if (i > 0 && grid[i-1][j] == '#') {
          adj[u].pb(ids[i-1][j]);
        }
        /* top[] will get this
        if (j > 0 && grid[i][j-1] == '#') {
          adj[u].pb(ids[i][j-1]);
        }
        */ 
        if (j + 1 < w  && grid[i][j+1] == '#') {
          adj[u].pb(ids[i][j+1]);
        }
        for (int col = j - 1; col <= j + 1; col++) {
          if (col < 0 || col >= w) continue;
          else if (top[col] != -1) {
            adj[u].pb(top[col]);
          }
        }
        top[j] = u;
      }
    }
  }

 
  SCC scc(adj);
  scc.build();
  int s = scc.components.size();
  vi indegree (s, 0);
  int ans = s;
  fore(u, 0, n) {
    for (int v : adj[u]) {
      if (scc.which_component[u] != scc.which_component[v]) {
        indegree[scc.which_component[v]]++;
        if (indegree[scc.which_component[v]] == 1) ans--;
      }
    }
  }
  cout << ans << "\n";
    
}



int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  int t;

  if (mode == 0) { 
    solve();
  } else {
    cin >> t;
    while (t--) {
      solve();
    }
  }
}
