Problem:
Square Carpets
Mr. Frugal bought a new house.
He feels deeply in love with his new house
because it has a comfortable living room
in which he can put himself completely at ease.
He thinks his new house is a really good buy.
But, to his disappointment, 
the floor of its living room has some scratches on it.
The floor has a rectangle shape, covered with square panels.
He wants to replace all the scratched panels with flawless panels, 
but he cannot afford to do so.
Then, he decides to cover all the scratched panels 
with carpets.
The features of the carpets he can use are as follows.
Carpets are square-shaped.
Carpets may overlap each other.
Carpets cannot be folded.
Different sizes of carpets are available.
Lengths of sides of carpets are multiples of that of the panels.
The carpets must cover all the scratched panels,
but must not cover any of the flawless ones.
For example, 
if the scratched panels are as shown in Figure 1, 
at least 6 carpets are needed.
Figure 1: Example Covering
As carpets cost the same irrespective of their sizes, 
Mr. Frugal would like to use as few number of carpets as possible.
Your job is to write a program which tells the minimum number 
of the carpets to cover all the scratched panels.
Input
The input consists of multiple data sets.

As in the following, the end of the input is indicated by a line
containing two zeros.
DataSet
1
DataSet
2
...
DataSet
n
0
0
Each data set (
DataSet
i
) represents the
state of a floor. The format of a data set is as follows.
W
H
P
11
P
12
P
13
...
P
1
W
P
21
P
22
P
23
...
P
2
W
...
P
H
1
P
H
2
P
H
3
...
P
HW
The positive integers
W
and
H
are the numbers of panels
on the living room
in the x- and y- direction, respectively.
The values of
W
and
H
are no more than 10.
The integer
P
yx
represents the state of the panel.
The value of
P
yx
means,
0
: flawless panel (must not be covered),
1
: scratched panel (must be covered).
Output
For each data set,
your program should output a line containing one integer which 
represents the minimum number of the carpets to cover 
all of the scratched panels.
Sample Input
4 3
0 1 1 1
1 1 1 1
1 1 1 1
8 5
0 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 0 1 1 1 1
0 1 1 1 0 1 1 1
8 8
0 1 1 0 0 1 1 0
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
0 1 1 0 0 1 1 0
0 1 1 0 0 1 1 0
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
0 1 1 0 0 1 1 0
10 10
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 0 1 1 0 1 1 0 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 0 1 1 0 1 1 0 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 0 1 1 0 1 1 0 1
1 1 1 1 1 1 1 1 1 1
0 0
Output for the Sample Input
2
6
14
29

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
//#define int long long
typedef long long ll;
using namespace std;
#define inf 0x3f3f3f3f
#define se second
#define fi first
const int mx = 1E4;
int n,m;
int a[14][14];
int dp[14][14];
int vis[14][14];
int ans;
void paint(int x,int y){
    for(int i = x;i<x+dp[x][y];i++){
        for(int j = y;j<y+dp[x][y];j++){
            vis[i][j]++;
        }
    }
}

void unPaint(int x,int y){
    for(int i = x;i<x+dp[x][y];i++){
        for(int j = y;j<y+dp[x][y];j++){
            vis[i][j]--;
        }
    }
}

bool cov(int x,int y){
    if(!a[x][y]) return true;
    if(vis[x][y]) return true;
    return false;
}
unordered_map<string,int> pp;
string getCon(int cur){
    string s;
    for(int i = 1;i<=n;i++){
        for(int j = 1;j<=m;j++){
            if(vis[i][j]){
                s+="1";
            }else{
                s+="0";
            }
        }
    }
    s+= to_string(cur);
    return s;
}

void dfs(int t,int cur){
    int x = t/m+1;
    int y = t%m+1;
    if( cur >= ans) return ;
    if(t == n*m){
        ans = min(ans,cur);
        return ;
    }
    string tmp = getCon(cur);
    if(pp.find(tmp) != pp.end()){
        return;
    }
    int as = mx;
    if(cov(x,y)){
        dfs(t+1,cur);
        if(!dp[x][y]) return;
        paint(x,y);
        dfs(t+1,cur+1);
        unPaint(x,y);
    }else{
        if(!dp[x][y]) return;
        paint(x,y);
        dfs(t+1,cur+1);
        unPaint(x,y);
    }
    pp[tmp] = 1;
}

signed main(){
#ifdef LOCAL
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
#endif
    while(cin>>m>>n && (m|n)){
        pp.clear();
        ans = mx;
        memset(dp,0,sizeof(dp));
        memset(vis,0,sizeof(vis));
        memset(a,0,sizeof(a));

        for(int i = 1;i<=n;i++){
            for(int j = 1;j<=m;j++){
                scanf("%d",&a[i][j]);
            }
        }
        for(int i = n;i>0;i--){
            for(int j = m;j>0;j--){
                if(!a[i][j]) continue;
                dp[i][j] = min(dp[i+1][j],min(dp[i+1][j+1],dp[i][j+1]))+1;
            }
        }

        //递推化简
        for(int i = n;i>0;i--){
            for(int j = m;j;j--){
                if(dp[i+1][j+1]<dp[i][j]) dp[i+1][j+1] = 0;
                if(dp[i][j+1]<dp[i][j]) dp[i][j+1] = 0;
                if(dp[i+1][j]<dp[i][j]) dp[i+1][j] = 0;
            }
        }
        dfs(0,0);
        printf("%d\n",ans);
    }

}
accuracy: 1
time_ms: 20
memory_kb: 4092
final_rank: 6

code_snippet: #include <iostream>

using namespace std;
using pii = pair<int, int>;
#define MAX 11
#define FLO 0
#define SCR 1
#define CAR 2
#define mkpr make_pair

int map[MAX][MAX];
int bigCar[MAX][MAX];
int numCar[MAX][MAX];
int h, w, minCost;

int calcBigCar(int y, int x)
{
    if (map[y][x] == 0)
        return 0;

    int dx[3] = { 0,1,1 };
    int dy[3] = { 1,1,0 };
    int front, last;
    front = last = 0;
    bool vis[MAX][MAX] = { false };
    pair<pii, int> q[MAX * MAX] = {};
    q[last] = mkpr(mkpr(y, x), 0);  ++last;
    vis[y][x] = true;

    while (last-front)
    {
        pii t = q[front].first;
        int turn = q[front].second;  ++front;
        for (int i = 0; i < 3; ++i)
        {
            int nexty = t.first + dy[i];
            int nextx = t.second + dx[i];
            if (map[nexty][nextx] == FLO)
                return turn + 1;
            else if (!vis[nexty][nextx])
            {
                vis[nexty][nextx] = true;
                q[last] = mkpr(mkpr(nexty, nextx), turn + 1);  ++last;
            }
        }
    }
    return -1;
}
void calcNumCar(int y, int x, int s)
{
    for (int i = y; i < y + s; ++i)
        for (int j = x; j < x + s; ++j)
            ++numCar[i][j];
    return;
}
int layCar(int y, int x, int bkup[MAX][MAX] = map)
{
    int add = 0;
    int of = bigCar[y][x];
    for (int i = y; i < y + of; ++i)
        for (int j = x; j < x +of; ++j)
        {
            bkup[i][j] = map[i][j];
            if (map[i][j] == SCR)
            {
                ++add;
                map[i][j] = CAR;
            }
        }
    return add;
}
void copyArray(int y, int x, int bef[MAX][MAX], int aft[MAX][MAX])
{
    int of = bigCar[y][x];
    for (int i = y; i < y + of; ++i)
        for (int j = x; j < x + of; ++j)
            aft[i][j] = bef[i][j];
    return;
}

void dfs(int y, int x, int cost, int remain)
{
    if (cost >= minCost)
        return;
    if (remain)
    {
        if ((cost + 1) >= minCost)
            return;
    }
    else
    {
        minCost = min(minCost, cost);
        return;
    }

    if (!map[y][x] || numCar[y][x] == 1)
    {
        if (x + 1 == w)
            dfs(y + 1, 0, cost, remain);
        else
            dfs(y, x + 1, cost, remain);
        return;
    }

    if (map[y][x] == 2)
    {
        if (x + 1 == w)
            dfs(y + 1, 0, cost, remain);
        else
            dfs(y, x + 1, cost, remain);
    }

    int temp[MAX][MAX];
    int n = layCar(y, x, temp);
    if (!n)  return;
    else
    {
        if (x + 1 == w)
            dfs(y + 1, 0, cost + 1, remain - n);
        else
            dfs(y, x + 1, cost + 1, remain - n);
        copyArray(y, x, temp, map);
    }
    return;
}

int main()
{
    while (cin >> w >> h, w || h)
    {
        int ans = 0;
        int numScr = 0;
        minCost = 0;
        for (int i = 0; i < MAX; ++i)
            for (int j = 0; j < MAX; ++j)
            {
                map[i][j] = FLO;
                numCar[i][j] = 0;
            }
        for (int i = 0; i < h; ++i)
            for (int j = 0; j < w; ++j)
            {
                cin >> map[i][j];
                if (map[i][j] == SCR)
                    ++numScr;
            }
        for (int i = 0; i < h; ++i)
            for (int j = 0; j < w; ++j)
            {
                bigCar[i][j] = calcBigCar(i, j);
                calcNumCar(i, j, bigCar[i][j]);
                if (numCar[i][j] == 1)
                {
                    numScr -= layCar(i, j);
                    ++ans;
                }
            }
        minCost = numScr;
        dfs(0, 0, 0, numScr);
        cout << ans + minCost << endl;
    }
}
accuracy: 1
time_ms: 440
memory_kb: 3140
final_rank: 11

