#include <bits/stdc++.h>
class Graph {
 private:
  struct Edge {
    int to, next, c;
  } edge[1 << 20];
  int cnt, head[1 << 20];
  void add(int from, int to, int c) {
    edge[++cnt].to = to;
    edge[cnt].c = c;
    edge[cnt].next = head[from];
    head[from] = cnt;
  }
  int dep[1 << 20];
  bool bfs(void) {
    std::queue<int> q;
    q.push(s);
    std::memset(dep, 0, sizeof dep);
    dep[s] = 1;
    while (!q.empty()) {
      int node = q.front();
      q.pop();
      for (int i = head[node]; i != -1; i = edge[i].next) {
        if (edge[i].c && !dep[edge[i].to])
          dep[edge[i].to] = dep[node] + 1, q.push(edge[i].to);
      }
    }
    return dep[t];
  }
  int cur[1 << 20];
  int dfs(int node, int flow) {
    if (node == t || !flow) return flow;
    int stream = 0, f;
    for (int i = cur[node]; i != -1; i = edge[i].next) {
      cur[node] = i;
      if (dep[edge[i].to] == dep[node] + 1 &&
          (f = dfs(edge[i].to, std::min(flow, edge[i].c)))) {
        edge[i].c -= f, edge[i ^ 1].c += f;
        flow -= f, stream += f;
        if (!flow) break;
      }
    }
    return stream;
  }

 public:
  int s, t;
  Graph() {
    std::memset(head, -1, sizeof head);
    cnt = -1;
  }
  void set(int src, int trm) { s = src, t = trm; }
  void add_edge(int from, int to, int c) {
    add(from, to, c);
    add(to, from, 0);
  }
  int flow(void) {
    int f = 0;
    while (bfs()) {
      std::memcpy(cur, head, sizeof head);
      f += dfs(s, 0x3f3f3f3f);
    }
    return f;
  }
} G;
const int MAXN = 2e2 + 19;
int n, m, ans;
char s[MAXN][MAXN];
int h[MAXN][MAXN][2], ind = 2;
inline int hash(int i, int j, int a) {
  if (!h[i][j][a]) h[i][j][a] = ++ind;
  return h[i][j][a];
}
int main() {
  std::scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; ++i) std::scanf("%s", s[i] + 1);
  G.set(1, 2);
  for (int i = 1; i <= n; ++i)
    for (int j = 1; j <= m; ++j)
      if (s[i][j] == '#') ++ans;
  for (int i = 1; i <= n; ++i)
    for (int j = 1; j < m; ++j)
      if (s[i][j] == '#' && s[i][j + 1] == '#') {
        --ans;
        G.add_edge(1, hash(i, j, 0), 1);
      }
  for (int i = 1; i < n; ++i)
    for (int j = 1; j <= m; ++j)
      if (s[i][j] == '#' && s[i + 1][j] == '#') {
        --ans;
        G.add_edge(hash(i, j, 1), 2, 1);
      }
  for (int i = 1; i <= n; ++i)
    for (int j = 1; j < m; ++j)
      if (s[i][j] == '#' && s[i][j + 1] == '#') {
        if (s[i - 1][j] == '#')
          G.add_edge(hash(i, j, 0), hash(i - 1, j, 1), 1e6);
        if (s[i + 1][j] == '#') G.add_edge(hash(i, j, 0), hash(i, j, 1), 1e6);
        if (s[i - 1][j + 1] == '#')
          G.add_edge(hash(i, j, 0), hash(i - 1, j + 1, 1), 1e6);
        if (s[i + 1][j + 1] == '#')
          G.add_edge(hash(i, j, 0), hash(i, j + 1, 1), 1e6);
      }
  std::printf("%d\n", ans + G.flow());
  return 0;
}
