use std::ascii::AsciiExt;
use std::ops::DivAssign;
use std::ops::MulAssign;
use std::ops::SubAssign;
use std::collections::BinaryHeap;
use std::str::FromStr;
use std::collections::HashSet;
use std::collections::BTreeMap;
use std::fmt::Display;
use std::ops::Neg;
use std::ops::Div;
use std::ops::Mul;
use std::ops::Add;
use std::ops::{AddAssign, Sub};
use std::cmp::max;
use std::collections::VecDeque;
use std::cmp::min;
use std::collections::{HashMap, BTreeSet};
use std::cmp::Ordering;
use std::fmt::Debug;

fn read_line() -> String {
    let mut buffer = String::new();
    std::io::stdin().read_line(&mut buffer).expect("No Line");
    buffer.trim().to_owned()
}
fn read_lines<T: std::str::FromStr>(count: usize) -> Vec<T> {
    let mut buffer = String::new();
    let mut vec = Vec::with_capacity(count);
    for _ in 0 .. count {
        std::io::stdin().read_line(&mut buffer).expect("No Line");
        vec.push(buffer.trim().parse().ok().expect("Can't Parse"));
        buffer.clear();
    }
    vec
}
fn read_tabulate<R, T: Fn(&str)->R> (count: usize, transformer: T) -> Vec<R> {
    let mut buffer = String::new();
    let mut vec = Vec::with_capacity(count);
    for _ in 0 .. count {
        std::io::stdin().read_line(&mut buffer).expect("No Line");
        vec.push(transformer(buffer.trim()));
        buffer.clear();
    }
    vec
}
fn read_value<T: std::str::FromStr>() -> T {
    read_line().trim().parse().ok().unwrap()
}
fn read_values<T: std::str::FromStr>() -> Vec<T> {
    read_line().trim().split_whitespace().map(|x| x.parse().ok().expect("Can't Parse")).collect::<Vec<T>>()
}
macro_rules! freeze {
    ($($id:ident), *) => {
        $(let $id = $id;)*
    };
}
macro_rules! read_map {
    ($ident: ident: [$block: block; $size: expr]) => {
        let $ident = (0 .. $size).into_iter().map(|_| $block).collect::<Vec<_>>();
    };
    (mut $ident: ident: [$block: block; $size: expr]) => {
        let mut $ident = (0 .. $size).into_iter().map(|_| $block).collect::<Vec<_>>();
    };
}
macro_rules! read {
    (mut $ident: ident: String) => {
        let mut $ident = read_value::<String>();
    };
    ($ident: ident: String) => {
        let $ident = read_value::<String>();
    };
    (mut $ident: ident: [$ty:ty]) => {
        let mut $ident = read_values::<$ty>();
    };
    ($ident: ident: [$ty:ty]) => {
        let $ident = read_values::<$ty>();
    };
    (mut $ident: ident: [[$ty:ty]; $size: expr]) => {
        let mut $ident = (0 .. $size).into_iter().map(|_| read_values::<$ty>()).collect::<Vec<_>>();
    };
    ($ident: ident: [[$ty:ty]; $size: expr]) => {
        let $ident = (0 .. $size).into_iter().map(|_| read_values::<$ty>()).collect::<Vec<_>>();
    };
    (mut $ident: ident: [$ty:ty; $size:expr]) => {
        let mut $ident = read_lines::<$ty>($size);
    };
    ($ident: ident: [$ty:ty; $size:expr]) => {
        let $ident = read_lines::<$ty>($size);
    };
    ($ident: ident: [$block: block; $size: expr]) => {
        let $ident = (0 .. $size).into_iter().map(|_| $block).collect::<Vec<_>>();
    };
    (mut $ident: ident: [$block: block; $size: expr]) => {
        let mut $ident = (0 .. $size).into_iter().map(|_| $block).collect::<Vec<_>>();
    };
    ($($token: tt)*) => {
        let mut iter = read_values::<String>().into_iter();
        read_from_iter!(iter; $($token)*);
    };
}
macro_rules! read_from_iter {
    ($iter:expr; mut $ident:ident:$ty:ty, $($rest:tt)*) => {
        let mut $ident = $iter.next().unwrap().parse::<$ty>().expect("Can't Parse");
        read_from_iter!($iter; $($rest)*);
    };
    ($iter:expr; $ident:ident:$ty:ty, $($rest:tt)*) => {
        let $ident = $iter.next().unwrap().parse::<$ty>().expect("Can't Parse");
        read_from_iter!($iter; $($rest)*);
    };
    ($iter:expr; mut $ident:ident:$ty:ty) => {
        let mut $ident = $iter.next().unwrap().parse::<$ty>().expect("Can't Parse");
    };
    ($iter:expr; $ident:ident:$ty:ty) => {
        let $ident = $iter.next().unwrap().parse::<$ty>().expect("Can't Parse");
    };
    ($iter: expr; ) => {};
}
struct KeyValue<K, V> {
    key: K,
    value: V
}
impl <K: PartialOrd, V> PartialEq for KeyValue<K, V> {
    fn eq(&self, other: &Self) -> bool {
        self.key.eq(&other.key)
    }
}
impl <K: PartialOrd, V> Eq for KeyValue<K, V> {}
impl <K: PartialOrd, V> PartialOrd for KeyValue<K, V> {
    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
        self.key.partial_cmp(&other.key)
    }
}
impl <K: PartialOrd, V> Ord for KeyValue<K, V> {
    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
        self.key.partial_cmp(&other.key).ok_or("Can't Compare").unwrap()
    }
}
#[derive(Copy, Clone)]
enum Cell {
    Blank, Value(i32)
}
impl Cell {
    fn is_blank(&self) -> bool {
        match self {
            &Cell::Blank => true,
            _ => false
        }
    }
}
impl FromStr for Cell {
    type Err = ();
    fn from_str(s: &str) -> std::result::Result<Self, <Self as std::str::FromStr>::Err> { 
        if s == "?" {
            Ok(Cell::Blank)
        }else {
            match i32::from_str(s) {
                Ok(value) => Ok(Cell::Value(value)),
                _ => Err(())
            }
        }
     }
}


