#include <bits/stdc++.h>
using namespace std;
constexpr int kN = int(1E5 + 10), kNN = int(2E2 + 10), kInf = int(1E9 + 10);
struct Edge {
  int to, rev, cap;
};
vector<Edge> graph[kN];
int iter[kN], went[kN], dep[kN];
void AddEdge(int u, int v, int c) {
  graph[u].push_back({v, int(graph[v].size()), c});
  graph[v].push_back({u, int(graph[u].size()) - 1, 0});
  return;
}
void Bfs(int s, int t) {
  queue<int> q;
  int nxt;
  q.push(s);
  iter[s] = dep[s] = 0;
  went[s] = t;
  while (!q.empty()) {
    nxt = q.front();
    q.pop();
    for (Edge i : graph[nxt])
      if (went[i.to] != t && i.cap > 0) {
        went[i.to] = t;
        dep[i.to] = dep[nxt] + 1;
        q.push(i.to);
        iter[i.to] = 0;
      }
  }
  return;
}
int Dfs(int u, int t, int nv) {
  if (u == t) return nv;
  int tmp;
  for (int& i = iter[u]; i < int(graph[u].size()); i++) {
    Edge& nxt = graph[u][i];
    if (dep[nxt.to] > dep[u] && nxt.cap > 0) {
      tmp = Dfs(nxt.to, t, min(nv, nxt.cap));
      if (tmp > 0) {
        nxt.cap -= tmp;
        graph[nxt.to][nxt.rev].cap += tmp;
        return tmp;
      }
    }
  }
  return 0;
}
int Dinic(int s, int t) {
  int ans = 0, cnt = 0, f;
  for (int i = 0; i < kN; i++) went[i] = 0;
  while (true) {
    Bfs(s, ++cnt);
    if (went[s] != went[t]) break;
    while ((f = Dfs(s, t, kInf)) > 0) ans += f;
  }
  return ans;
}
string s[kNN];
int idx1[kNN][kNN], idx2[kNN][kNN];
int main() {
  int n, m, cnt = 0, now = 0, S, T, v = 0;
  cin >> n >> m;
  for (int i = 0; i < n; i++) cin >> s[i];
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++)
      if (s[i][j] == '#') cnt++;
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++) idx1[i][j] = now++;
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++) idx2[i][j] = now++;
  S = now++;
  T = now++;
  for (int i = 0; i < n; i++)
    for (int j = 1; j < m; j++)
      if (s[i][j] == '#' && s[i][j - 1] == '#') {
        v++;
        AddEdge(S, idx1[i][j], 1);
      }
  for (int i = 1; i < n; i++)
    for (int j = 0; j < m; j++)
      if (s[i][j] == '#' && s[i - 1][j] == '#') {
        v++;
        AddEdge(idx2[i][j], T, 1);
      }
  for (int i = 1; i < n; i++)
    for (int j = 1; j < m; j++)
      if (s[i][j - 1] == '#' && s[i - 1][j] == '#') {
        AddEdge(idx1[i][j], idx2[i][j], 1);
        AddEdge(idx1[i - 1][j], idx2[i][j - 1], 1);
      }
  for (int i = 1; i < n; i++)
    for (int j = 1; j < m; j++)
      if (s[i][j] == '#' && s[i - 1][j - 1] == '#') {
        AddEdge(idx1[i][j], idx2[i][j - 1], 1);
        AddEdge(idx1[i - 1][j], idx2[i][j], 1);
      }
  printf("%d\n", cnt - v + Dinic(S, T));
}