code_snippet: #include <iostream>

using namespace std;

#define MAX 11
#define FLO 0
#define SCR 1
#define CAR 2
#define mkpr make_pair

int map[MAX][MAX];
int bigCar[MAX][MAX];
int numCar[MAX][MAX];
int h, w, minCost;


int calcBigCar(int y, int x)
{
    if (map[y][x] == 0)
        return 0;

    int dx[3] = { 0,1,1 };
    int dy[3] = { 1,1,0 };
    int front, last;
    front = last = 0;
    bool vis[MAX][MAX] = { false };
    pair<pair<int, int>, int> q[MAX * MAX] = {};
    q[last] = mkpr(mkpr(y, x), 0);  ++last;
    vis[y][x] = true;

    while (last-front)
    {
        pair<int, int> t = q[front].first;
        int turn = q[front].second;  ++front;

        for (int i = 0; i < 3; ++i)
        {
            int nexty = t.first + dy[i];
            int nextx = t.second + dx[i];
            if (map[nexty][nextx] == FLO)
                return turn + 1;
            else if (!vis[nexty][nextx])
            {
                vis[nexty][nextx] = true;
                q[last] = mkpr(mkpr(nexty, nextx), turn + 1);  ++last;
            }
        }
    }
    return -1;
}

void calcNumCar(int y, int x, int size)
{
    for (int i = y; i < y + size; ++i)
        for (int j = x; j < x + size; ++j)
            ++numCar[i][j];
    return;
}

int layCar(int y, int x, int temp[MAX][MAX] = map)
{
    int add = 0;
    for (int i = y; i < y + bigCar[y][x]; ++i)
        for (int j = x; j < x + bigCar[y][x]; ++j)
        {
            temp[i][j] = map[i][j];
            if (map[i][j] == SCR)
            {
                ++add;
                map[i][j] = CAR;
            }
        }
    return add;
}

void copyArray(int y, int x, int bef[MAX][MAX], int aft[MAX][MAX])
{
    for (int i = y; i < y+bigCar[y][x]; ++i)
        for (int j = x; j < x+bigCar[y][x]; ++j)
            aft[i][j] = bef[i][j];

    return;
}

void dfs(int y, int x, int cost, int remain)
{
    if (cost >= minCost)
        return;
    if (remain)
    {
        if ((cost + 1) >= minCost)
            return;
    }
    else
    {
        minCost = min(minCost, cost);
        return;
    }
    if (y == h)
        return;
    if (!map[y][x] || numCar[y][x] == 1)
    {
        if (x + 1 == w)
            dfs(y + 1, 0, cost, remain);
        else
            dfs(y, x + 1, cost, remain);
        return;
    }
    
    if (map[y][x] == 2)
    {
        if (x + 1 == w)
            dfs(y + 1, 0, cost, remain);
        else
            dfs(y, x + 1, cost, remain);
    }

    int tempMap[MAX][MAX];
    int covered = layCar(y, x, tempMap);
    if (!covered)
        return;
    else
    {
        if (x + 1 == w)
            dfs(y + 1, 0, cost + 1, remain - covered);
        else
            dfs(y, x + 1, cost + 1, remain - covered);
        copyArray(y, x, tempMap, map);
    }
    return;
}

int main()
{
    while (cin >> w >> h, w || h)
    {
        int ans = 0;
        int numScr = 0;
        minCost = 0;

        for (int i = 0; i < MAX; ++i)
            for (int j = 0; j < MAX; ++j)
            {
                map[i][j] = FLO;
                numCar[i][j] = 0;
            }
        for (int i = 0; i < h; ++i)
            for (int j = 0; j < w; ++j)
            {
                cin >> map[i][j];
                if (map[i][j] == SCR)
                    ++numScr;
            }
        for (int i = 0; i < h; ++i)
            for (int j = 0; j < w; ++j)
            {
                bigCar[i][j] = calcBigCar(i, j);
                calcNumCar(i, j, bigCar[i][j]);
                if (numCar[i][j] == 1)
                {
                    numScr -= layCar(i, j);
                    ++ans;
                }
            }
        minCost = numScr;
        dfs(0, 0, 0, numScr);

        cout << ans + minCost << endl;
    }
}
accuracy: 1
time_ms: 420
memory_kb: 3128
final_rank: 10

code_snippet: #include "iostream"
#include "climits"
#include "list"
#include "queue"
#include "stack"
#include "set"
#include "functional"
#include "algorithm"
#include "string"
#include "map"
#include "unordered_map"
#include "unordered_set"
#include "iomanip"
#include "cmath"
#include "random"
#include "bitset"
#include "cstdio"
#include "numeric"
#include "cassert"
#include "ctime"
#include "complex"

using namespace std;

constexpr long long int MOD = 1000000007;
//constexpr int MOD = 1000000007;
//constexpr int MOD = 998244353;
//constexpr long long int MOD = 998244353;
constexpr double EPS = 1e-12;

//int N, M, K, T, H, W, L, R;
long long int N, M, K, T, H, W, L, R;

void func(vector<vector<int>>v, vector<vector<int>>&w, int y, int x, int score = 0) {
	if (score >= K)return;
	do {
		if (x>=0&&v[y][x])return;
		x++;
		if (x == W) {
			x = 0;
			y++;
		}
	}while(y < H && (w[y][x] == 0));
	if (y == H) {
		K = min(K, 0LL + score);
		return;
	}
	if (v[y][x] == 0)func(v, w, y, x, score);
	for (int i = y; i < y + w[y][x]; i++) {
		for (int j = x; j < x + w[y][x]; j++) {
			v[i][j] = 0;
		}
	}
	func(v, w, y, x, score + 1);
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	while (cin >> W >> H, H) {
		vector<vector<int>>v(H, vector<int>(W));
		vector<vector<int>>num(H, vector<int>(W));
		for (auto &i : v)for (auto &j : i)cin >> j;
		for (int i = 0; i < H; i++) {
			for (int j = 0; j < W; j++) {
				for (int k = 1; k <= H - i && k <= W - j; k++) {
					bool ok = true;
					for (int l = i; l < i + k; l++) {
						for (int m = j; m < j + k; m++) {
							if (v[l][m] == 0)ok = false;
						}
					}
					if (ok)num[i][j] = k;
				}
			}
		}
		for (int i = H - 1; i >= 0; i--) {
			for (int j = W - 1; j >= 0; j--) {
				if (i) {
					if (num[i - 1][j] > num[i][j])num[i][j] = 0;
					if (j) {
						if (num[i - 1][j - 1] > num[i][j])num[i][j] = 0;
					}
				}
				if (j) {
					if (num[i][j - 1] > num[i][j])num[i][j] = 0;
				}
			}
		}
		vector<vector<int>>sum(H, vector<int>(W));
		for (int i = 0; i < H; i++) {
			for (int j = 0; j < W; j++) {
				for (int k = i; k <i+ num[i][j]; k++) {
					for (int l = j; l < j + num[i][j]; l++) {
						sum[k][l]++;
					}
				}
			}
		}
		int add = 0;
		for (int i = 0; i < H; i++) {
			for (int j = 0; j < W; j++) {
				bool flag = false;
				for (int k = i; k <i + num[i][j]; k++) {
					for (int l = j; l < j + num[i][j]; l++) {
						if (sum[k][l] == 1) {
							flag = true;
						}
					}
				}
				if (flag) {
					add++;
					for (int k = i; k <i + num[i][j]; k++) {
						for (int l = j; l < j + num[i][j]; l++) {
							v[k][l] = 0;
						}
					}
					num[i][j] = 0;
				}
			}
		}
		K = MOD;
		func(v, num, 0, -1);
		cout << K +add<< endl;
	}
}
accuracy: 1
time_ms: 960
memory_kb: 3432
final_rank: 19

code_snippet: // 利用估价函数进行剪枝
// RE了一发，原因：未特判todo空的情况。 
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <utility>
#include <queue>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ldouble;
const int LEN = 100000;

struct fastio {
  int it, len;
  char s[LEN + 5];
  fastio() {
    it = len = 0;
  }
  char get() {
    if (it < len) return s[it++];
    it = 0, len = fread(s, 1, LEN, stdin);
    return len ? s[it++] : EOF;
  }
  bool notend() {
    char c;
    for (c = get(); c == ' ' || c == '\n' || c == '\r'; c = get());
    if (it) it--;
    return c != EOF;
  }
  void put(char c) {
    if (it == LEN) fwrite(s,1,LEN,stdout), it = 0;
    s[it++] = c;
  }
  void flush() {
    fwrite(s, 1, it, stdout);
  }
}buff, bufo;
inline int getint() {
  char c; int res = 0, sig = 1;
  for (c = buff.get(); c < '0' || c > '9'; c = buff.get()) if(c == '-') sig = -1;
  for (; c >= '0' && c <= '9'; c = buff.get()) res = res * 10 + (c - '0');
  return sig * res;
}
inline ll getll() {
  char c; ll res = 0, sig = 1;
  for (c = buff.get(); c < '0' || c > '9'; c = buff.get()) if (c == '-') sig = -1;
  for (; c >= '0' && c <= '9'; c = buff.get()) res = res * 10 + (c - '0');
  return sig * res;
}
inline void putint(int x, char suf) {
  if (!x) bufo.put('0');
  else {
    if (x < 0) bufo.put('-'), x = -x;
    int k = 0; char s[15];
    while (x) {
      s[++k] = x % 10 + '0';
      x /= 10;
    }
    for (; k; k--) bufo.put(s[k]);
  }
  bufo.put(suf);
}
inline void putll(ll x, char suf) {
  if (!x) bufo.put('0');
  else {
    if (x < 0) bufo.put('-'), x = -x;
    int k = 0; char s[25];
    while (x) {
      s[++k] = x % 10 + '0';
      x /= 10;
    }
    for (; k; k--) bufo.put(s[k]);
  }
  bufo.put(suf);
}
inline char get_char() {
  char c;
  for (c = buff.get(); c == ' ' || c == '\n' || c == '\r'; c = buff.get());
  return c;
}
template<class T> bool chmin(T &x, T y) {
  return x > y ? (x = y, true) : false;
}
template<class T> bool chmax(T &x, T y) {
  return x < y ? (x = y, true) : false;
}

