#include #include using namespace std; using mint = atcoder::modint998244353; struct Problem_C{ int num_component; vector parent_or_size; Problem_C(int N) : num_component(N), parent_or_size(N, -1) {} int leader(int v){ if(parent_or_size[v] < 0) return v; return parent_or_size[v] = leader(parent_or_size[v]); } bool same(int u, int v) { return leader(u) == leader(v); } void 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); parent_or_size[x] += parent_or_size[y]; parent_or_size[y] = x; num_component--; } }; int main(){ ios::sync_with_stdio(false); cin.tie(0); int W, H; cin >> W >> H; vector pow10(W + 1); pow10[0] = 1; for(int i = 0; i < W; i++)pow10[i + 1] = pow10[i] * 10; Problem_C uf(W + 10); while(H--){ string s; cin >> s; array pos{}; pos.fill(-1); for(int i = 0; i < W; i++){ if(s[i] == '?') continue; if('0' <= s[i] && s[i] <= '9') { uf.merge(s[i] - '0' + W, i); continue; } int c = s[i] - 'a'; if(pos[c] != -1) uf.merge(i, pos[c]); pos[c] = i; } bool is_zero = false; for(int i = 0; i < 10; i++){ for(int j = 0; j < i; j++){ if(uf.same(i + W, j + W)) is_zero = true; } } cout << (is_zero ? 0 : pow10[uf.num_component - 10].val()) << '\n'; } }