fn main() {
    let mut first = true;
    loop {
        read!(values: [usize]);
        if values[0] == 0 {break;}
        if !first {
            println!("");
        }
        let row_count = values[0];
        let column_count = values[1];
        read!(mut graph: [[Cell]; row_count + 1]);
        let mut count_by_row = vec![0usize; row_count];
        let mut count_by_column = vec![0usize; column_count];
        let mut blank_count = 0;
        let mut blank_cell = Vec::new();
        for r in 0 .. row_count {
            for c in 0 .. column_count {
                match graph[r][c] {
                    Cell::Blank => {
                        count_by_row[r] += 1;
                        count_by_column[c] += 1;
                        blank_count += 1;
                        blank_cell.push((r, c));
                    },
                    _ => (),
                }
            }
        }
        while blank_count > 0 && (count_by_row.iter().any(|&c| c == 1) || count_by_column.iter().any(|&c| c == 1)) {
            if let Some(r) = (0 .. row_count).find(|&i| count_by_row[i] == 1) {
                let c = (0 .. column_count).find(|&i| graph[r][i].is_blank()).unwrap();
                let others = (0 .. column_count).map(|i| {
                    match graph[r][i] {
                        Cell::Value(value) => value,
                        _ => 0
                    }
                }).sum::<i32>();
                let sum = match graph[r][column_count] {
                    Cell::Value(value) => value,
                    _ => panic!()
                };
                graph[r][c] = Cell::Value(sum - others);
                count_by_row[r] -= 1;
                count_by_column[c] -= 1;
            }else if let Some(c) = (0 .. column_count).find(|&i| count_by_column[i] == 1) {
                let r = (0 .. row_count).find(|&i| graph[i][c].is_blank()).unwrap();
                let others = (0 .. row_count).map(|i| {
                    match graph[i][c] {
                        Cell::Value(value) => value,
                        _ => 0
                    }
                }).sum::<i32>();
                let sum = match graph[row_count][c] {
                    Cell::Value(value) => value,
                    _ => panic!()
                };
                graph[r][c] = Cell::Value(sum - others);
                count_by_row[r] -= 1;
                count_by_column[c] -= 1;
            }
        }
        if graph.iter().any(|line| line.iter().any(|cell| cell.is_blank())) {
            println!("NO");
        }else {
            for (r, c) in blank_cell {
                match graph[r][c] {
                    Cell::Value(value) => println!("{}", value),
                    _ => panic!()
                }
            }
        }
        read!(blank: String);
        first = false;
    }
}


Measured memory_bytes: 5056