#define _USE_MATH_DEFINES
#define _CRT_SECURE_NO_DEPRECATE

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <limits>
#include <ctime>
#include <cassert>
#include <map>
#include <set>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
#include <sstream>
#include <stack>
#include <queue>
#include <numeric>
#include <iterator>
#include <bitset>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> Pii;
typedef pair<ll, ll> Pll;

#define FOR(i,n) for(int i = 0; i < (n); i++)
#define sz(c) ((int)(c).size())
#define ten(x) ((int)1e##x)

// #pragma comment(linker,"/STACK:36777216")

template<class T> void chmax(T& l, const T r) { l = max(l, r); }
template<class T> void chmin(T& l, const T r) { l = min(l, r); }

const int MAX_N = 100000;
vector<int> G[MAX_N];
int match[MAX_N];
bool used[MAX_N];

void add_edge(int u, int v) {
	G[u].push_back(v);
	G[v].push_back(u);
}

bool dfs(int v) {
	used[v] = true;
	for (auto u : G[v]) {
		int w = match[u];
		if (w < 0 || !used[w] && dfs(w)) {
			match[v] = u;
			match[u] = v;
			return true;
		}
	}
	return false;
}

int bipartite_matching(int N) {
	int ret = 0;
	memset(match, -1, sizeof(match));
	FOR(v, N) {
		if (match[v] < 0) {
			memset(used, 0, sizeof(used));
			if (dfs(v)) ret++;
		}
	}
	return ret;
}

int h, w;
char s[100][101];
int block[100][100];
int dir[100][100];

int solve() {
	FOR(i, h) FOR(j, w) block[i][j] = (s[i][j] == '.') ? 0 : 1;
	FOR(i, h - 1) FOR(j, w - 1) {
		dir[i][j] = -1;
		int sum = block[i][j] + block[i][j + 1] + block[i + 1][j] + block[i + 1][j + 1];
		if (sum == 3) {
			if (block[i][j] == 0) dir[i][j] = 0;
			else if (block[i][j + 1] == 0) dir[i][j] = 1;
			else if (block[i + 1][j] == 0) dir[i][j] = 2;
			else dir[i][j] = 3;
		}
	}

	vector<pair<Pii, Pii> > lrcut,udcut;
	FOR(i, h - 1) {
		Pii left(-1, -1);
		FOR(j, w - 1) {
			if (block[i][j + 1] == 0 && block[i + 1][j + 1] == 0) {
				left = Pii(-1, -1);
				continue;
			}
			if (dir[i][j] == -1) continue;
			if (dir[i][j] == 0 || dir[i][j] == 2) {
				left = Pii(i, j);
			} else {
				if (left.first != -1) {
					lrcut.emplace_back(left, Pii(i, j));
					left = Pii(-1, -1);
				}
			}
		}
	}
	FOR(j, w - 1) {
		Pii left(-1, -1);
		FOR(i, h - 1) {
			if (block[i + 1][j] == 0 && block[i + 1][j + 1] == 0) {
				left = Pii(-1, -1);
				continue;
			}
			if (dir[i][j] == -1) continue;
			if (dir[i][j] == 0 || dir[i][j] == 1) {
				left = Pii(i, j);
			} else {
				if (left.first != -1) {
					udcut.emplace_back(left, Pii(i, j));
					left = Pii(-1, -1);
				}
			}
		}
	}

	map<pair<Pii, Pii>, int> pt2id;
	for (auto& val : lrcut){  
		int id = sz(pt2id);
		pt2id[val] = id;
	}
	for (auto& val : udcut) {
		int id = sz(pt2id);
		pt2id[val] = id;
	}

	FOR(i, sz(lrcut) + sz(udcut)) G[i].clear();
	for (auto& lr: lrcut) {
		for (auto& ud: udcut) {
			if (lr.first.second <= ud.first.second && ud.first.second <= lr.second.second &&
				ud.first.first <= lr.first.first && lr.first.first <= ud.second.first) {
				add_edge(pt2id[lr], pt2id[ud]);
			}
		}
	}

	int matching = bipartite_matching(sz(lrcut) + sz(udcut));
	int independent_set = sz(lrcut) + sz(udcut) - matching;
	int cut_sum = 0;
	FOR(i, h - 1) FOR(j, w - 1) if (dir[i][j] != -1) cut_sum++;
	cut_sum -= independent_set;
	return cut_sum + 1;
}

int main() {
	while (cin >> h >> w, h) {
		FOR(i, h) cin >> s[i];
		int ans = solve();
		cout << ans << endl;
	}

	return 0;
}

Measured memory_bytes: 4852