#define maxn 15
#define mp make_pair
typedef pair<int, int> P;
const int inf = 0x3f3f3f3f;
int w, h, len[maxn][maxn], p[maxn][maxn];

bool check(int x, int y, int l) {
  for (int i = 0; i < l; i++)
    for (int j = 0; j < l; j++) if (!p[x + i][y + j]) return false;
  return true;
}

vector<P> todo; // {(i, j)|p[i][j] = 1}
int ans, cover[maxn][maxn];

int hstar(int id, int r) { // 还剩r个格子没覆盖
  int maxi = 0;
  for (int i = id; i < (int)todo.size(); i++) {
    chmax(maxi, len[todo[i].first][todo[i].second]);
  }
  maxi *= maxi;
  return (r + maxi - 1) / maxi - 1;
}

void dfs(int cur, int r, int id) {
  if (cur + hstar(id, r) >= ans) return; // 最优性剪枝1 
  // 目前(连todo[id])铺了cur块，(不连todo[id])还剩r个格子没覆盖，
  // 现在考虑(必选的)todo[id]
  int x = todo[id].first, y = todo[id].second;
  for (int i = 0; i < len[x][y]; i++) {
    for (int j = 0; j < len[x][y]; j++) {
      r -= !cover[x + i][y + j];
      cover[x + i][y + j]++;
    }
  }
  int nxt;
  for (nxt = id + 1; nxt < (int)todo.size(); nxt++) {
    int cx = todo[nxt].first, cy = todo[nxt].second;
    if (!cover[cx][cy]) break; // 可行性剪枝 
  }
  if (nxt == (int)todo.size()) {
    chmin(ans, cur);
  } else {
    for (; nxt > id; nxt--) { // 调整搜索顺序 
      bool useful = false;
      int cx = todo[nxt].first, cy = todo[nxt].second;
      for (int j = 0; j < len[cx][cy]; j++) {
        for (int k = 0; k < len[cx][cy]; k++) {
          if (!cover[cx + j][cy + k]) useful = true;
        }
      }
      if (useful) dfs(cur + 1, r, nxt); // 最优性剪枝2 
    }
  }
  for (int i = 0; i < len[x][y]; i++) {
    for (int j = 0; j < len[x][y]; j++) {
      cover[x + i][y + j]--;
      r += !cover[x + i][y + j];
    }
  }
}

void solve() {
  memset(p, 0, sizeof(p));
  memset(len, 0, sizeof(len));
  todo.clear();
  for (int i = 1; i <= h; i++) {
    for (int j = 1; j <= w; j++) {
      if (p[i][j] = getint()) todo.push_back(mp(i, j));
    }
  }
  for (int i = 1; i <= h; i++) {
    for (int j = 1; j <= w; j++) {
      while (check(i, j, len[i][j] + 1)) len[i][j]++;
    }
  }
  for (int i = todo.size() - 1; i >= 0; i--) { // 最优性剪枝3 
    for (int j = i + 1; j < (int)todo.size(); j++) {
      int xi = todo[i].first, yi = todo[i].second,
          xj = todo[j].first, yj = todo[j].second;
      if (yi <= yj && len[xi][yi] - len[xj][yj] >= max(yj - yi, xj - xi))
        len[xj][yj] = 1;
    }
  }
  if (todo.empty()) {
    putint(0, '\n');
    return;
  }
  ans = inf;
  memset(cover, 0, sizeof(cover)); 
  dfs(1, todo.size(), 0);
  putint(ans, '\n');
}

int main() {
//  freopen("sample.in", "r", stdin);
//  freopen("sample.out", "w", stdout); 
  while ((w = getint()) && (h = getint())) solve();
  bufo.flush();
  return 0;
}
accuracy: 1
time_ms: 230
memory_kb: 3104
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return true; } return false; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return true; } return false; }
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define mp make_pair
#define si(x) int(x.size())
const int mod=1000000007,MAX=1005;
const int INF=1e6;
//const ll INF=1LL<<60;

map<vector<vector<int>>,int> MA;

vector<vector<int>> S(10,vector<int>(10));
int ma[12][12],must[12][12];
int H,W;

int ans=INF;

void DFS(int h,int w,int sum){
    
    if(sum>=ans) return;
    
    if(MA.count(S)&&MA[S]<=sum) return;
    
    if(must[h][w]){
        if(sum+1>=ans) return;
        
        vector<pair<int,int>> Q;
        
        for(int a=h;a<h+ma[h][w];a++){
            for(int b=w;b<w+ma[h][w];b++){
                if(S[a][b]){
                    Q.push_back(mp(a,b));
                    S[a][b]=0;
                }
            }
        }
        if(w==W-1) DFS(h+1,0,sum+1);
        else DFS(h,w+1,sum+1);
        
        for(auto x:Q) S[x.fi][x.se]=1;
        
        return ;
    }
    
    int sh=h,sw=w;
    
    while(h<H){
        while(w<W&&S[h][w]==0) w++;
        if(w==W){
            h++;
            w=0;
        }else break;
    }
    if(h==H){
        chmin(ans,sum);
        return;
    }
    
    swap(h,sh);
    swap(w,sw);
    
    int change=0;
    for(int a=h;a<h+ma[h][w];a++){
        for(int b=w;b<w+ma[h][w];b++){
            if(S[a][b]){
                change++;
                break;
            }
        }
        if(change) break;
    }
    
    if(change==0){
        if(w==W-1) DFS(h+1,0,sum);
        else DFS(h,w+1,sum);
    }else if(S[h][w]){
        if(sum+1>=ans) return;
        
        vector<pair<int,int>> Q;
        
        for(int a=h;a<h+ma[h][w];a++){
            for(int b=w;b<w+ma[h][w];b++){
                if(S[a][b]){
                    Q.push_back(mp(a,b));
                    S[a][b]=0;
                }
            }
        }
        if(w==W-1) DFS(h+1,0,sum+1);
        else DFS(h,w+1,sum+1);
        
        for(auto x:Q) S[x.fi][x.se]=1;
    }else{
        if(w==W-1) DFS(h+1,0,sum);
        else DFS(h,w+1,sum);
        
        vector<pair<int,int>> Q;
        
        for(int a=h;a<h+ma[h][w];a++){
            for(int b=w;b<w+ma[h][w];b++){
                if(S[a][b]){
                    Q.push_back(mp(a,b));
                    S[a][b]=0;
                }
            }
        }
        if(w==W-1) DFS(h+1,0,sum+1);
        else DFS(h,w+1,sum+1);
        
        for(auto x:Q) S[x.fi][x.se]=1;
    }
    
    MA[S]=sum;
}

int main(){
    
    std::ifstream in("text.txt");
    std::cin.rdbuf(in.rdbuf());
    cin.tie(0);
    ios::sync_with_stdio(false);
    
    while(1){
        cin>>W>>H;
        if(H==0) break;
        memset(ma,0,sizeof(ma));
        memset(must,0,sizeof(must));
        ans=INF;
        for(int i=0;i<10;i++) for(int j=0;j<10;j++) S[i][j]=0;
        MA.clear();
        for(int i=0;i<H;i++) for(int j=0;j<W;j++) {cin>>S[i][j];}
        
        for(int i=0;i<H;i++){
            for(int j=0;j<W;j++){
                for(int k=1;k<=max(H-i,W-j);k++){
                    int cnt=0;
                    
                    for(int a=i;a<i+k;a++){
                        for(int b=j;b<j+k;b++){
                            if(a<H&&b<W&&S[a][b]) cnt++;
                        }
                    }
                    
                    if(cnt==k*k){
                        ma[i][j]=k;
                    }
                }
                
                int k=ma[i][j];
                
                for(int a=i;a<i+k;a++){
                    for(int b=j;b<j+k;b++){
                        must[a][b]++;
                    }
                }
            }
        }
        
        for(int i=0;i<H;i++){
            for(int j=0;j<W;j++){
                if(must[i][j]!=1) must[i][j]=0;
            }
        }
        
        DFS(0,0,0);
        
        cout<<ans<<endl;
    }
}
accuracy: 1
time_ms: 350
memory_kb: 4216
final_rank: 16

code_snippet: #include <bits/stdc++.h>
#define FOR(i,k,n) for(int i=(k);i<(int)(n);++i)
#define REP(i,n) FOR(i,0,n)
#define ALL(x) begin(x),end(x)
using namespace std;
using ll = int64_t;

