#include <bits/stdc++.h>
using namespace std;
const int maxn = 4e4 + 7;
const int inf = 0x3f3f3f3f;
struct Edge {
  int from, to, cap, flow;
};
struct Dinic {
  int n, m, s, t;
  vector<Edge> edges;
  vector<int> G[maxn];
  bool vis[maxn];
  int d[maxn];
  int cur[maxn];
  void init(int n) {
    this->n = n;
    for (int i = 0; i < n; i++) G[i].clear();
    edges.clear();
  }
  void addedge(int from, int to, int cap, int c = 0) {
    edges.push_back(Edge{from, to, cap, 0});
    edges.push_back(Edge{to, from, c, 0});
    m = edges.size();
    G[from].push_back(m - 2);
    G[to].push_back(m - 1);
  }
  bool BFS() {
    memset(vis, 0, sizeof(vis));
    queue<int> q;
    q.push(s);
    d[s] = 0;
    vis[s] = 1;
    while (!q.empty()) {
      int u = q.front();
      q.pop();
      for (int i = 0; i < G[u].size(); i++) {
        Edge& e = edges[G[u][i]];
        if (!vis[e.to] && e.cap > e.flow) {
          vis[e.to] = 1;
          d[e.to] = d[u] + 1;
          q.push(e.to);
        }
      }
    }
    return vis[t];
  }
  int DFS(int u, int dist) {
    if (u == t || dist == 0) return dist;
    int flow = 0, f;
    for (int& i = cur[u]; i < G[u].size(); i++) {
      Edge& e = edges[G[u][i]];
      if (d[u] + 1 == d[e.to] &&
          (f = DFS(e.to, min(dist, e.cap - e.flow))) > 0) {
        e.flow += f;
        edges[G[u][i] ^ 1].flow -= f;
        flow += f;
        dist -= f;
        if (!dist) break;
      }
    }
    return flow;
  }
  int Maxflow(int s, int t) {
    this->s = s;
    this->t = t;
    int flow = 0;
    while (BFS()) {
      memset(cur, 0, sizeof(cur));
      flow += DFS(s, inf);
    }
    return flow;
  }
} net;
int id[220][220];
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n, m;
  cin >> n >> m;
  vector<string> mp(n);
  for (int i = 0; i < n; ++i) cin >> mp[i];
  int s = 1, tot = 0;
  for (int i = 0; i < n; ++i)
    for (int j = 0; j < m; ++j)
      if (mp[i][j] == '#') id[i][j] = s++, tot++;
  net.init(s + 1);
  int ans = 0;
  for (int i = 0; i < n - 1; ++i) {
    for (int j = 0; j < m; ++j) {
      if (id[i][j] && id[i + 1][j]) {
        ans += 2;
        net.addedge(0, id[i][j], 1);
        net.addedge(0, id[i + 1][j], 1);
        net.addedge(id[i + 1][j], id[i][j], 1);
        net.addedge(id[i][j], id[i + 1][j], 1);
      }
    }
  }
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < m - 1; ++j) {
      if (id[i][j] && id[i][j + 1]) {
        ans += 2;
        net.addedge(id[i][j], s, 1);
        net.addedge(id[i][j + 1], s, 1);
        net.addedge(id[i][j + 1], id[i][j], 1);
        net.addedge(id[i][j], id[i][j + 1], 1);
      }
    }
  }
  ans -= net.Maxflow(0, s);
  cout << tot - ans / 2 << '\n';
  return 0;
}
