#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;

const int INF = 1<<28;

const int MAXN = 105;
int R, C;
int G[MAXN][MAXN];

int getValue(int i, int j, int di, int dj) {
  int sum = 0;
  for(int d = -1; d <= 1; d += 2) {
    int ni = i;
    int nj = j;
    for(ni = i, nj = j;
        0 <= ni && ni < R && 0 <= nj && nj < C;
        ni += d*di, nj += d*dj) {
      if(ni == i && nj == j) continue;
      if(G[ni][nj] == INF) return INF;
      sum -= G[ni][nj];
    }
    if(ni >= 0 && nj >= 0) sum += G[ni][nj];
  }
  return sum;
}

int main() {
  while(cin >> R && R) {
    cin >> C;
    for(int i = 0; i < R+1; ++i) {
      for(int j = 0; j < C+1; ++j) {
        string s;
        cin >> s;
        if(s == "?") {
          G[i][j] = INF;
        } else {
          G[i][j] = atoi(s.c_str());

        }
      }
    }
    queue<pair<int,int> > que;
    int n = 0;
    for(int i = 0; i < R; ++i) {
      for(int j = 0; j < C; ++j) {
        if(G[i][j] == INF) {
          que.push(make_pair(i,j));
          ++n;
        }
      }
    }
    vector<pair<pair<int,int>, int> > res;
    while(!que.empty()) {
      int i = que.front().first;
      int j = que.front().second;
      que.pop();
      if(G[i][j] != INF) continue;
      int u = getValue(i,j,1,0);
      int v = getValue(i,j,0,1);
      if(u != INF || v != INF) {
        G[i][j] = min(u,v);
        res.push_back(make_pair(make_pair(i,j),G[i][j]));
        for(int k = 0; k < C; ++k) {
          if(G[i][k] == INF) que.push(make_pair(i,k));
        }
        for(int k = 0; k < R; ++k) {
          if(G[k][j] == INF) que.push(make_pair(k,j));
        }
      }
    }

    static bool first = true;
    if(first) first = false;
    else cout << endl;
    if(res.size() != n) {
      cout << "NO" << endl;
    } else {
      sort(res.begin(), res.end());
      for(int i = 0; i < res.size(); ++i) {
        cout << res[i].second << endl;
      }
    }
  }
  return 0;
}