int solve(const vector<bitset<100>>& v, const bitset<100>& rem) {
  if (rem.none()) return 0;
  bitset<100> b;
  int mx = 0;
  vector<int> cnt(100, 0);
  for(auto&& t : v) {
    int n = (rem & t).count();
    if (n > mx) {
      b = t;
      mx = n;
    }
    REP(i,100) {
      if (t[i]) ++cnt[i];
    }
  }
  set<int> s;
  REP(i,100) {
    if (rem[i]) {
      if (cnt[i] == 0) return 10000;
      if (cnt[i] == 1) s.insert(i);
    }
  }
  if (s.empty()) {
    vector<bitset<100>> tmp;
    for(auto&& t : v) {
      if (t != b) tmp.push_back(t);
    }
    return min(solve(tmp, rem & ~b) + 1, solve(tmp, rem));
  } else {
    vector<bitset<100>> tmp;
    bitset<100> next = rem;
    for(auto&& t : v) {
      bool use = false;
      for(auto&& i : s) {
        if (t[i]) {
          next &= ~t;
          use = true;
          break;
        }
      }
      if (use) continue;
      tmp.push_back(t);
    }
    return solve(tmp, next) + (v.size() - tmp.size());
  }
}

int main() {
  while(1) {
    int w,h;
    cin>>w>>h;
    if (!w) break;
    vector<vector<int>> t(h, vector<int>(w));
    REP(i,h)REP(j,w) cin>>t[i][j];
    REP(i,h)REP(j,w) {
      int m=min(h-i, w-j);
      FOR(k,1,m+1) {
        bool ok = true;
        REP(p,k)REP(q,k) {
          if (t[i+p][j+q]==0) ok=false;
        }
        if (ok) t[i][j] = k;
      }
    }
    vector<vector<bool>> maxi(h, vector<bool>(w, true));
    REP(i,h)REP(j,w) {
      if (t[i][j] == 0) maxi[i][j] = false;
      REP(p,i+1)REP(q,j+1) {
        if (p==i && q==j) continue;
        int d=max(i-p,j-q);
        if (t[p][q] >= t[i][j] + d) maxi[i][j] = false;
      }
    }
    vector<bitset<100>> v;
    REP(i,h)REP(j,w) {
      if (maxi[i][j]) {
        bitset<100> b;
        REP(p,t[i][j])REP(q,t[i][j]) {
          b[(i+p)*10+(j+q)] = true;
        }
        v.push_back(b);
      }
    }
    bitset<100> rem;
    REP(i,h)REP(j,w) {
      if (t[i][j]) rem[i*10+j] = true;
    }
    cout << solve(v, rem) << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 750
memory_kb: 3064
final_rank: 18

code_snippet: #include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<utility>
#include<stack>
#include<bitset>
#include<map>
#include<numeric>
#include<unordered_map>
using namespace std;
typedef long long ll;
#define rep(i,n) for(int i=0;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define stop char nyaa;cin>>nyaa;
const ll mod = 1000000007;
const long double eps = 1e-8;
typedef pair<ll, ll> LP;

#define int short int
typedef pair<int, int> P;

typedef long double ld;

int h, w;

typedef pair<vector<int>, P> speP;

void solve() {
	vector<vector<int>> v(h),sz;
	map<speP, bool> mp;
	sz.resize(h);
	rep(i, h) {
		v[i].resize(w); sz[i].resize(w,0);
		rep(j, w)cin >> v[i][j];
	}
	rep(i, h) {
		rep(j, w) {
			if (v[i][j] == 0)continue;
			rep1(k, 11) {
				bool f = true;
				Rep(x, i, i + k) {
					Rep(y, j, j + k) {
						if (x >= h || y >= w) {
							f = false; break;
						}
						if (v[x][y] == 0) {
							f = false; break;
						}
					}
				}
				if (f) {
					sz[i][j] = k;
				}
				else break;
			}
		}
	}
	vector<int> sta;
	rep(i, h)rep(j, w)sta.push_back(v[i][j]);
	deque<speP> q;
	map<speP, int> ans;
	q.push_back({ sta,{0,0} }); ans[{sta, { 0,0 }}] = 0; mp[{sta, { 0,0 }}] = true;
	while (!q.empty()) {
			speP p = q.front(); q.pop_front();
			if (p.second == P{ h,0 }) {
				cout << ans[p] << endl; return;
			}
			vector<int> &v = p.first;
			int& x = p.second.first, y = p.second.second;
			//cout << x << " " << y << endl;
			int nd = ans[p];
			int nx = x, ny = y + 1;
			if (ny == w) {
				nx++; ny = 0;
			}
			
			speP nex; nex.second = { nx,ny };
			if (v[x*w+y] == 0) {
				//cout << nx << " " << ny << endl;
				nex.first = v;
				if (!mp[nex]) {
					mp[nex] = true;
					ans[nex] = nd;
					q.push_front(nex);
				}
				else {
					if (nd < ans[nex]) {
						ans[nex] = nd;
						q.push_front(nex);
					}
				}
			}
			else if (v[x*w+y] == 1) {
				int len = sz[x][y];
				Rep(i, x, x + len) {
					Rep(j, y, y + len) {
						v[i*w+j] = 2;
					}
				}
				nex.first = v;
				if (!mp[nex]) {
					mp[nex] = true;
					ans[nex] = nd + 1;
					q.push_back(nex);
				}
			}
			else {
				//non
				nex.first = v;
				if (!mp[nex]) {
					mp[nex] = true;
					ans[nex] = nd;
					q.push_front(nex);
				}
				else {
					if (nd < ans[nex]) {
						ans[nex] = nd;
						q.push_front(nex);
					}
				}
				bool exi = false;
				int len = sz[x][y];
				Rep(i, x, x + len) {
					Rep(j, y, y + len) {
						if (v[i*w+j] != 2)exi = true;
						v[i*w+j] = 2;
					}
				}
				if (exi) {
					nex.first = v;
					if (!mp[nex]) {
						mp[nex] = true;
						ans[nex] = nd+1;
						q.push_back(nex);
					}
				}
			}
	}
	//cout << dfs(v, 0, 0) << endl;
}
signed main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	//string s = "-0=0";
	//cout << valid(s) << endl;
	//cout << fixed << setprecision(10);
	while (cin >> w >> h, w) {
		solve();
		//cout << "end" << endl;
	}
	//solve();
	//stop
		return 0;
}
accuracy: 1
time_ms: 380
memory_kb: 7612
final_rank: 20

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <set>
#include <cstring>
#include <queue>
#include <map>
#include <list>
#include <cmath>
#include <iomanip>
#define INF 0x3f3f3f3f
#define EPS 10e-5

typedef long long ll;
const int dx[]={-1,0,0,1,0},dy[]={0,1,-1,0,0};
using namespace std;
int w,h,ecnt;
int mps[10][10];    // record used square
int cnts[10][10][2];// record the square size
int scts[10][10];
bool badc[10][10];
int upbound,bcnt,mxsqus,res;
bool reach,needf[10][10];

int vps[250];
int vsct[250][250],vl[250];

void dfs(int now,int cost){

    if(ecnt==0) {
        if(cost==res)
            reach = true;
        upbound = min(upbound,cost);
        return;
    }

    if(cost+round(1.0*ecnt/mxsqus)>res||reach) return;

    if(now==bcnt) return;

    bool cover = false;
    int bs = vl[now],*vct=vsct[now];

    for(int i=0;i<bs;++i){
        if(vps[vct[i]]==0){
            cover = true;break;
        }
    }

    if(!cover) {
        return dfs(now+1,cost);
    }

    for(int i=0;i<bs;++i){
        if(++vps[vct[i]]==1) --ecnt;
    }
    dfs(now+1,cost+1);
    for(int i=0;i<bs;++i){
        if(--vps[vct[i]]==0) ++ecnt;
    }

    if(vps[vsct[now][0]]==0) return;
    dfs(now+1,cost);
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    while(scanf("%d%d",&w,&h)){
        if(w==0&&h==0)break;
        memset(mps,0,sizeof(mps));
        memset(cnts,0,sizeof(cnts));
        memset(badc,0,sizeof(badc));
        memset(needf,0,sizeof(needf));
        memset(vl,0,sizeof(vl));

        ecnt = mxsqus = 0;
        int tmp;
        for(int i=0;i<h;++i)
            for(int j=0;j<w;++j){
                scanf("%d",&tmp);
                if(tmp) {
                    mps[i][j] = 1;++ecnt;
                    needf[i][j] = true;
                }
            }
        if(ecnt==0){
            printf("0\n");
            continue;
        }
        for(int i=0;i<w;++i){
            int last = 0;
            for(int j=h-1;j>=0;--j){
                if(mps[j][i]) cnts[j][i][1] = ++last;
                else last = 0;
            }
        }
        for(int i=0;i<h;++i)
        {
            int last = 0;
            for(int j=w-1;j>=0;--j){
                if(mps[i][j]) cnts[i][j][0] = ++last;
                else last = 0;
            }
        }

        for(int i=0;i<h;++i)
            for(int j=0;j<w;++j)
            {
                int k=j,last = INF;
                for(;k<w;++k){
                    last = min(cnts[i][k][1],last);
                    if(k+1-j>last) break;
                }
                mxsqus = max(scts[i][j] = k-j,mxsqus);
            }
        mxsqus*=mxsqus;
        bcnt = 0;

        for(int i=0;i<h;++i)
            for(int j=0;j<w;++j){
                if(badc[i][j]) continue;
                for(int i2=0;i2<scts[i][j];++i2){
                    for(int j2=0;j2<scts[i][j];++j2){
                        if(i2==0&&j2==0) continue;
                        if(scts[i+i2][j+j2]<=min(scts[i][j]-i2,scts[i][j]-j2)){
                            badc[i+i2][j+j2] = true;
                        }
                    }
                }
            }

        for(int i=0;i<h;++i){
            for(int j=0;j<w;++j){
                if(!badc[i][j]){
                    for(int i2=0;i2<scts[i][j];++i2){
                        for(int j2=0;j2<scts[i][j];++j2){
                            vsct[bcnt][vl[bcnt]++] = (i+i2)*w+j+j2;
                        }
                    }
                    bcnt++;
                }
            }
        }

        memset(mps,0,sizeof(mps));
        upbound = INF;
        res = ecnt/mxsqus;reach = false;
        while(!reach&&res!=upbound){
            dfs(0,0);
            ++res;
        }
        printf("%d\n",upbound);
    }
    return 0;
}
accuracy: 1
time_ms: 510
memory_kb: 3452
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define fi first
#define se second
#define dbg(x) cout<<#x" = "<<((x))<<endl
template<class T,class U> ostream& operator<<(ostream& o, const pair<T,U> &p){o<<"("<<p.fi<<","<<p.se<<")";return o;}
template<class T> ostream& operator<<(ostream& o, const vector<T> &v){o<<"[";for(T t:v){o<<t<<",";}o<<"]";return o;}

const int N = 10;
const int INF = 19191919;

int w,h;

int p[N][N];
int sq[N][N];
int need[N][N];
int ct[N][N];

bool can_place(int y, int x, int sz){
    for(int i=y; i<y+sz; ++i)for(int j=x; j<x+sz; ++j)if(!p[i][j]) return false;
    return true;
}

int check_need(int y, int x){
    int LY = y, RY = y+sq[y][x];
    int LX = x, RX = x+sq[y][x];
    rep(i,h)rep(j,w){
        if(i==y && j==x) continue;
        int ly = i, ry = i+sq[i][j];
        int lx = j, rx = j+sq[i][j];
        if(ly<=LY && RY<=ry && lx<=LX && RX<=rx) return 0;
    }
    return 1;
}

int ans;
int now;
bool ret;
void dfs(int y, int x){
    if(y==h-1 && x==w-1){
        rep(i,h)rep(j,w){
            if(p[i][j]){
                if(!ct[i][j]) return;
            }
            else{
                if(ct[i][j]) return;
            }
        }
        ret = true;
        return;
    }

    int ny = y, nx = x+1;
    if(nx==w){
        ++ny;
        nx = 0;
    }

    if(!need[y][x]) dfs(ny,nx);
    else{
        if(!ct[y][x]){
            for(int i=y; i<y+sq[y][x]; ++i)for(int j=x; j<x+sq[y][x]; ++j) ++ct[i][j];
            if(now<ans){
                ++now;
                dfs(ny,nx);
                --now;
            }
            for(int i=y; i<y+sq[y][x]; ++i)for(int j=x; j<x+sq[y][x]; ++j) --ct[i][j];
        }
        else{
            dfs(ny,nx);
            if(ret) return;

            // bool worth = false;
            // for(int i=y; i<y+sq[y][x]; ++i)for(int j=x; j<x+sq[y][x]; ++j){
            //     if(ct[i][j]==0) worth = true;
            // }

            for(int i=y; i<y+sq[y][x]; ++i)for(int j=x; j<x+sq[y][x]; ++j) ++ct[i][j];
            if(now<ans){
                ++now;
                dfs(ny,nx);
                --now;
            }
            for(int i=y; i<y+sq[y][x]; ++i)for(int j=x; j<x+sq[y][x]; ++j) --ct[i][j];
        }
    }
}

int main(){
    while(scanf(" %d %d", &w, &h),w){
        rep(i,h)rep(j,w) scanf(" %d", &p[i][j]);

        memset(sq,0,sizeof(sq));
        rep(i,h)rep(j,w)if(p[i][j]){
            for(int k=min(w-j,h-i); k>=1; --k){
                if(can_place(i,j,k)){
                    sq[i][j] = k;
                    break;
                }
            }
        }

        memset(need,0,sizeof(need));
        rep(i,h)rep(j,w)if(p[i][j]){
            need[i][j] = check_need(i,j);
        }

        memset(ct,0,sizeof(ct));
        int must = 0;
        vector<pair<int,int>> ppp;
        rep(i,h)rep(j,w){
            if(!need[i][j]) continue;

            bool flg = false;
            for(int y=i; y<i+sq[i][j]; ++y)for(int x=j; x<j+sq[i][j]; ++x){
                int covered = 0;
                rep(li,h)rep(lj,w){
                    if(!need[li][lj]) continue;

                    if(li<=y && y<li+sq[li][lj] && lj<=x && x<lj+sq[li][lj]) ++covered;
                }
                if(covered == 1){
                    flg = true;
                    break;
                }
            }

            if(flg){
                ppp.pb({i,j});
                ++must;
                for(int y=i; y<i+sq[i][j]; ++y)for(int x=j; x<j+sq[i][j]; ++x) ++ct[y][x];
            }
        }
        for(const auto &pp:ppp) need[pp.fi][pp.se] = 0;

        // rep(i,h){
        //     rep(j,w) printf(" %d", need[i][j]);
        //     puts("");
        // }

        ans = must;
        while(1){
            // dbg(ans);
            ret = false;
            now = must;
            dfs(0,0);
            if(ret) break;
            ++ans;
        }
        printf("%d\n",ans);
    }
    return 0;
}
accuracy: 1
time_ms: 110
memory_kb: 3224
final_rank: 3

code_snippet: #include <bits/stdc++.h>
#define r(i,n) for(int i=0;i<n;i++)
using namespace std;

int w,h,n,A[11][11],ans,cnt;
bitset<100> B[11][11],p;

void dfs(int d,bitset<100> s,int sco){
  if(d==n){
    ans=min(ans,sco);
    return;
  }
  cnt++;
  if(cnt>=19000000)return;
  if(ans<=sco)return;
  if(!A[d/w][d%w])dfs(d+1,s,sco);
  else{
    int y=d/w;
    int x=d%w;
    if((B[y][x]&s).any()){
      p&=0;
      p.set(y*10+x);//(y*100+x);
      if(!(s&p).any())dfs(d+1,s,sco);
      dfs(d+1,(B[y][x]|s)^B[y][x],sco+1);
    }
    else dfs(d+1,s,sco);
  }
}

int main(){
  while(cin>>w>>h,w){
    memset(A,0,sizeof(A));
    r(i,11)r(j,11)B[i][j]&=0;
    n=h*w;
    bitset<100> b;
    r(i,h)r(j,w)cin>>A[i][j];
    r(i,h)r(j,w)if(A[i][j]){
      int sum=1;
      for(;;sum++){
        int f=0;
        for(int y=i;y<i+sum;y++){
          for(int x=j;x<j+sum;x++){
            if(A[y][x]==0)f++;
          }
        }
        if(f){
          sum--;
          break;
        }
      }
      bitset<100>tmp;
      for(int y=i,k=0;k<sum;k++,y++){
        for(int x=j,l=0;l<sum;l++,x++){
          tmp.set(y*10+x);
        }
      }
      b.set(i*10+j);
      B[i][j]=tmp;
    }
    ans=100;
    cnt=0;
    dfs(0,b,0);
    cout<<ans<<endl;
  }
}
accuracy: 1
time_ms: 400
memory_kb: 3076
final_rank: 8

code_snippet: #include <bits/stdc++.h>
#define r(i,n) for(int i=0;i<n;i++)
using namespace std;

int w,h,n,A[11][11],ans,cnt;
bitset<100> B[11][11],p;

void dfs(int d,bitset<100> s,int sco){
  if(d==n){
    ans=min(ans,sco);
    return;
  }
  cnt++;
  if(cnt>=20000000)return;
  if(ans<=sco)return;
  if(!A[d/w][d%w])dfs(d+1,s,sco);
  else{
    int y=d/w;
    int x=d%w;
    if((B[y][x]&s).any()){
      p&=0;
      p.set(y*10+x);//(y*100+x);
      if(!(s&p).any())dfs(d+1,s,sco);
      dfs(d+1,(B[y][x]|s)^B[y][x],sco+1);
    }
    else dfs(d+1,s,sco);
  }
}

int main(){
  while(cin>>w>>h,w){
    memset(A,0,sizeof(A));
    r(i,11)r(j,11)B[i][j]&=0;
    n=h*w;
    bitset<100> b;
    r(i,h)r(j,w)cin>>A[i][j];
    r(i,h)r(j,w)if(A[i][j]){
      int sum=1;
      for(;;sum++){
        int f=0;
        for(int y=i;y<i+sum;y++){
          for(int x=j;x<j+sum;x++){
            if(A[y][x]==0)f++;
          }
        }
        if(f){
          sum--;
          break;
        }
      }
      bitset<100>tmp;
      for(int y=i,k=0;k<sum;k++,y++){
        for(int x=j,l=0;l<sum;l++,x++){
          tmp.set(y*10+x);
        }
      }
      b.set(i*10+j);
      B[i][j]=tmp;
    }
    ans=100;
    cnt=0;
    dfs(0,b,0);
    cout<<ans<<endl;
  }
}
accuracy: 1
time_ms: 420
memory_kb: 3056
final_rank: 9

code_snippet: #include <bits/stdc++.h>
#define r(i,n) for(int i=0;i<n;i++)
using namespace std;

int w,h,n,A[11][11],ans,cnt;
bitset<100> B[11][11];

void dfs(int d,bitset<100> s,int sco){
  if(d==n){
    ans=min(ans,sco);
    return;
  }
  cnt++;
  if(cnt>=30000000)return;
  if(ans<=sco)return;
  if(!A[d/w][d%w])dfs(d+1,s,sco);
  else{
    int y=d/w;
    int x=d%w;
    if((B[y][x]&s).any()){
      bitset<100>p;
      p.set(y*10+x);//(y*100+x);
      if(!(s&p).any())dfs(d+1,s,sco);
      dfs(d+1,(B[y][x]|s)^B[y][x],sco+1);
    }
    else dfs(d+1,s,sco);
  }
}

int main(){
  while(cin>>w>>h,w){
    memset(A,0,sizeof(A));
    r(i,11)r(j,11)B[i][j]&=0;
    n=h*w;
    bitset<100> b;
    r(i,h)r(j,w)cin>>A[i][j];
    r(i,h)r(j,w)if(A[i][j]){
      int sum=1;
      for(;;sum++){
        int f=0;
        for(int y=i;y<i+sum;y++){
          for(int x=j;x<j+sum;x++){
            if(A[y][x]==0)f++;
          }
        }
        if(f){
          sum--;
          break;
        }
      }
      bitset<100>tmp;
      for(int y=i,k=0;k<sum;k++,y++){
        for(int x=j,l=0;l<sum;l++,x++){
          tmp.set(y*10+x);
        }
      }
      b.set(i*10+j);
      B[i][j]=tmp;
    }
    ans=100;
    cnt=0;
    dfs(0,b,0);
    cout<<ans<<endl;
  }
}
accuracy: 1
time_ms: 550
memory_kb: 3100
final_rank: 14

code_snippet: #include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>

#include <iostream>
#include <complex>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>

#include <random>
#include <functional>
#include <cassert>

typedef long long ll;
using namespace std;

#define debug(x) cerr << __LINE__ << " : " << #x << " = " << (x) << endl;

#define mod 1000000007 //1e9+7(prime number)
#define INF 1000000000 //1e9
#define LLINF 2000000000000000000LL //2e18
#define SIZE 11

#define P3(a,b,c) make_pair(make_pair(a,b),c)

int h, w;
int t[SIZE][SIZE], t2[SIZE][SIZE];
int max_size[11][11] = {};
int covered[11][11] = {};
map<pair<pair<ll,ll>,int>,int> visited;

int ans;

void dfs(int y, int x, int counter = 0, ll hash = 0, ll hash2 = 0){
  //debug(ans);
  int diff[11][11] = {};
  if(ans <= counter) return;
  auto it = visited.find(P3(hash,hash2,y*w+x));
  if(it != visited.end() && it->second <= counter) return;
  
  if(y == h){
    ans = min(ans, counter);
    return;
  }

  if(max_size[y][x] == 0 || covered[y][x])
    dfs(y + (x == w-1), (x + 1)%w, counter, hash, hash2);
  
  if(max_size[y][x] != 0){
    ll newhash = hash, newhash2 = hash2;
    int diffcounter = 0;
    for(int i=0;i<max_size[y][x];i++)
      for(int j=0;j<max_size[y][x];j++)
        if(covered[y+i][x+j] == 0){
          diff[y+i][x+j] = covered[y+i][x+j] = 1;
          newhash ^= t[y+i][x+j];
          newhash2 ^= t2[y+i][x+j];
          diffcounter++;
        }

    if(diffcounter)
      dfs(y + (x == w-1), (x + 1)%w, counter+1, newhash, newhash2);

    for(int i=0;i<max_size[y][x];i++)
      for(int j=0;j<max_size[y][x];j++)
        if(diff[y+i][x+j] == 1){
          covered[y+i][x+j] = 0;
        }
  }
  
  visited[P3(hash,hash2,y*w+x)] = counter;
}

bool solve(){
  int sp[11][11] = {};
  int p[11][11];
  //debug(clock());
  
  scanf("%d%d", &w, &h);

  if(h == 0) return false;


  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      scanf("%d", p[i]+j);
      sp[i][j] = p[i][j];
    }
  }

  for(int i=h;i>0;i--)
    for(int j=0;j<=w;j++)
      sp[i-1][j] += sp[i][j];

  for(int i=0;i<=h;i++)
    for(int j=w;j>0;j--)
      sp[i][j-1] += sp[i][j];


  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      int p = min(h-i, w-j);
      max_size[i][j] = 0;
      for(int k=1;k<=p;k++){
        if(sp[i][j] + sp[i+k][j+k] - sp[i+k][j] - sp[i][j+k] == k*k) max_size[i][j] = k;
        //debug(sp[i][j] + sp[i+k][j+k] - sp[i+k][j] - sp[i][j+k]);
      }
      //debug(max_size[i][j]);
    }
  }

  //debug(clock());

  visited = map<pair<pair<ll,ll>,int>,int >();
  ans = INF;
  dfs(0,0,0,0,0);
  printf("%d\n", ans);

  return true;
}

