#include<iostream>
#include<vector>
#include<set>
using namespace std;

const int INF = 1000000000;
// const int INF = 9;
const int NIL = -1;

//// 平面幾何 ////
enum POSITION {CW, ON, CCW};

struct Point {
    double x, y;
    Point(const double d) :x(d), y(d) {}
    Point(const double x, const double y) :x(x), y(y) {}
};

struct Segment {
    Point initial, terminal;
    Segment(const Point& i, const Point& t) :initial(i), terminal(t) {}
};

bool intersectHV(const Segment& h, const Segment& v) {
    return h.initial.x <= v.initial.x && v.initial.x <= h.terminal.x
        && v.initial.y <= h.initial.y && h.initial.y <= v.terminal.y;
}

bool operator<(const Point& lhs, const Point& rhs) {return lhs.y != rhs.y ? lhs.y < rhs.y : lhs.x < rhs.x;}

//// 色々 ////
bool in(const int y, const int x, const int h, const int w) {
    return 0 <= y && y < h && 0 <= x && x < w;
}

//// グラフ ////
bool augment(const vector<vector<int>>& edge, const int from, vector<int>& matchTo, vector<bool>& visited) {
    if(from == NIL) return true;
    for(const auto& to: edge[from]) {
        if(visited[to]) continue;
        visited[to] = true;
        if(!augment(edge, matchTo[to], matchTo, visited)) continue;
        matchTo[from] = to;
        matchTo[to] = from;
        return true;
    }
    return false;
}

int matching(const vector<vector<int>>& edge, const int x) {
    int result = 0;

    vector<int> matchTo(edge.size(), NIL);
    for(int i = 0; i < x; ++i) {
        vector<bool> visited(edge.size(), false);
        if(augment(edge, i, matchTo, visited)) ++result;
    }

    for(const auto& i: matchTo) if(i == NIL) ++result;

    return result;
}

//// メイン ////
int main() {
    int h, w;
    while(cin >> h >> w , h | w) {
        vector<vector<bool>> chocolate(h, vector<bool>(w, false));
        for(int i = 0; i < h; ++i) for(int j = 0; j < w; ++j) {
            char c;
            cin >> c;
            chocolate[i][j] = (c == '#' ? true : false);
        }

        // 凹点
        enum {Y, X};
        const int NEXT[4][2] = {{-1, -1}, {-1, 1}, {1, -1}, {1, 1}};

        set<Point> point;
        for(int i = 0; i < h; ++i) for(int j = 0; j < w; ++j) {
            if(chocolate[i][j]) continue;
            for(const auto& d: NEXT) {
                int y1 = i + d[Y], x1 = j;
                int y2 = i,        x2 = j + d[X];
                if(!in(y1, x1, h, w) || !in(y2, x2, h, w)) continue;
                if(!chocolate[y1][x1] || !chocolate[y2][x2]) continue;
                point.insert(Point(j + (d[X] == 1 ? 1 : 0), i + (d[Y] == 1 ? 1 : 0)));
            }
        }
//         cout<<"point: "<<point.size()<<endl;
//         for(auto p:point)cout<<p.x<<","<<p.y<<endl;cout<<endl;

        // 分割のための線分
        enum {H, V};
        vector<Segment> vertex[2];

        for(int i = 1; i < h; ++i) for(int j = 1; j < w; ++j) {
            if(!point.count(Point(j, i))) continue;
            for(int x = j; x < w; ++x) {
                if(!chocolate[i - 1][x] || !chocolate[i][x]) break;
                if(!point.count(Point(x + 1, i))) continue;
                vertex[H].push_back(Segment(Point(j, i), Point(x + 1, i)));
                break;
            }
            for(int y = i; y < h; ++y) {
                if(!chocolate[y][j - 1] || !chocolate[y][j]) break;
                if(!point.count(Point(j, y + 1))) continue;
                vertex[V].push_back(Segment(Point(j, i), Point(j, y + 1)));
                break;
            }
        }
//         cout<<"H"<<endl; for(auto v:vertex[H])cout<<v.initial.x<<","<<v.initial.y<<"; "<<v.terminal.x<<","<<v.terminal.y<<endl;
//         cout<<"V"<<endl; for(auto v:vertex[V])cout<<v.initial.x<<","<<v.initial.y<<"; "<<v.terminal.x<<","<<v.terminal.y<<endl;

        // 線分を頂点とした二部グラフ
        vector<vector<int>> edge(vertex[H].size() + vertex[V].size());
        for(int i = 0; i < vertex[H].size(); ++i) for(int j = 0; j < vertex[V].size(); ++j) {
            if(!intersectHV(vertex[H][i], vertex[V][j])) continue;
            edge[i].push_back(vertex[H].size() + j);
            edge[vertex[H].size() + j].push_back(i);
        }
//         for(int i = 0; i < vertex[H].size(); ++i) {
//             for(int j = 0; j < vertex[V].size(); ++j) cout<<" "<<edge[i][j];
//             cout<<endl;
//         }

        // 二部グラフの最大マッチング
        int match = matching(edge, vertex[H].size());
//         cout<<"match: "<<match<<endl;

        cout << point.size() - match + 1 << endl;
//         cout << endl;
    }
}

Measured memory_bytes: 1968