#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
using ll = long long;
using ull = unsigned long long; 
using pii =  pair<int, int>;
using pll =  pair<long long, long long>;
#define rep(i, n) for(int i = 0; i < (n); ++i)
#define all(x) (x).begin(),(x).end()
constexpr char ln =  '\n';
constexpr long long MOD = 1000000007LL;
//constexpr long long MOD = 998244353LL;
template<class T, class U> inline bool chmax(T &a, U b) { if (a < b) { a = b; return true;} return false; }
template<class T, class U> inline bool chmin(T &a, U b) { if (a > b) { a = b; return true;} return false; }
////////////////////////////////////////////////////////////////////////////////////////////////////////////

template<typename flow_t>
struct Dinic {
    struct edge {
        int to;
        flow_t cap;
        int rev;
        edge(){}
        edge(int to, flow_t cap, int rev) : to(to), cap(cap), rev(rev) {}
    };

    vector<vector<edge>> G;
    vector<int> level,iter;
    Dinic(){}
    Dinic(int N) : G(N),level(N),iter(N) {} 

    int add_edge(int from, int to, flow_t cap) {
        G[from].emplace_back(to, cap, G[to].size());
        G[to].emplace_back(from, 0, G[from].size()-1);
        return G[to].back().rev;
    }

    void bfs(int s) {
        fill(level.begin(),level.end(),-1);
        queue<int> que;
        level[s] = 0;
        que.emplace(s);
        while (!que.empty()) {
            int v = que.front(); que.pop();
            for(int i = 0; i < (int)G[v].size(); i++) {
                edge &e = G[v][i];
                if(e.cap > 0 && level[e.to] < 0) {
                    level[e.to] = level[v] + 1;
                    que.emplace(e.to);
                }
            }
        }
    }

    flow_t dfs(int v, int t, flow_t f) {
        if(v == t) return f;
        for (int &i=iter[v]; i < (int)G[v].size(); i++) {
            edge &e = G[v][i];
            if (e.cap > 0 && level[v] < level[e.to]) {
                flow_t d = dfs(e.to, t, min(f,e.cap));
                if (d == 0) continue;
                e.cap -= d;
                G[e.to][e.rev].cap += d;
                return d;
            }
        }
        return 0;
    }

    flow_t flow(int s, int t, flow_t lim) {
        flow_t fl = 0;
        while (true) {
            bfs(s);
            if (level[t] < 0 || lim == 0) break;
            fill(iter.begin(),iter.end(),0);

            while (true) {
                flow_t f = dfs(s,t,lim);
                if (f == 0) break;
                fl += f;
                lim -= f;
            }
        }
        return fl;
    }
};

const int dy[4] = {-1,0,1,0};
const int dx[4] = {0,-1,0,1};

int main() {
    ios::sync_with_stdio(false); cin.tie(nullptr);
    int R,C; cin >> R >> C;
    vector<string> S(R);
    rep(i,R) cin >> S[i];

    map<int, int> dic;
    int N = 2;
    rep(i,R) {
        rep(j,C) {
            if (S[i][j]=='#') {
                dic.emplace(i*C+j,N++);
            }
        }
    }
    if (N==2) {
        cout << 0 << ln;
        return 0;
    }
    Dinic<int> D(2000);
    //0は縦、1は横
    int ans = 0;
    rep(i,R) {
        rep(j,C) {
            if (S[i][j]=='#') {
                int id = dic[i*C+j];
                D.add_edge(0,id,1);
                D.add_edge(id,1,1);
                rep(k,2) {
                    int ny = i+dy[k];
                    int nx = j+dx[k];
                    if (ny < 0 or nx < 0) continue;
                    if (S[ny][nx]!='#') continue;
                    int nid = dic[ny*C+nx];
                    if (k) {
                        //横
                        D.add_edge(id,N,1e9);
                        D.add_edge(nid,N,1e9);
                        D.add_edge(0,N,0);
                        D.add_edge(N,1,1);
                    } else {
                        //縦
                        D.add_edge(N,id,1e9);
                        D.add_edge(N,nid,1e9);
                        D.add_edge(N,1,0);
                        D.add_edge(0,N,1);
                    }
                    ans++;
                    N++;
                }
            }
        }
    }
    
    cout << D.flow(0,1,1e9)-ans << ln;
}


Measured memory_bytes: 3420