#include<iostream>
#include<algorithm>
#include<map>
#include<cassert>

using namespace std;
#define rep(i,n) for ( int i = 0; i < n; i++)

#define MAX 15
#define INF (1<<29)
static const int di[9] = {0, 0, -1, -1, -1, 0, 1, 1, 1};
static const int dj[9] = {0, 1, 1, 0, -1, -1, -1, 0, 1};
long long T[17];
int size;

class State{
public:
  int pos;
  long long val;
  State(){ pos = val = 0;}
  bool operator < ( const State &s) const{
    if ( pos != s.pos ) return pos < s.pos;
    return val < s.val;
  }

  int getValue(int i){
    return (val%(T[i+1]))/T[i];
  }
  void setValue(int i, int x){
    val -= getValue(i)*T[i];
    val += x*T[i];
  }
  void inc(int i, int f){
    val += f*T[i];
  }
};

int H, W, dsize;
char M[MAX][MAX]; //map
int I[MAX][MAX]; // index of number P
pair<int, int> D[9*MAX], PI[MAX]; // * for depth
map<State, int> memo;

bool isout(int ni, int nj){
  if (ni < 0 || nj < 0 || H <= ni || W <= nj) return true;
  return I[ni][nj] == -1;
}

int dfs(State &u){
  if ( u.val == 0 ) return memo[u] = 0;
  if ( memo.count(u) ) return  memo[u];
  if ( u.pos >= dsize ) return memo[u] = INF;

  rep(i, size){ // pruning
    if ( PI[i].first + 1 < D[u.pos].first && u.getValue(i) > 0 ) return memo[u] = INF;
    if ( PI[i].first < D[u.pos].first && PI[i].second + 1 < D[u.pos].second && u.getValue(i) > 0 ) return memo[u] = INF;
  }

  int res = INF;

  bool critical = false;
  if ( !isout( D[u.pos].first-1, D[u.pos].second-1 ) ){ // pruning
    if ( u.getValue(I[D[u.pos].first-1][D[u.pos].second-1]) > 0 ) critical = true;
  }
  if ( !isout( D[u.pos].first-1, D[u.pos].second ) ){ // pruning
    if ( D[u.pos].second+1<W && M[D[u.pos].first][D[u.pos].second+1] == '.' ){
      if ( u.getValue(I[D[u.pos].first-1][D[u.pos].second]) > 0 ) critical = true;
    }
  }

  if ( !critical ){
    u.pos++;
    res = dfs(u);
    u.pos--;
    if ( u.val == 0 ) return memo[u] = res;
  }

  rep(r, 9){
    int ni = D[u.pos].first + di[r];
    int nj = D[u.pos].second + dj[r];
    if ( isout(ni, nj) ) continue;
    if ( u.getValue(I[ni][nj]) == 0 ) return memo[u] = res;
  }

  rep(r, 9){
    int ni = D[u.pos].first + di[r];
    int nj = D[u.pos].second + dj[r];
    if ( isout(ni, nj) ) continue;
    u.inc(I[ni][nj], -1);
  }

  u.pos++;
  res = min(res, dfs(u) + 1);
  u.pos--;

  rep(r, 9){
    int ni = D[u.pos].first + di[r];
    int nj = D[u.pos].second + dj[r];
    if ( isout(ni, nj) ) continue;
    u.inc(I[ni][nj], 1);
  }

  return memo[u] = res;
}

main(){
  long long p = 1;
  rep(i, 17) { T[i] = p; p *= 10;};

  while(1){
    cin >> H >> W;
    if ( H == 0 && W == 0 ) break;
    State init;
    size = dsize = 0;
    rep(i, H) rep(j, W) I[i][j] = -1;
    
    memo.clear();
    
    rep(i, H) rep(j, W){
      cin >> M[i][j];
      if ( isdigit(M[i][j]) ){
	I[i][j] = size;
	PI[size] = make_pair(i, j);
	init.setValue(size++, (M[i][j]-'0'));
      }
    }
    rep(i, H) rep(j, W){
      if  ( M[i][j] == '*' || isdigit(M[i][j]) ){
	bool target = false;
	rep(r, 9){
	  int ni = i + di[r];
	  int nj = j + dj[r];
	  if ( 0 <= ni  && 0 <= nj && ni < H && nj < W ){
	    if ( '0' <= M[ni][nj]  && M[ni][nj] <= '9' ) { target = true; break;}
	  }
	}
	if ( target )  D[dsize++] = make_pair(i, j);
      }
    }

    cout << dfs(init) << endl;
  }
}

Measured memory_bytes: 11988