#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <complex>
#include <cstring>
#include <cstdlib>
#include <string>
#include <cmath>
#include <cassert>
#include <queue>
#include <set>
#include <map>
#include <valarray>
#include <bitset>
#include <stack>
#include <iomanip>
#include <fstream>
using namespace std;

#define REP(i,n) for(int i=0;i<(int)n;++i)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()
const int INF = 1<<29;
typedef long long ll;
typedef pair<int,int> pii;

struct Cmp {
  bool operator()(const vector<int> &a, const vector<int> &b) const {
    int am = INF, bm = INF;
    FOR(it, a) am=min(am,*it);
    FOR(it, b) bm=min(bm,*it);
    return am!=bm ? am < bm : a < b;
    // return a.size() != b.size() ? a.size() > b.size() : a<b;
  }
};

vector<int> p[15*9];
int pn[15*9];
int n;

int chance[15*9+1][15];
char ba[15][15];
int ans;
int num[15];
int numnum;

int tmp[15];

ll encode(int a[]) {
  ll q = 1;
  ll res = 0;
  REP(i,numnum) {
    res += q*a[i];
    q *= 10;
  }
  return res;
}

ll ten[20];

int get(ll S, int i) {
  return S/ten[i]%10;
}
ll change(ll S, int i, int x) {
  assert(x>=0&&x<10);
  S -= get(S,i)*ten[i];
  S += x*ten[i];
  return S;
}

map<ll, int> memo[15*9];

int solve(int now, ll S) {
  if (S == 0) return 0;
  if (now == n) return INF;
  if (memo[now].count(S)) return memo[now][S];
  
  REP(i,numnum) {
    if (get(S,i) > chance[now][i]) return INF;
  }
  
  int res = INF;
  ll T = S;
  REP(k,pn[now]) {
    bool ng = 0;
    REP(i,p[now].size()) {
      int a = p[now][i];
      int c = get(T,a);
      if (c == 0) {
        ng = 1;
        break;
      }
      T = change(T,a,c-1);
    }
    if (!ng) {
      res = min(res, solve(now+1, T)+k+1);
    } else {
      break;
    }
  }
  res = min(res, solve(now+1, S));
  // cout << res << endl;
  return memo[now][S] = res;
}

int main() {
  ten[0] = 1;
  REP(i,19) ten[i+1] = ten[i] * 10;
  int h, w;
  while(cin >> h >> w, h||w) {
    numnum = 0;
    n = 0;
    map<pii,int>mp;
    REP(i,h) {
      REP(j,w) {
        cin >> ba[i][j];
      }
    }
    REP(i,h) {
      REP(j,w) {
        if (isdigit(ba[i][j])) {
          for (int y=i-1; y<=i+1; ++y) {
            for (int x=j-1; x<=j+1; ++x) {
              if (y<0||y>=h||x<0||x>=w) continue;
              if (ba[y][x] == '.') continue;
              if (mp.count(pii(y,x)) == 0) {
                mp[pii(y,x)] = n;
                p[n].clear();
                n++;
              }
              int a = mp[pii(y,x)];
              p[a].push_back(numnum);
            }
          }
          num[numnum] = ba[i][j] - '0';
          numnum++;
        }
      }
    }
    map<vector<int>, int, Cmp> mp2;
    REP(i,n) mp2[p[i]]++;
    n = 0;
    FOR(it, mp2) {
      p[n] = it->first;
      pn[n] = it->second;
      n++;
    }
    // sort(p,p+n,cmp);
    // REP(i,n) {
    //   cout << "pn = " << pn[i] << endl;
    //   FOR(it, p[i]) {
    //     cout << *it << " ";
    //   }
    //   cout << endl;
    // }
    memset(chance,0,sizeof(chance));
    for (int i=n-1; i>=0; --i) {
      REP(j,numnum) chance[i][j]= chance[i+1][j];
      REP(j,pn[i]) {
        FOR(it, p[i]) {
          chance[i][*it]++;
        }
      }
    }
    REP(i,n) memo[i].clear();
    ll S = encode(num);
    cout << solve(0,S) << endl;
  }
    
}

Measured memory_bytes: 1828