#include <bits/stdc++.h>
using namespace std;
int S, T;
struct Dinic {
  struct Edge {
    int j, cap, flow;
    Edge(int j = 0, int cap = 0, int flow = 0) : j(j), cap(cap), flow(flow) {}
  };
  int ptr[88400], dist[88400];
  vector<Edge> edge;
  vector<int> graph[88400];
  void addEdge(int u, int v) {
    graph[u].push_back(edge.size());
    edge.push_back(Edge(v, 1, 0));
    graph[v].push_back(edge.size());
    edge.push_back(Edge(u, 0, 0));
  }
  int dfs(int x, int cur) {
    if (x == T) return cur;
    while (ptr[x] < graph[x].size()) {
      int edgeId = graph[x][ptr[x]++];
      int y = edge[edgeId].j;
      if (dist[y] != dist[x] + 1 || edge[edgeId].flow >= edge[edgeId].cap)
        continue;
      int f = min(cur, edge[edgeId].cap - edge[edgeId].flow);
      f = dfs(y, f);
      if (f > 0) {
        edge[edgeId].flow += f;
        edge[edgeId ^ 1].flow -= f;
        return f;
      }
    }
    return 0;
  }
  bool buildLevelGraph() {
    for (int i = 0; i <= T * 2 + 5; i++) dist[i] = -1;
    dist[S] = 0;
    vector<int> q;
    q.push_back(S);
    int ini = 0;
    while (ini < q.size()) {
      int x = q[ini++];
      for (int j = 0; j < graph[x].size(); j++) {
        int edgeId = graph[x][j];
        int y = edge[edgeId].j;
        int cap = edge[edgeId].cap;
        int flow = edge[edgeId].flow;
        if (flow >= cap || dist[y] != -1) continue;
        dist[y] = dist[x] + 1;
        q.push_back(y);
      }
    }
    return dist[T] != -1;
  }
  int maximumMatching() {
    int maxFlow = 0, f;
    while (buildLevelGraph()) {
      for (int i = 0; i <= 2 * T + 5; i++) ptr[i] = 0;
      while (true) {
        f = dfs(S, 1000000007);
        if (f == 0) break;
        maxFlow += f;
      }
    }
    return maxFlow;
  }
} dinic;
int n, m, cte, qtdBlack, qtdVert;
char grid[210][210];
bool valid(int i, int j) { return 0 <= min(i, j) && i < n && j < m; }
int get(int i, int j) { return i * m + j; }
int32_t main() {
  scanf("%d%d", &n, &m);
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++) {
      scanf(" %c", &grid[i][j]);
      qtdBlack += (grid[i][j] == '#');
    }
  S = (n - 1) * m + m;
  T = S + 1;
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++) {
      if (grid[i][j] == '#' && valid(i + 1, j) && grid[i + 1][j] == '#') {
        qtdVert++;
        dinic.addEdge(S, get(i, j));
        if (valid(i, j - 1) && grid[i][j - 1] == '#')
          dinic.addEdge(get(i, j), get(i, j - 1) + T + 1);
        if (valid(i, j + 1) && grid[i][j + 1] == '#')
          dinic.addEdge(get(i, j), get(i, j) + T + 1);
        if (valid(i + 1, j) && grid[i + 1][j] == '#') {
          if (valid(i + 1, j + 1) && grid[i + 1][j + 1] == '#')
            dinic.addEdge(get(i, j), get(i + 1, j) + T + 1);
          if (valid(i + 1, j - 1) && grid[i + 1][j - 1] == '#')
            dinic.addEdge(get(i, j), get(i + 1, j - 1) + T + 1);
        }
      }
      if (grid[i][j] == '#' && valid(i, j + 1) && grid[i][j + 1] == '#') {
        qtdVert++;
        dinic.addEdge(get(i, j) + T + 1, T);
      }
    }
  printf("%d\n", qtdBlack - (qtdVert - dinic.maximumMatching()));
}