int main(){
  std::random_device rd;
  for(int i=0;i<10;i++){
    for(int j=0;j<10;j++){
      t[i][j] = ((ll)rd() << 32) + rd(); 
      t2[i][j] = ((ll)rd() << 32) + rd(); 
    }
  }

  //debug(clock());
  
  while(solve());
  
  return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3936
final_rank: 5

code_snippet: #include <iostream>
#include <algorithm>
#include <map>
#include <tuple>
using namespace std;

struct State {
	int a[10][10];
};

char c[10][10]; int p[10][10], H, W, mindep, cnts;

int range(int sx, int sy, int gx, int gy) {
	int cnt = 0;
	for (int i = sx; i < gx; i++) {
		for (int j = sy; j < gy; j++) {
			if (c[i][j] == '0') cnt++;
		}
	}
	return cnt;
}
int range2(int sx, int sy, int gx, int gy, State G) {
	int cnt = 0;
	for (int i = sx; i < gx; i++) { if (G.a[i][sy] == 0) cnt++; }
	for (int i = sy; i < gy; i++) { if (G.a[sx][i] == 0) cnt++; }
	return cnt;
}

State nurie(State P, int cx, int cy) {
	for (int i = cx; i < cx + p[cx][cy]; i++) {
		for (int j = cy; j < cy + p[cx][cy]; j++) P.a[i][j] = 1;
	}
	return P;
}

long long hash_value(State I) {
	long long mod = 2555555555555555555LL, II = 0, J = 1;
	for (int i = 0; i < H; i++) {
		for (int j = 0; j < W; j++) {
			if (I.a[i][j] == 1) II += J; J *= 2;
			if (II >= mod) II -= mod;
			if (J >= mod) J -= mod;
		}
	}
	return II;
}

map<tuple<int, int, int, long long>, int>M;

void dfs(int cx, int cy, int depth, State S) {
	long long K = hash_value(S);
	if (M[make_tuple(cx, cy, depth, K)] == 1) return;
	M[make_tuple(cx, cy, depth, K)] = 1;
	cnts++;
	if (depth == mindep) return;
	if (cx == H) {
		mindep = min(mindep, depth);
		return;
	}
	int nx = cx, ny = cy + 1; if (ny == W) { ny = 0; nx++; }
	if (c[cx][cy] == '0') {
		dfs(nx, ny, depth, S);
	}
	else {
		if (S.a[cx][cy] == 0) {
			State V = nurie(S, cx, cy);
			dfs(nx, ny, depth + 1, V);
		}
		else if (range2(cx, cy, cx + p[cx][cy], cy + p[cx][cy], S) == 0) {
			dfs(nx, ny, depth, S);
		}
		else {
			dfs(nx, ny, depth, S);
			State V = nurie(S, cx, cy);
			dfs(nx, ny, depth + 1, V);
		}
	}
}

int main() {
	while (true) {
		cin >> W >> H; M.clear(); mindep = (1 << 30); if (H == 0 && W == 0) break;
		for (int i = 0; i < H; i++) {
			for (int j = 0; j < W; j++) cin >> c[i][j];
		}
		for (int i = 0; i < H; i++) {
			for (int j = 0; j < W; j++) {
				for (int k = 1; k <= min(H - i, W - j); k++) {
					if (range(i, j, i + k, j + k) >= 1) break;
					p[i][j] = k;
				}
			}
		}
		State S; for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) S.a[i][j] = 0; }
		dfs(0, 0, 0, S);
		cout << mindep << endl;
	}
	//cout << "Totalcount : " << cnts << endl;
	return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 5228
