#include <bits/stdc++.h>   #pragma GCC optimize( O3 )   #pragma GCC optimize( Ofast,no-stack-protector )   using namespace std;   function<void(void)> ____ = []() {     ios_base::sync_with_stdio(false);     cin.tie(0);     cout.tie(0);   };   template <typename T>   vector<T> &operator<<(vector<T> &__container, T x) {     __container.push_back(x);     return __container;   }   template <typename T>   ostream &operator<<(ostream &out, vector<T> &__container) {     for (T _ : __container) out << _ <<    ;     return out;   }   const int MAXN = 1e5 + 7;   struct EDGE {     int to, cap, rev;     EDGE(){};     EDGE(int to, int cap, int rev) : to(to), cap(cap), rev(rev){};   };   vector<EDGE> G[MAXN];   int iter[MAXN], rk[MAXN];   void ADDEDGE(int u, int v, int cap) {     G[u].push_back(EDGE(v, cap, (int)G[v].size()));     G[v].push_back(EDGE(u, 0, (int)G[u].size() - 1));   }   bool bfs() {     memset(rk, 0, sizeof(rk));     memset(iter, 0, sizeof(iter));     rk[0] = 1;     queue<int> que;     que.push(0);     while (!que.empty()) {       int u = que.front();       que.pop();       for (auto e : G[u]) {         if (!e.cap or rk[e.to]) continue;         rk[e.to] = rk[u] + 1;         que.push(e.to);       }     }     return rk[MAXN - 1] != 0;   }   int dfs(int u, int flow) {     if (u == MAXN - 1) return flow;     for (int &i = iter[u]; i < (int)G[u].size(); i++) {       auto &e = G[u][i];       if (!e.cap or rk[e.to] != rk[u] + 1) continue;       int d = dfs(e.to, min(e.cap, flow));       if (d) {         e.cap -= d;         G[e.to][e.rev].cap += d;         return d;       }     }     return 0;   }   int Dinic() {     int flow = 0;     while (bfs()) {       int d = dfs(0, 0x3f3f3f3f);       while (d) {         flow += d;         d = dfs(0, 0x3f3f3f3f);       }     }     return flow;   }   int n, m, idud[222][222], idlr[MAXN][222];   char g[222][222];   void solve() {     scanf( %d , &n);     scanf( %d , &m);     int cur = 1, cnt = 0, tot = 0;     for (int i = 1; i <= n; i++) scanf( %s , g[i] + 1);     for (int i = 1; i <= n; i++)       for (int j = 1; j <= m; j++)         if (g[i][j] ==  # ) tot++;     for (int i = 1; i < n; i++)       for (int j = 1; j <= m; j++) idud[i][j] = cur++;     for (int i = 1; i <= n; i++)       for (int j = 1; j < m; j++) idlr[i][j] = cur++;     for (int i = 1; i < n; i++)       for (int j = 1; j <= m; j++)         if (g[i][j] ==  #  and g[i + 1][j] ==  # )           ADDEDGE(0, idud[i][j], 1), cnt++;     for (int i = 1; i <= n; i++)       for (int j = 1; j < m; j++)         if (g[i][j] ==  #  and g[i][j + 1] ==  # )           ADDEDGE(idlr[i][j], MAXN - 1, 1), cnt++;     for (int i = 1; i < n; i++)       for (int j = 1; j <= m; j++) {         if (g[i][j] ==  #  and g[i + 1][j] ==  # ) {           if (g[i][j - 1] ==  # ) ADDEDGE(idud[i][j], idlr[i][j - 1], 0x3f3f3f3f);           if (g[i + 1][j - 1] ==  # )             ADDEDGE(idud[i][j], idlr[i + 1][j - 1], 0x3f3f3f3f);           if (g[i][j + 1] ==  # ) ADDEDGE(idud[i][j], idlr[i][j], 0x3f3f3f3f);           if (g[i + 1][j + 1] ==  # )             ADDEDGE(idud[i][j], idlr[i + 1][j], 0x3f3f3f3f);         }       }     cout << tot - (cnt - Dinic()) <<   n ;   }   int main() {     solve();     return 0;   }