#include #include using namespace std; int main(){ ios::sync_with_stdio(false); cin.tie(0); int W, H; cin >> W >> H; //10のべき乗の前計算 vector pow10(W + 1); pow10[0] = 1; for(int i = 0; i < W; i++) pow10[i + 1] = pow10[i] * 10; //Union Find int num_component = W; //連結成分のサイズ - 10 vector parent_or_size(W + 10, -1); function leader = [&](int v){ if(parent_or_size[v] < 0) return v; return parent_or_size[v] = leader(parent_or_size[v]); }; auto merge = [&](int u, int v){ int x = leader(u), y = leader(v); if(x == y)return; if(-parent_or_size[x] < -parent_or_size[y]) swap(x, y); num_component--; parent_or_size[x] += parent_or_size[y]; parent_or_size[y] = x; }; while(H--){ string s; cin >> s; vector alphabet(26, -1); for(int i = 0; i < W; i++){ if(s[i] == '?') continue; if('0' <= s[i] && s[i] <= '9') { merge(i, s[i] - '0' + W); continue; } int c = s[i] - 'a'; if(alphabet[c] != -1) merge(alphabet[c], i); alphabet[c] = i; } bool is_zero = false; for(int i = 0; i < 10; i++){ for(int j = 0; j < i; j++){ if(leader(i + W) == leader(j + W)) is_zero = true; } } cout << (is_zero ? 0 : pow10[num_component].val()) << '\n'; } }