final_rank: 15

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

const int INF = 1e9;

int w, h;
int A[10][10], B[10][10], used[10][10][10][10];

int update(int y, int x){
  
  if( A[y][x] == 0 ) return 0;
  
  for(int i=y;i<h;i++)
    for(int j=x;j<w;j++) used[y][x][i][j] = 0;
  
  int L;
  
  for(int l=min(h-y-1, w-x-1);l>=0;l--){

    int flag = 1, cnt = 0;
    
    for(int i=y;i<=y+l;i++){
      
      for(int j=x;j<=x+l;j++){
	
	if( A[i][j] == 0 ) flag = 0;
	if( B[i][j] ) cnt++;
	
	if( !flag ) break;
	
      }
      
      if( !flag ) break;
      
    }
    
    if( flag ){
      
      if( cnt == 0 ) return 0;
      L = l;
      
      break;
    }
    
  }
  
  for(int i=y;i<=y+L;i++){
    for(int j=x;j<=x+L;j++){
      used[y][x][i][j] = B[i][j];
      B[i][j] = 0;
    }
  }
  
  return 1;
}

void add(int y, int x){
  
  for(int i=y;i<h;i++)
    for(int j=x;j<w;j++) B[i][j] += used[y][x][i][j];
  
}

typedef unsigned long long ull;

map<ull,int> memo[10][10];

