#include <bits/stdc++.h>
using namespace std;

#define REP(i,n) for(int i=0; i<n; i++)
#define FOR(i,a,b) for(int i=a; i<b; i++)
#define FORR(i,a,b) for(int i=(int)b-1; i>=a; i--)

#define ALL(v) (v).begin(), (v).end()

using ll = long long;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
using vi = vector<int>;
using vl = vector<ll>;

#define DEBUG(x) cerr<<#x<<": "<<(x)<<endl
#define CHMIN(a,b) (a)=min((a),(b))
#define CHMAX(a,b) (a)=max((a),(b))

const int INF = 1ll<<28;
using flow_type = int;

struct dinic{
	struct edge{
		int from, to;
		flow_type cost;
		int rev;
	};
	int n;
	vector<vector<edge>> G,C;
	vector<int> level;
	vector<bool> finished;
	dinic(int n):n(n){
		G.assign(n,vector<edge>());
		level.assign(n,0);
		finished.assign(n,false);
	}
	void add_edge(int from,int to,flow_type cost){
		edge s = (edge){from,to,cost,(int)G[to].size()};
		edge t = (edge){to,from,(flow_type)0,(int)G[from].size()};
		G[from].push_back(s);
		G[to].push_back(t);
	}
	flow_type dfs(int u, int t, flow_type cur){
		if(u==t || cur==0)return cur;
		if(finished[u])return 0;
		finished[u] = true;
		for(edge &e : C[u]){
			if(level[e.to] > level[u]){
				flow_type f = dfs(e.to, t, min(cur, e.cost));
				if(f>0){
					e.cost -= f;
					C[e.to][e.rev].cost += f;
					finished[u] = false;
					return f;
				}
			}
		}
		return 0;
	}
	flow_type calc(int s, int t){
		C = G;
		flow_type total = 0;
		while(true){
			REP(i,n)level[i] = -1;
			level[s] = 0;
			queue<int> Q; Q.push(s);
			int d = n;
			while(!Q.empty()){
				int u = Q.front(); Q.pop();
				for(edge &e:C[u]){
					if(e.cost > 0 && level[e.to] == -1){
						Q.push(e.to);
						level[e.to] = level[u] + 1;
					}
				}
			}
			REP(i,n)finished[i] = false;
			bool flag = false;
			while(true){
				flow_type f = dfs(s,t,INF);
				if(f==0)break;
				total += f;
				flag = true;
			}
			if(!flag)break;
		}
		return total;
	}
};

int w,h;
char mp[125][125];

bool vert(pair<pii,pii> line){
	return line.first.second == line.second.second;
}

int main(){
	while(true){
		scanf("%d%d",&h,&w);
		if(h+w==0)break;
		REP(i,125)REP(j,125)mp[i][j] = '.';
		REP(i,h)scanf("%s",mp[i+1]+1);
		h+=2; w+=2;
		vector<pair<pii,pii>> lines;
		vector<pii> vertices;
		FOR(y1,1,h-1)FOR(x1,1,w-1){
			int cnt = 0;
			REP(dy,2)REP(dx,2)cnt += (mp[y1-dy][x1-dx]=='#');
			if(cnt!=3)continue;
			vertices.push_back(pii(y1,x1));
			{
				int cy=y1, cx=x1;
				while(mp[cy][cx]=='#' && mp[cy-1][cx]=='#')cx++;
				int cnt = 0;
				REP(dy,2)REP(dx,2)cnt += (mp[cy-dy][cx-dx]=='#');
				if((cy!=y1 || cx!=x1) && cnt==3){
					lines.push_back(make_pair(pii(y1,x1),pii(cy,cx)));
					// printf("%d %d - %d %d\n",y1,x1,cy,cx);
				}
			}
			{
				int cy=y1, cx=x1;
				while(mp[cy][cx]=='#' && mp[cy][cx-1]=='#')cy++;
				int cnt = 0;
				REP(dy,2)REP(dx,2)cnt += (mp[cy-dy][cx-dx]=='#');
				if((cy!=y1 || cx!=x1) && cnt==3){
					lines.push_back(make_pair(pii(y1,x1),pii(cy,cx)));
					// printf("%d %d - %d %d\n",y1,x1,cy,cx);
				}
			}
		}
		int N = lines.size();
		const int S = N;
		const int T = N+1;
		dinic D(N+2);
		REP(i,N){
			if(vert(lines[i])){
				D.add_edge(S,i,+1);
				D.add_edge(i,T,+0);
			}else{
				D.add_edge(S,i,+0);
				D.add_edge(i,T,+1);
			}
		}
		REP(i,N)REP(j,i){
			pair<pii,pii> a = lines[i], b = lines[j];
			if(vert(a)==vert(b))continue;
			bool flag = false;
			if(vert(b))flag=true,swap(a,b);
			assert(vert(a));
			if(b.second.second < a.first.second)continue;
			if(a.first.second < b.first.second)continue;
			if(a.second.first < b.first.first)continue;
			if(b.first.first < a.first.first)continue;
			if(!flag){
				// i is vert
				D.add_edge(i,j,+40000);
			}else{
				D.add_edge(j,i,+40000);
			}
			// DEBUG(i); DEBUG(j);
		}
		int unused = D.calc(S,T);
		int used = N - unused;
		int ans = used + (vertices.size() - 2*used) + 1;
		printf("%d\n",ans);
		// break;
	}
	return 0;
}




Measured memory_bytes: 4516