ull Hash(int y, int x){
  
  ull res = 0;
  ull base = 1777771;
  
  for(int i=y;i<h;i++){
    int s = 0;
    if( i == y ) s = x;
    for(int j=s;j<w;j++){
      res = res * base + ( B[i][j] + 1 );
    }
  }
  
  return res;
}

int dfs(int y, int x){

  if( y == h - 1 && x == w - 1 ) return B[y][x];
  
  ull H = Hash( y, x );
  
  if( memo[y][x].count( H ) ) return memo[y][x][H];
  
  int res = INF;
  
  int ny = y, nx = x + 1;
  if( nx == w ) ny++, nx = 0;
  
  if( B[y][x] == 0 ) res = dfs( ny, nx );
  
  int r = update( y, x );
  
  res = min( res, r + dfs( ny, nx ) );
  
  add( y, x );
  
  return memo[y][x][H] = res;
}

signed main(){

  while(1){
    
    cin>>w>>h;
    if( !w && !h ) break;
    
    for(int i=0;i<h;i++)
      for(int j=0;j<w;j++) memo[i][j].clear();
    
    memset(used,0,sizeof(used));
    
    for(int i=0;i<h;i++){
      for(int j=0;j<w;j++){
	cin>>A[i][j];
	B[i][j] = A[i][j];
      }
    }
  
    cout << dfs( 0, 0 ) << endl;
  
  }
  
  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3700
final_rank: 4

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;
Int w,h;
Int cnt,sum,ans,tmp;
Int a[20][20];
Int us[20][20];
Int dp[20][20];
Int pn[20][20];
void inc(Int y,Int x){
  cnt+=!us[y][x];
  us[y][x]++;
}
void dec(Int y,Int x){
  us[y][x]--;
  cnt-=!us[y][x];
}
void show(){
  cout<<cnt<<" "<<sum<<":"<<tmp<<endl;
  for(Int i=0;i<h;i++)
    for(Int j=0;j<w;j++)
      cout<<us[i][j]<<" \n"[j==w-1];
  cout<<endl;
}

void dfs(Int y,Int x){
  Int ny=y+(x+1)/w,nx=(x+1)%w;
  if(ny==h||tmp+1>=ans) return;
  
  if(us[y][x]) dfs(ny,nx);
  if(!dp[y][x]) return;
  
  Int bc=cnt,k=dp[y][x];
  for(Int i=0;i<k;i++)
    for(Int j=0;j<k;j++)
      inc(y+i,x+j);

  if(bc<cnt){
    tmp++;
    if(cnt==sum) ans=min(ans,tmp);
    else if(tmp+1<ans)  dfs(ny,nx);
    tmp--;
  }
  
  for(Int i=0;i<k;i++)
    for(Int j=0;j<k;j++)
      dec(y+i,x+j);
}

signed main(){
  while(cin>>w>>h,w){
    
    cnt=sum=0;
    memset(a,0,sizeof(a));
    memset(us,0,sizeof(us));
    for(Int i=0;i<h;i++){
      for(Int j=0;j<w;j++){
	cin>>a[i][j];
	sum+=a[i][j];
	us[i][j]=!a[i][j];
      }
    }
    
    memset(dp,0,sizeof(dp));
    for(Int i=h-1;i>=0;i--)
      for(Int j=w-1;j>=0;j--)
	dp[i][j]=a[i][j]*(min({dp[i][j+1],dp[i+1][j],dp[i+1][j+1]})+1);
    
    for(Int i=h-1;i>=0;i--)
      for(Int j=w-1;j>=0;j--)
	if(dp[i][j]==dp[i+1][j+1]+1)
	  dp[i+1][j+1]=0;
    
    memset(pn,0,sizeof(pn));
    for(Int i=0;i<h;i++)
      for(Int j=0;j<w;j++)
	for(Int k=0;k<dp[i][j];k++)
	  for(Int l=0;l<dp[i][j];l++)
	    pn[i+k][j+l]++;

    Int pre=0;
    for(Int i=0;i<h;i++){
      for(Int j=0;j<w;j++){
	if(dp[i][j]&&pn[i][j]==1){
	  pre++;
	  for(Int k=0;k<dp[i][j];k++)
	    for(Int l=0;l<dp[i][j];l++)
	      inc(i+k,j+l);
	}
      }
    }

    if(0){
      cout<<pre<<" "<<sum<<endl;
      for(Int i=0;i<h;i++)
	for(Int j=0;j<w;j++)
	  cout<<dp[i][j]<<" \n"[j==w-1];
      cout<<flush;

      show();
    }

    ans=w*h*(cnt!=sum);tmp=0;
    dfs(0,0);
    
    cout<<pre+ans<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 510
memory_kb: 3032
final_rank: 13

code_snippet: #include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#include<map>
#define MAX_W 10
#define INF 1E9

using namespace std;
typedef unsigned long long ull;

const ull B = 100000007;
int w, h; 
int s[MAX_W][MAX_W]; //可延伸的最大正方形邊長
int contain[MAX_W][MAX_W];
bool same[MAX_W][MAX_W][MAX_W][MAX_W];
int limit;
int ct;

struct P{
	int x, y, size;
	P() {}
	P(int x, int y, int size) : x(x), y(y), size(size) {}
	bool operator < (const P& other) const{
		return size < other.size;
	}
};
void init(vector<int>& f){
	memset(contain, 0, sizeof(contain));
	memset(same, false, sizeof(same));
	for(int i = 0; i < h; i++){
		for(int j = 0; j < w; j++){
			s[i][j] = (f[i] >> (w - 1 - j)) & 1;
		}
	}
	for(int i = 0; i < h; i++){
		for(int j = 0; j < w; j++){
			for(int k = 0;; k++){
				bool ok = true;
				if(i + k < h && j + k < w){
					for(int l = 0; ok && l <= k; l++){
						if(s[i + k][j + l] == 0 || s[i + l][j + k] == 0) ok = false;
					}
				}else{
					ok = false;
				}
				if(!ok){
					s[i][j] = k;
					break;
				}
			}
			for(int a = 0; a < s[i][j]; a++){
				for(int b = 0; b < s[i][j]; b++){
					contain[i + a][j + b]++;
				}
			}
			for(int a = 0; a < s[i][j] * s[i][j]; a++){
				int x1 = i + a / s[i][j], y1 = j + a % s[i][j];
				for(int b = 0; b < s[i][j] * s[i][j]; b++){
					int x2 = i + b / s[i][j], y2 = j + b % s[i][j];
					same[x1][y1][x2][y2] = same[x2][y2][x1][y1] = true;
				}
			}
		}
	}
}
int hstar(vector<int> f){
	//選取盡量多的點，其中每個集合最多只能有一個點被選中
	vector<P> ps, X;
	for(int i = 0; i < h; i++){
		for(int j = 0; j < w; j++){
			if((f[i] >> (w - 1 - j)) & 1){
				ps.push_back(P(i, j, contain[i][j]));
			}
		}
	}
	sort(ps.begin(), ps.end());
	for(int i = 0; i < ps.size(); i++){
		bool ok = true;
		int x1 = ps[i].x, y1 = ps[i].y;
		for(int j = 0; j < X.size() && ok; j++){
			int x2 = X[j].x, y2 = X[j].y;
			if(same[x1][y1][x2][y2]) ok = false;
		}
		if(ok) X.push_back(ps[i]);
	}
	return X.size();
}
int dfs(int num, vector<int> f, int idx){
	if(num + hstar(f) > limit) return INF;
	
	ct++;
	vector<int> reset(f.begin(), f.end());
	for(; idx < w * h; idx++){
		int i = idx / w, j = idx % w;
		int k = s[i][j];
		if(k > 0){
			int tmp = ((1 << k) - 1) << (w - j - k), n = 0;
			for(int m = 0; m < k; m++){
				if((f[i + m] & (~tmp)) == f[i + m]) n++;
				f[i + m] &= ~tmp;
			}
			if(n < k){
				if(dfs(num + 1, f, idx + 1) < INF) return num;
			}
			for(int m = 0; m < k; m++) f[i + m] = reset[i + m];
			if(((f[i] >> (w - 1 - j)) & 1) && n < k) break;
		}
	}	
	bool check = true;
	for(int i = 0; i < h && check; i++) check &= (f[i] == 0);
	return (check ? num : INF);
}
int solve(vector<int>& f){
	init(f);
	ct = 0;
	for(limit = hstar(f);; limit++){
		if(dfs(0, f, 0) < INF) return limit;
	}
}
int main(){
	while(cin >> w >> h && (w || h)){
		vector<int> f(h, 0);
		for(int i = 0; i < h; i++){
			f[i] = 0;
			int a;
			for(int j = 0; j < w; j++){
				cin >> a;
				f[i] = (f[i] << 1) | a;
			}
		}
		cout << solve(f) << endl;
		// cout << "ct = " << ct << "\n\n";
	}
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3104
final_rank: 2

code_snippet: #include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#include<unordered_map>
#include<map>
#define MAX_W 10
#define INF 1E9

using namespace std;
typedef unsigned long long ull;

const ull B = 100000007;
int w, h; 
int s[MAX_W][MAX_W]; //可延伸的最大正方形邊長
int contain[MAX_W][MAX_W];
bool same[MAX_W][MAX_W][MAX_W][MAX_W];
int limit;
int ct;
unordered_map<ull, int> mp;

struct P{
	int x, y, size;
	P() {}
	P(int x, int y, int size) : x(x), y(y), size(size) {}
	bool operator < (const P& other) const{
		return size < other.size;
	}
};
void show(vector<int>& cover){
	for(int i = 0; i < h; i++){
		for(int j = 0; j < w; j++){
			printf("%d ", (cover[i] >> (w - 1 - j)) & 1);
		}
		cout << endl;
	}
	cout << endl;
}
void init(vector<int>& f){
	memset(contain, 0, sizeof(contain));
	memset(same, false, sizeof(same));
	for(int i = 0; i < h; i++){
		for(int j = 0; j < w; j++){
			s[i][j] = (f[i] >> (w - 1 - j)) & 1;
		}
	}
	for(int i = 0; i < h; i++){
		for(int j = 0; j < w; j++){
			for(int k = 0;; k++){
				bool ok = true;
				if(i + k < h && j + k < w){
					for(int l = 0; ok && l <= k; l++){
						if(s[i + k][j + l] == 0 || s[i + l][j + k] == 0) ok = false;
					}
				}else{
					ok = false;
				}
				if(!ok){
					s[i][j] = k;
					break;
				}
			}
			for(int a = 0; a < s[i][j]; a++){
				for(int b = 0; b < s[i][j]; b++){
					contain[i + a][j + b]++;
				}
			}
			for(int a = 0; a < s[i][j] * s[i][j]; a++){
				int x1 = i + a / s[i][j], y1 = j + a % s[i][j];
				for(int b = 0; b < s[i][j] * s[i][j]; b++){
					int x2 = i + b / s[i][j], y2 = j + b % s[i][j];
					same[x1][y1][x2][y2] = same[x2][y2][x1][y1] = true;
				}
			}
		}
	}
}
ull calc_hash(vector<int>& f){
	ull t = 0;
	for(int i = 0; i < f.size(); i++){
		t = t * B + f[i];
	}
	return t;
}
int greedy(vector<int> f){
	int res = 0;
	bool update;
	do{
		update = false;
		int m_i, m_j, max = 0;
		for(int i = 0; i < h; i++){
			for(int j = 0; j < w; j++){
				if(s[i][j] > 0){
					int tmp = 0, m = ((1 << s[i][j]) - 1) <<  (w - j - s[i][j]);
					for(int k = 0; k < s[i][j]; k++){
						tmp += __builtin_popcount(f[i + k] & m);
					}
					if(max < tmp){
						max = tmp;
						m_i = i, m_j = j;
					}
				}
			}
		}
		if(max > 0){
			int m = ((1 << s[m_i][m_j]) - 1) << (w - m_j - s[m_i][m_j]);
			for(int i = 0; i < s[m_i][m_j]; i++) f[m_i + i] &= ~m;
			res++;
			update = true;
		}
	}while(update);
	return res;
}
int hstar(vector<int> f){
	//選取盡量多的點，其中每個集合最多只能有一個點被選中
	vector<P> ps, X;
	for(int i = 0; i < h; i++){
		for(int j = 0; j < w; j++){
			if((f[i] >> (w - 1 - j)) & 1){
				ps.push_back(P(i, j, contain[i][j]));
			}
		}
	}
	sort(ps.begin(), ps.end());
	for(int i = 0; i < ps.size(); i++){
		bool ok = true;
		int x1 = ps[i].x, y1 = ps[i].y;
		for(int j = 0; j < X.size() && ok; j++){
			int x2 = X[j].x, y2 = X[j].y;
			if(same[x1][y1][x2][y2]) ok = false;
		}
		if(ok) X.push_back(ps[i]);
	}
	return X.size();
}
int dfs(int num, vector<int> f, int idx){
	if(num + hstar(f) > limit) return INF;
	
	// printf("num = %2d  hstar = %2d   greedy = %2d\n", num,  hstar(f), greedy(f));
	// ull t = calc_hash(f);
	// if(mp.find(t) != mp.end() && mp[t] <= num) return INF;
	// mp[t] = num;
	ct++;
	// if(ct % 10000 == 0) cout << ct << endl;
	
	vector<int> reset(f.begin(), f.end());
	for(; idx < w * h; idx++){
		int i = idx / w, j = idx % w;
		int k = s[i][j];
		if(k > 0){
			int tmp = ((1 << k) - 1) << (w - j - k), n = 0;
			for(int m = 0; m < k; m++){
				if((f[i + m] & (~tmp)) == f[i + m]) n++;
				f[i + m] &= ~tmp;
			}
			if(n < k){
				if(dfs(num + 1, f, idx + 1) < INF) return num;
			}
			//f.assign(reset.begin(), reset.end());
			for(int m = 0; m < k; m++) f[i + m] = reset[i + m];
			if(((f[i] >> (w - 1 - j)) & 1) && n < k) break;
		}
	}	
	bool check = true;
	for(int i = 0; i < h && check; i++) check &= (f[i] == 0);
	return (check ? num : INF);
}
int solve(vector<int>& f){
	init(f);
	ct = 0;
	for(limit = greedy(f);; limit--){
		// printf("limit = %d\n", limit);
		mp.clear();
		if(dfs(0, f, 0) == INF) return limit + 1;
	}
}
int main(){
	while(cin >> w >> h && (w || h)){
		vector<int> f(h, 0);
		for(int i = 0; i < h; i++){
			f[i] = 0;
			int a;
			for(int j = 0; j < w; j++){
				cin >> a;
				f[i] = (f[i] << 1) | a;
			}
		}
		cout << solve(f) << endl;
		// cout << "ct = " << ct << "\n\n";
	}
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3084
final_rank: 1

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


struct Info{
    short table[10][10],num;
};

int W,H,ans,POW[11];
int first_table[10][10],max_size[10][10];


bool rangeCheck(int row,int col){
    if(row >= 0 && row <= H-1 && col >= 0 && col <= W-1)return true;
    else{
        return false;
    }
}

void recursive(Info info,int base_row,int base_col){

    if(info.num == ans)return;

    if(base_row == H){
        ans = info.num;
        return;
    }

    if(info.table[base_row][base_col] == -1){

        if(base_col == W-1){
            recursive(info,base_row+1,0);
        }else{
            recursive(info,base_row,base_col+1);
        }
        return;
    }


    int new_num = 0;
	for(int i = 0; i < max_size[base_row][base_col]; i++){
		for(int k = 0; k < max_size[base_row][base_col]; k++){
			if(info.table[base_row+i][base_col+k] == 0){
				new_num++;
				break;
			}
		}
		if(new_num != 0)break;
	}

    if(new_num == 0){

        if(base_col != W-1){
            recursive(info,base_row,base_col+1);
        }else{
            recursive(info,base_row+1,0);
        }
    }else{

        if(info.table[base_row][base_col] != 0){

            if(base_col != W-1){
                recursive(info,base_row,base_col+1);
            }else{
                recursive(info,base_row+1,0);
            }
        }

        for(int i = 0; i < max_size[base_row][base_col]; i++){
            for(int k = 0; k < max_size[base_row][base_col]; k++){
                info.table[base_row+i][base_col+k]++;
            }
        }

        int must_add = 0;
        bool FLG = false;

        for(int row = base_row; row <= base_row; row++){
            for(int col = base_col; col < W; col++){
               if(info.table[row][col] == 0 && first_table[row][col] > 1){
                    FLG = true;
                    goto SHISHIMARU;
               }
            }
        }

        for(int row = base_row+1; row < H; row++){
            for(int col = 0; col < W; col++){
                if(info.table[row][col] == 0 && first_table[row][col] > 1){
                    FLG = true;
                    goto SHISHIMARU;
                }
            }
        }

SHISHIMARU:

        if(FLG)must_add++;

        info.num++;

        if(info.num+must_add < ans){
            if(base_col != W-1){
                recursive(info,base_row,base_col+1);
            }else{
                recursive(info,base_row+1,0);
            }
        }
    }
}


void func(){

    for(int row = 0; row < H; row++){
        for(int col = 0; col < W; col++){
            scanf("%d",&first_table[row][col]);
            first_table[row][col] -= 1;
        }
    }

    bool FLG;
    int size;

    for(int row = 0; row < H; row++){
        for(int col = 0; col < W; col++){
            if(first_table[row][col] == -1){
                max_size[row][col] = 0;
            }else{
                size = 1;

                FLG = true;

                while(true){
                    for(int i = 0; i < size; i++){
                        for(int k = 0; k < size; k++){
                            if(rangeCheck(row+i,col+k) == false || first_table[row+i][col+k] == -1){
                                FLG = false;
                                break;
                            }
                        }
                        if(!FLG)break;
                    }
                    if(!FLG){
                        size -= 1;
                        break;
                    }
                    size++;
                }

                max_size[row][col] = size;

                for(int calc_size = 1; calc_size <= size; calc_size++){
                    for(int i = 0; i < calc_size; i++){
                        for(int k = 0; k < size; k++){
                            first_table[row+i][col+k]++;
                        }
                    }
                }
            }
        }
    }

    Info start;
    start.num = 0;

    for(int row = 0; row < H; row++){
        for(int col = 0; col < W; col++){
            if(first_table[row][col] == -1){
            	start.table[row][col] = -1;
            }else{
                if(first_table[row][col] == 1){
                	 start.num++;
                	 start.table[row][col] = 1;
                }else{
                     start.table[row][col] = 0;
                }
            }
        }
    }

    ans = BIG_NUM;

    recursive(start,0,0);

    printf("%d\n",ans);
}

int main(){

    for(int i = 0; i < 11; i++)POW[i] = pow(2,i);

    while(true){
        scanf("%d %d",&W,&H);
        if(W == 0 && H == 0)break;

        func();
    }

    return 0;
}
accuracy: 1
time_ms: 430
memory_kb: 3352
final_rank: 12