Problem:
Problem D:
Indian Puzzle
In the Indian Puzzle, one is intended to fill out blanks with numbers and operators in a
n
by
n
grid in order to make equalities in the grid true (See Figure 1).
Figure 1
A blank cell should be filled out with a number (from 0 to 9 inclusive) or an operator (
+
,
-
,
×
,
÷
,
=
), and black cells split equalities. Initially, some cells are already filled with numbers or operators.
The objective of this puzzle is to fill out all the blank cells with numbers (from 0 to 9 inclusive) and operators (
+
,
-
,
×
,
÷
) in a given list. All the numbers and operators in the list must be used to fill out the blank cells.
A equality is organized by more than 2 consecutive left-to-right or top-to-bottom white cells. You can assume that a equality contains exactly one cell with '
=
' which connects two expressions.
The expressions conform to the order of operations and semantics of conventional four arithmetic operations. First, do all multiplication and division, starting from the left (top). Then, do all addition and subtraction, starting from the left (top). In addition, this puzzle has the following rules:
Division by zero and division leaving a remainder, are not allowed.
Leading zeros are not allowed.
Unary operators like
3×-8=-24
are not allowed.
In a formal description, the equality must conform the syntax in the following BNF:
<Eq> ::= <Ex> = <Ex>
<Ex> ::= <N0> | <Ex> <Op> <N0> 
<N0> ::= <N> | 0
<N>  ::= <D> | <N> <D> | <N> 0
<Op> ::= + | - | × | ÷
<D>  ::= 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
Of course, puzzle creators must make solvable puzzle.
Your task is to write a program which verifies whether given puzzle is solvable or not.
Input
Input consists of several datasets. Each dataset consists of:
H W
H
×
W
characters
n
n
characters
The integers
H
and
W
are the numbers of rows and columns of the grid, respectively.
H
×
W
characters denote the grid which contains '
.
' representing a blank cell, '
#
' representing a black cell, numbers (from
0
to
9
inclusive), operators('
+
','
-
', '
*
', '
/
', '
=
')(
×
is represented by '
*
' and
÷
is represented by '
/
').
The integer
n
is the number of characters in the list. The last line of a dataset contains
n
characters indicating numbers and operators for the blank cells.
The end of input is indicated by a line containing two zeros separated by a space.
Output
For each dataset, print "
Yes
" if the given puzzle is solvable, "
No
" if not.
Constraints
Judge data includes at most 100 data sets.
H
,
W
≤ 10
n
≤ 10
Sample Input
5 5
4=..2
+#=#+
.-2=.
=#*#=
.-.=3
6
7 3 1 4 / 8
1 6
8..3=2
2
2 +
0 0
Output for the Sample Input
Yes
No

Submitted solutions:

code_snippet: #include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <map>
#include <string>
#include <queue>
using namespace std;
#define SZ(v) ((int)(v).size())
const int maxint = -1u>>1;
const int maxn = 10 + 2;
//const int dx[] = {-1, 1, 0, 0};
//const int dy[] = {0, 0, -1, 1};

int n, m, k, cnt;
char s[maxn][maxn], d[maxn];
pair<int, int> rec[maxn];
bool used[maxn];

bool out(int x, int y) {
    return x < 0 || y < 0 || x >= n || y >= m;
}
bool isop(char c) {
    return c == '+' || c == '-' || c == '*' || c == '/';
}
bool calc(int &x1, int x2, char op) {
    if (op == '+') x1 += x2;
    else if (op == '-') x1 -= x2;
    else if (op == '*') x1 *= x2;
    else if (op == '/') {
        if (x2 == 0 || x1 % x2) return false;
        x1 /= x2;
    }
    return true;
}
bool calc_exp(char *s, int n, int &val) {
    if (n == 0) return false;
    int now = 0;
    vector<int> num;
    vector<char> op;
    for (int i = 0; i <= n; ++i) {
        if (i == n || s[i] == '+' || s[i] == '-') {
            num.push_back(now);
            now = 0;
            while (num.size() > 1) {
                int x2 = num.back();
                num.pop_back();
                int x1 = num.back();
                num.pop_back();
                if (!calc(x1, x2, op.back())) return false;
                op.pop_back();
                num.push_back(x1);
            }
            if (i != n) op.push_back(s[i]);
        } else if (isdigit(s[i])) {
            now = now * 10 + s[i] - '0';
        } else if (s[i] == '*' || s[i] == '/') {
            num.push_back(now);
            now = 0;
            while (op.size() > 0 && (op.back() == '*' || op.back() == '/')) {
                int x2 = num.back();
                num.pop_back();
                int x1 = num.back();
                num.pop_back();
                if (!calc(x1, x2, op.back())) return false;
                op.pop_back();
                num.push_back(x1);
            }
            op.push_back(s[i]);
        }
    }
    val = num[0];
    return true;
}
bool legal_exp(char *s, int n, int &val) {
    //printf("%s %d\n", s, n);
    for (int i = 0; i < n; ++i) {
        if (i + 1 < n && s[i] == '0' && isdigit(s[i + 1]) && (i == 0 || !isdigit(s[i - 1]))) return false;
        //if ((i == 0 || i == n - 1) && isop(s[i])) return false;
        //if (i + 1 < n && isop(s[i]) && isop(s[i + 1])) return false;
    }
    if (!calc_exp(s, n, val)) return false;
    return true;
}
bool legal_equility(char *s, int n) {
    if (n <= 2) return true;
    int x = -1;
    for (int i = 0; i < n; ++i) {
        if (s[i] == '=') {
            if (x >= 0) return false;
            x = i;
        }
    }
    if (x == -1) return false;
    for (int i = 0; i < n; ++i) {
        if ((i == 0 || i == n - 1) && isop(s[i])) return false;
        if (i + 1 < n && isop(s[i]) && isop(s[i + 1])) return false;
        if (i + 1 < n && isop(s[i]) && s[i + 1] == '=') return false;
        if (i - 1 >= 0 && isop(s[i]) && s[i - 1] == '=') return false;
    }
    for (int i = 0; i < n; ++i) {
        if (s[i] == '.') return true;
    }
    int x1, x2;
    //puts("ok");
    if (!legal_exp(s, x, x1) || !legal_exp(s + x + 1, n - x - 1, x2)) return false;
    //printf("x1 %d x2 %d\n", x1, x2);
    return x1 == x2;
}
bool check_ori() {
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            if (s[i][j] == '#') continue;
            int k = j + 1;
            while (k < m && s[i][k] != '#') ++k;
            if (!legal_equility(s[i] + j, k - j)) return false;
            j = k;
        }
    }
    char str[maxn];
    int len;
    for (int j = 0; j < m; ++j) {
        for (int i = 0; i < n; ++i) {
            if (s[i][j] == '#') continue;
            len = 0;
            while (i + len < n && s[i + len][j] != '#') {
                str[len] = s[i + len][j];
                ++len;
            }
            if (!legal_equility(str, len)) return false;
            i += len;
        }
    }
    return true;
}

bool ok(int x1, int x2) {
    int lf = x2, rt = x2;
    while (lf >= 0 && s[x1][lf] != '#') --lf;
    while (rt < m && s[x1][rt] != '#') ++rt;
    ++lf;
    --rt;
    if (!legal_equility(s[x1] + lf, rt - lf + 1)) return false;
    char str[maxn];
    int len = 0;
    while (x1 >= 0 && s[x1][x2] != '#') --x1;
    ++x1;
    while (x1 < n && s[x1][x2] != '#') {
        str[len++] = s[x1++][x2];
    }
    if (!legal_equility(str, len)) return false;
    return true;
}

bool dfs(int dep) {
    if (dep == cnt) {
        return true;
    }
    for (int i = 0; i < k; ++i) {
        if (used[i]) continue;
        if (i > 0 && d[i] == d[i - 1] && !used[i - 1]) continue;
        s[rec[dep].first][rec[dep].second] = d[i];
        used[i] = true;
        if (ok(rec[dep].first, rec[dep].second) && dfs(dep + 1)) return true;
        used[i] = false;
        s[rec[dep].first][rec[dep].second] = '.';
    }
    return false;
}

bool check() {
    if (cnt > k) return false;
    if (!check_ori()) return false;
    memset(used, 0, sizeof(used));
    if (!dfs(0)) return false;
    return true;
}
bool cmp(char x1, char x2) {
    return x1 < x2;
}
int main() {
    //char st[100];
    //while (scanf("%s", st) && strcmp(st, "0")) {
        //bool flag = legal_equility(st, strlen(st));
        //printf("%d\n", flag);
    //}
    //return 0;
        //int val;
        //bool flag = legal_exp(st, strlen(st), val);
        //printf("%d %d\n", val, flag);
    //}
    //printf("0\n");
    //freopen("0.out", "w", stdout);
    while (scanf("%d%d", &n, &m) == 2 && (n + m)) {
        cnt = 0;
        for (int i = 0; i < n; ++i) {
            scanf("%s", s[i]);
            for (int j = 0; j < m; ++j) {
                if (s[i][j] == '.') rec[cnt++] = make_pair(i, j);
            }
        }
        scanf("%d", &k);
        if (k > 10) while (1);
        //char str[10];
        for (int i = 0; i < k; ++i) {
            do {
                d[i] = getchar();
            } while (!isdigit(d[i]) && !isop(d[i]));
        }
        sort(d, d + k, cmp);
        //d[k] = 0; printf("%s\n", d);
        bool flag = check();
        if (flag) printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3276
final_rank: 1

code_snippet: #ifdef _DEBUG
#define _GLIBCXX_DEBUG
#endif
#include <bits/stdc++.h>
using namespace std;
#include <atcoder/all>
using namespace atcoder;
// #include <boost/rational.hpp>
// using namespace boost;
// using rat = rational<long long int>;
using mint = modint998244353;
// using mint = modint1000000007;
// using mint = mint;
using ll = long long;
using ld = long double;
using ull = uint64_t;
using pll = pair<ll, ll>;
using vll = vector<ll>;
using vvll = vector<vll>;
using vvvll = vector<vvll>;
using vpll = vector<pll>;
using vvpll = vector<vpll>;
using vm = vector<mint>;
using vvm = vector<vm>;
using vvvm = vector<vvm>;
using vstr = vector<string>;
#define v(T) vector<T>
#define vv(T) vector<vector<T>>
#define vvv(T) vector<vector<vector<T>>>
#define vvvv(T) vector<vector<vector<vector<T>>>>

istream &operator>>(istream &is, mint &a){ll tmp; is >> tmp; a = tmp; return is;}
ostream &operator<<(ostream &os, const mint &a){ os << a.val(); return os; }
string to_string(const __int128_t &a) { if (a == 0) return "0"; string s = ""; __int128_t num = a; bool is_negative = false; if (num < 0) { is_negative = true; num = -num; } while (num > 0) { s += '0' + (num % 10); num /= 10; } if (is_negative) s += '-'; reverse(s.begin(), s.end()); return s; }
istream &operator>>(istream &is, __int128_t &a){ string s; is >> s; a = 0; for(char c : s) { if(isdigit(c)) {a = a*10 + (c - '0'); }  } if(s[0]=='-'){ a *= -1; } return is; }
ostream &operator<<(ostream &os, const __int128_t &a){ os << to_string(a); return os; }
template<class T, class U> istream &operator>>(istream &is, pair<T, U> &p) { is >> p.first >> p.second; return is; }
template<class T, class U> ostream &operator<<(ostream &os, const pair<T, U> &p) { os << p.first << " " << p.second; return os; }
template<class T> istream &operator>>(istream &is, vector<T> &vec){ for(T &e : vec){is >> e;} return is; }
template<class T> ostream &operator<<(ostream &os, const vector<T> &vec) { for(int i = 0; i < (int)vec.size(); i++) { os << vec[i] << (i + 1 != (int)vec.size() ? " " : ""); } return os; }

template <class... T> constexpr auto min (T... a) { return min(initializer_list<common_type_t<T...>>{a...}); }
template <class... T> constexpr auto max (T... a) { return max(initializer_list<common_type_t<T...>>{a...}); }
template<class T> using pqg = priority_queue<T, vector<T>, greater<T>>;
template<class T> T opmin(T x, T y) { return min(x, y); }
template<class T> T einf() { return numeric_limits<T>::max(); }
template<class T> T opmax(T x, T y) { return max(x, y); }
template<class T> T eminf() { return numeric_limits<T>::min(); }
template<class T> T opsum(T x, T y) { return x + y; }
template<class T> T ezero() { return (T)0; }
// #define maxseg(T) segtree<T, [](T x, T y){return max(x, y);}, [](){return (T)(-(1LL << 60));}>
// #define minseg(T) segtree<T, [](T x, T y){return min(x, y);}, [](){return (T)((1LL << 60));}>
// #define sumseg(T) segtree<T, [](T x, T y){return x + y;}, [](){return (T)(0);}>
template<class T> using minseg = segtree<T, opmin<T>, einf<T>>;
template<class T> using maxseg = segtree<T, opmax<T>, eminf<T>>;
template<class T> using sumseg = segtree<T, opsum<T>, ezero<T>>;
// template<class T> struct v : vector<T> { using vector<T> :: vector; };
// template<class T> struct vv : vector<v<T>> { using vector<v<T>> :: vector; };
// template<class T> struct vvv : vector<vv<T>> { using vector<vv<T>> :: vector; };
template<class T> inline bool chmin(T& a, T b) {if(a > b){a = b; return true;} else {return false;}};
template<class T> inline bool chmax(T& a, T b) {if(a < b){a = b; return true;} else {return false;}};
#define rep(i,n) for(ll i = 0; i < (ll)(n); i++)
#define repr(i,n) for(ll i = (ll)(n) - 1; i >= 0; i--)
#define REP(i, l, r) for(ll i = (ll)l; i <= (ll)(r); i++)
#define REPR(i, l, r) for(ll i = (ll)r; i >= (ll)(l); i--)
const ll inf = (1 << 30);
const ll INF = (1LL << 60);
const vector<pair<ll, ll>> DIJ = {{1, 0}, {0, -1}, {-1, 0}, {0, 1}};
void out(){cout<<'\n';}
template<class T, class... Ts> void out(const T& a, const Ts&... b){ cout<<a; (cout<<... << (cout << ' ', b)); cout << '\n';}
void outf(){cout<<endl;}
template<class T, class... Ts> void outf(const T& a, const Ts&... b){ cout<<a; (cout<<... << (cout << ' ', b)); cout << endl;}
template<class T, class U> void outp(pair<T, U> a){ out((a).first, (a).second); }
template<class T, class U> void outpf(pair<T, U> a){ outf((a).first, (a).second); }
template<class T> void outv(T a){rep(i, (a).size()){ cout << (a)[i] << " "; } cout << endl;}
template<class T> void outvL(T a){rep(i, (a).size()){out((a)[i]);} cout << flush; }
// template<class T> void outvv(T a){rep(i, a.size()){ rep(j, a.at(i).size()){cout << a.at(i).at(j) << " "; } cout << endl; }}
// template<class T> void outvp(T a){rep(i, a.size()){ out2(a.at(i).first, a.at(i).second); }}
void setpre(int a){cout << fixed << setprecision(a);}
#define outN out("No")
#define outY out("Yes")
#define outYN(flag) out(flag ? "Yes" : "No")
#define dame(...) {outf(__VA_ARGS__);return 0;}

template<class T> void read(vector<T>& vec){ for(int i = 0; i < (int)vec.size(); i++) { cin >> vec[i]; } }
template<class... T> void read(T&... a){(cin >> ... >> a);}
#define readll(...) ll __VA_ARGS__; read(__VA_ARGS__)
#define readvll(a, n) vector<ll> a(n); read(a)
#define readvt(type, a, n) vector<type> a(n); read(a)
#define readvll2(a, b, n) vector<ll> a(n), b(n); for(int lopi = 0; lopi < (int)(n); lopi++) cin >> (a)[lopi] >> (b)[lopi]
#define readvll3(a, b, c, n) vector<ll> a(n), b(n), c(n); for(int lopi = 0; lopi < (int)(n); lopi++) cin >> (a)[lopi] >> (b)[lopi] >> (c)[lopi]
#define readstr(...) string __VA_ARGS__; read(__VA_ARGS__)
#define readundirG(G, N, M) G = vvll(N); rep(lopi, M) {ll a, b; cin >> a >> b; G[a-1].push_back(b-1); G[b-1].push_back(a-1);}
#define readdirG(G, N, M) G = vvll(N); rep(lopi, M) {ll a, b; cin >> a >> b; G[a-1].push_back(b-1);}
#define readundirwghG(G, N, M) G = vv(pll)(N); rep(lopi, M) {ll a, b, c; cin >> a >> b >> c; G[a-1].emplace_back(b-1,c); G[b-1].emplace_back(a-1, c);}
#define readdirwghG (G, N, M) G = vv(pll)(N); rep(lopi, M) {ll a, b, c; cin >> a >> b >> c; G[a-1].emplace_back(b-1, c);}

#define All(a) (a).begin(), (a).end()
template<class T> inline void sortr(T& a){ sort((a).rbegin(), (a).rend()); }
template<class T> inline vector<int> argsort(T V, bool rev = false){vector<int> res(V.size()); iota(res.begin(), res.end(), 0); sort(res.begin(), res.end(), [&](int x, int y){if(!rev){return V[x] < V[y];}else{return V[x] > V[y];}}); return res;}
template<class T, class U> inline void sort_by_idx(T& V, vector<U>& I){assert(V.size() == I.size()); T tmpv = V; for(int loopi = 0; loopi < (int)I.size(); loopi++){V[loopi] = tmpv[I.at(loopi)];}}
template<class T, class U> inline void sortp(vector<T>& v1, vector<U>& v2, bool rev1 = false, int rev2 = false){assert(v1.size() == v2.size()); vector<int> I(v1.size()); iota(I.begin(), I.end(), 0); sort(I.begin(), I.end(), [&](const int x, const int y){if(v1[x] != v1[y]){return (bool)(rev1 ^ (v1[x] < v1[y]));}else{if(v2[x]==v2[y]){return false;} return (bool)(rev2 ^ (v2[x] < v2[y]));}}); sort_by_idx(v1, I); sort_by_idx(v2, I);}
template<class T> T POW(T x, ll n) {T ret = 1; while(n > 0){if(n & 1) ret *= x; x *= x; n >>= 1;} return ret;}
ll powll(ll x, ll n){ll ret = 1; while(n > 0){if(n & 1) ret *= x; x *= x; n >>= 1;} return ret;}
inline ll divceil(ll x, ll y) { if(x >= 0) {return(x / y + (ll)(x % y != 0)); } else { return -((-x) / y); } }
inline ll divfloor(ll x, ll y) { if(x >= 0) { return x/y; } else { return -((-x)/y + (ll)((-x) % y != 0)); } }
inline bool inLR(ll x, ll L, ll R){ return (L <= x && x < R); }
inline bool inRect(ll pos_x, ll pos_y, ll rect_H, ll rect_W, ll rect_h = 0, ll rect_w = 0){ return (rect_h <= pos_x && pos_x < rect_H && rect_w <= pos_y && pos_y < rect_W); }

template<class T> vector<T> &operator++(vector<T> &v) {for(auto &e : v){e++;} return v;}
template<class T> vector<T> operator++(vector<T> &v, signed) {auto res=v; for(auto &e : v){e++;} return res;}
template<class T> vector<T> &operator--(vector<T> &v) {for(auto &e : v){e--;} return v;}
template<class T> vector<T> operator--(vector<T> &v, signed) {auto res=v; for(auto &e : v){e--;} return res;}
template<class T> vector<T> operator+(const vector<T> &x, const vector<T> &y) { assert(x.size() == y.size()); vector<T> ret(x.size()); for(int i = 0; i < (int)x.size(); i++) {ret[i] = x[i] + y[i];} return ret; }
template<class T> vector<T> operator-(const vector<T> &x, const vector<T> &y) { assert(x.size() == y.size()); vector<T> ret(x.size()); for(int i = 0; i < (int)x.size(); i++) {ret[i] = x[i] - y[i];} return ret; } 

template<class T, class U> pair<T, U> operator+(const pair<T, U> &x, const pair<T, U> &y) { return make_pair(x.first + y.first, x.second + y.second); }
template<class T, class U> pair<T, U> operator-(const pair<T, U> &x, const pair<T, U> &y) { return make_pair(x.first - y.first, x.second - y.second); }
template<class T, class U> void operator+=(pair<T, U> &x, pair<T, U> &y) { x = x + y; }
template<class T, class U> void operator-=(pair<T, U> &x, pair<T, U> &y) { x = x - y; }

template<class T> size_t HashCombine(const size_t seed,const T &v){ return seed^(std::hash<T>()(v)+0x9e3779b9+(seed<<6)+(seed>>2)); }
template<class T,class S> struct std::hash<std::pair<T,S>>{ size_t operator()(const std::pair<T,S> &keyval) const noexcept { return HashCombine(std::hash<T>()(keyval.first), keyval.second); } };
template<class T> struct std::hash<std::vector<T>>{ size_t operator()(const std::vector<T> &keyval) const noexcept { size_t s=0; for (auto&& v: keyval) s=HashCombine(s,v); return s; } };
template<int N> struct HashTupleCore{ template<class Tuple> size_t operator()(const Tuple &keyval) const noexcept{ size_t s=HashTupleCore<N-1>()(keyval); return HashCombine(s,std::get<N-1>(keyval)); } };
template <> struct HashTupleCore<0>{ template<class Tuple> size_t operator()(const Tuple &keyval) const noexcept{ return 0; } };
template<class... Args> struct std::hash<std::tuple<Args...>>{ size_t operator()(const tuple<Args...> &keyval) const noexcept { return HashTupleCore<tuple_size<tuple<Args...>>::value>()(keyval); } };

// https://drken1215.hatenablog.com/entry/2023/10/29/235354
// Parser (T must have constructor T(long long))
template<class T> struct Parser {
    /* basic settings */
    vector<vector<string>> OPERATORS;               // binary operator priority
    function<T(const string&, T, T)> OPERATION;     // binary operation

    /* optional settings */
    function<T(const string&, int&)> GET_LEAF;      // leaf parser
    vector<string> UNARY_OPERATORS;                 // unary operator (ex: "-", "log")
    function<T(const string&, T)> UNARY_OPERATION;  // unary operation
    const string OPERATOR_NUMBER = "num";
    
    /* results */
    string S;
    int root;                    // vals[root] is the answer
    vector<T> vals;              // value of each node
    vector<string> ops;          // operator of each node
    vector<int> left, right;     // the index of left-node, right-node
    vector<int> ids;             // the node-index of i-th value
    
    /* constructor */
    Parser() {}
    Parser(const vector<vector<string>> &operators,
           const function<T(const string&, T, T)> operation) {
        init(operators, operation);
    }
    Parser(const vector<vector<string>> &operators,
           const function<T(const string&, T, T)> operation,
           const function<T(const string&, int&)> get_leaf) {
        init(operators, operation, get_leaf);
    }
    Parser(const vector<vector<string>> &operators,
           const function<T(const string&, T, T)> operation,
           const function<T(const string&, int&)> get_leaf,
           const vector<string> &unary_operators,
           const function<T(const string &op, T)> unary_operation) {
        init(operators, operation, get_leaf, unary_operators, unary_operation);
    }
    void init(const vector<vector<string>> &operators,
              const function<T(const string&, T, T)> operation) {
        OPERATORS = operators, OPERATION = operation;
    }
    void init(const vector<vector<string>> &operators,
              const function<T(const string&, T, T)> operation,
              const function<T(const string&, int&)> get_leaf) {
        OPERATORS = operators, OPERATION = operation;
        GET_LEAF = get_leaf;
    }
    void init(const vector<vector<string>> &operators,
              const function<T(const string&, T, T)> operation,
              const function<T(const string&, int&)> get_leaf,
              const vector<string> &unary_operators,
              const function<T(const string &op, T)> unary_operation) {
        OPERATORS = operators, OPERATION = operation;
        GET_LEAF = get_leaf;
        UNARY_OPERATORS = unary_operators, UNARY_OPERATION = unary_operation;
    }
    void clear() {
        S = "";
        vals.clear(), ops.clear(), left.clear(), right.clear(), ids.clear();
    }
    
    /* node generator */
    // value
    int new_leaf(T val, int &id) {
        vals.push_back(val);
        ops.push_back(OPERATOR_NUMBER);
        left.push_back(-1);
        right.push_back(-1);
        ids.push_back(id++);
        return (int)vals.size() - 1;
    }
    // FUNC(lp)
    int new_node_with_left(T val, const string &op, int lp) {
        vals.push_back(val);
        ops.push_back(op);
        left.push_back(lp);
        right.push_back(-1);
        ids.push_back(-1);
        return (int)vals.size() - 1;
    }
    // (lp) op (rp)
    int new_node_with_left_right(const string &op, int lp, int rp) {
        vals.push_back(OPERATION(op, vals[lp], vals[rp]));
        ops.push_back(op);
        left.push_back(lp);
        right.push_back(rp);
        ids.push_back(-1);
        return (int)vals.size() - 1;
    }
    
    /* main parser */
    T parse(const string &str, bool default_parse_numeric = true) {
        clear();
        S = str;
        int p = 0, id = 0;
        root = parse(p, id, default_parse_numeric);
        return vals[root];
    }
    int parse(int &p, int &id, bool default_parse_numeric, int depth = 0) {
        assert(p >= 0 && p < (int)S.size());
        string op;
        if (depth < (int)OPERATORS.size()) {
            // recursive descent
            int lp = parse(p, id, default_parse_numeric, depth + 1);
            bool update = false;
            do {
                update = false;
                if (is_in_the_operators(p, op,
                                        OPERATORS[(int)OPERATORS.size() - depth - 1])) {
                    int rp = parse(p, id, default_parse_numeric, depth + 1);
                    lp = new_node_with_left_right(op, lp, rp);
                    update = true;
                }
            } while (p < (int)S.size() && update);
            return lp;
        }
        else if (S[p] == '(') {
            return get_bracket(p, id, default_parse_numeric);
        }
        else if (default_parse_numeric && (S[p] == '-' || isdigit(S[p]))) {
            return get_number(p, id);
        }
        else if (is_in_the_operators(p, op, UNARY_OPERATORS)) {
            return get_unary_operation(p, id, op, default_parse_numeric);
        }
        else {
            return new_leaf(GET_LEAF(S, p), id);
        }
    }
    bool is_the_operator(int &p, const string &op) {
        if (op != "" && S.substr(p, op.size()) == op) {
            p += op.size();
            return true;
        }
        return false;
    }
    bool is_in_the_operators(int &p, string &res_op, const vector<string> &ops) {
        for (const auto &op : ops) {
            if (is_the_operator(p, op)) {
                res_op = op;
                return true;
            }
        }
        return false;
    }
    int get_number(int &p, int &id) {
        long long val = 0, sign = 1;
        if (S[p] == '-') sign = -1, ++p;
        while (p < (int)S.size() && isdigit(S[p])) {
            val = val * 10 + (int)(S[p++] - '0');
        }
        return new_leaf(T(val * sign), id);
    }
    int get_bracket(int &p, int &id, bool default_parse_numeric) {
        ++p;  // skip "("
        int lp = parse(p, id, default_parse_numeric, 0);
        ++p;  // skip ")"
        return lp;
    }
    int get_unary_operation(int &p, int &id, const string &op,
                            bool default_parse_numeric) {
        int lp;
        if (S[p] == '(') lp = get_bracket(p, id, default_parse_numeric);
        else lp = parse(p, id, default_parse_numeric, (int)OPERATORS.size());
        return new_node_with_left(UNARY_OPERATION(op, vals[lp]), op, lp);
    }
    
    /* dump */
    void dump() {
        dump_rec(root);
    }
    void dump_rec(int v, string space = "") {
        cout << space << v << ": (" << ops[v] << ", " << vals[v]
             << ") -> left: " << left[v] << ", right: " << right[v] << endl;
        if (left[v] != -1) dump_rec(left[v], space + "  ");
        if (right[v] != -1) dump_rec(right[v], space + "  ");
    }
};

vector<vector<string>> operator4 = {{"*", "/"}, {"+", "-"}};

template<typename T> T op(const string &s, T l, T r)
{
    if(s == "*")
    {
        return l * r;
    }
    else if(s == "/")
    {
        return l / r;
    }
    else if(s == "+")
    {
        return l + r;
    }
    else if(s == "-")
    {
        return l - r;
    }
    else assert(false);
}

int main()
{
    std::cin.tie(nullptr), std::ios_base::sync_with_stdio(false);
    Parser<mint> ps(operator4, op<mint>);
    while(true)
    {
        readll(H, W);
        if(!H) break;
        readvt(string, S, H);
        readll(N);
        readvt(char, C, N);
        vpll bl;
        vector<vector<pll>> prb;
        vv(bool) cH(H, v(bool)(W, false)), cW(H, v(bool)(W, false));
        auto check_syn = [&](string &x)
        {
            char bf = '-';
            rep(i, x.size())
            {
                if(isdigit(x[i]))
                {
                    if(!isdigit(bf) && x[i] == '0' && (i + 1 < x.size() && isdigit(x[i + 1])))
                    {
                        return false;
                    }
                }
                else if(x[i] == '=') return false;
                else
                {
                    if(i - 1 < 0 || i + 1 >= x.size() || !isdigit(x[i-1]) || !isdigit(x[i + 1])) return false;
                    if(x[i] == '/' && i + 1 < x.size() && x[i + 1] == '0') return false;
                }
                bf = x[i];
            }
            return true;
        };
        auto check_str = [&](string &x)
        {
            ll eq = x.find('=');
            if(eq == string::npos) return false;
            string L = x.substr(0, eq);
            if(!check_syn(L)) return false;
            string R = x.substr(eq + 1, x.size() - eq - 1);
            if(!check_syn(R)) return false;
            return ps.parse(L, true) == ps.parse(R, true);
        };
        auto check = [&]()
        {
            for(auto &line : prb)
            {
                string tmp;
                for(auto &[x, y] : line) tmp.push_back(S[x][y]);
                if(!check_str(tmp)) return false;
            }
            return true;
        };
        bool ng = false;
        rep(i, H) rep(j, W)
        {
            if(ng)
            {
                i = INF;
                break;
            }
            if(S[i][j] == '.')
            {
                bl.emplace_back(i, j);
            }
            if(S[i][j] == '#') continue;
            if(!cH[i][j] && i + 1 < H && S[i + 1][j] != '#')
            {
                ll x = i, y = j;
                bool have = false;
                vpll tmp;
                string ss;
                while(inRect(x, y, H, W) && S[x][y] != '#')
                {
                    if(S[x][y] == '.') have = true;
                    tmp.emplace_back(x, y);
                    ss.push_back(S[x][y]);
                    cH[x][y] = true;
                    x++;
                }
                if(!have)
                {
                    if(!check_str(ss))
                    {
                        ng = true;
                        break;
                    }
                }
                else
                {
                    prb.emplace_back(tmp);
                }
            }
            if(!cW[i][j] && j + 1 < W && S[i][j + 1] != '#')
            {
                ll x = i, y = j;
                bool have = false;
                vpll tmp;
                string ss;
                while(inRect(x, y, H, W) && S[x][y] != '#')
                {
                    if(S[x][y] == '.') have = true;
                    tmp.emplace_back(x, y);
                    ss.push_back(S[x][y]);
                    cW[x][y] = true;
                    y++;
                }
                if(!have)
                {
                    if(!check_str(ss))
                    {
                        ng = true;
                        break;
                    }
                }
                else
                {
                    prb.emplace_back(tmp);
                }
            }
        }
        if(ng)
        {
            outN;
            continue;
        }
        sort(All(C));
        bool ok = false;
        do
        {
            rep(i, N)
            {
                auto [x, y] = bl[i];
                S[x][y] = C[i];
            }
            if(check())
            {
                ok = true;
                break;
            }
        } while (next_permutation(All(C)));
        outYN(ok);
    }
}
accuracy: 1
time_ms: 830
memory_kb: 3584
final_rank: 18

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
#define chmin(x,y) x = min(x,y)
#define chmax(x,y) x = max(x,y)
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000 //オーバーフローに注意
#define MOD 998244353
//#define MOD 1000000007
#define EPS 0.000000001


#define SIZE 105
#define SIZE2 12



int H,W,N;
int space_IND;
int hori_IND[SIZE][SIZE],vert_IND[SIZE][SIZE];
char buf[SIZE2][SIZE2],CAND[SIZE2];
char eq[SIZE];
bool used[SIZE],check_hori[SIZE][SIZE],check_vert[SIZE][SIZE];
bool not_zero[SIZE],not_num[SIZE],not_op[SIZE];
vector<vector<pair<int,int>>> V;
vector<pair<int,int>> SPACE,COMBI;
int num_ORD;
char ORD[3628800][10],WORK[12];
bool errorFLG;
map<pair<int,int>,int> MAP;


ll calc_E(char line[SIZE]);
ll calc_T(char line[SIZE]);
ll calc_F(char line[SIZE]);
ll calc_NUM(char line[SIZE]);

bool isOP(char ch){

	return (ch == '+' || ch == '-' || ch == '*' || ch == '/');
}

bool isNUM(char ch){

	return ch >= '0' && ch <= '9';
}

bool isZERO(char ch){

	return ch == '0';
}

void dfs(int len){
	if(len == N){

		for(int i = 0; i < len; i++){

			ORD[num_ORD][i] = WORK[i];
		}
		num_ORD++;
		return;
	}

	for(int i = 0; i < N; i++){
		if(used[i])continue;

		char ch = CAND[i];
		if((isZERO(ch) && not_zero[len]) || (isOP(ch) && not_op[len]) || (isNUM(ch) && not_num[len]))continue;

		used[i] = true;
		WORK[len] = '0'+i;
		dfs(len+1);
		used[i] = false;
	}
}

int INDEX;

ll calc_E(char line[SIZE]){

	ll ret = calc_T(line);

	while(true){

		if(line[INDEX] == '+'){

			INDEX++;
			ret += calc_T(line);

		}else if(line[INDEX] == '-'){

			INDEX++;
			ret -= calc_T(line);

		}else{

			break;
		}
	}

	return ret;
}

ll calc_T(char line[SIZE]){

	ll ret = calc_F(line);

	while(true){

		if(line[INDEX] == '*'){

			INDEX++;
			ret *= calc_F(line);

		}else if(line[INDEX] == '/'){

			INDEX++;
			ll tmp = calc_F(line);
			if(tmp == 0 || (ret%tmp != 0)){

				errorFLG = true;
				tmp = HUGE_NUM;
			}
			ret /= tmp;

		}else{

			break;
		}
	}

	return ret;
}

ll calc_F(char line[SIZE]){

	if(line[INDEX] == '('){
		INDEX++;
		ll ret = calc_E(line);
		INDEX++;

		return ret;
	}else{

		return calc_NUM(line);
	}
}

ll calc_NUM(char line[SIZE]){

	ll ret = 0;

	vector<char> vec;

	while(line[INDEX] >= '0' && line[INDEX] <= '9'){

		ret = 10*ret + line[INDEX]-'0';
		vec.push_back(line[INDEX]);
		INDEX++;
	}
	if(vec.size() == 0){
		errorFLG = true;
		ret = 1;
	}
	if(vec.size() >= 2 && vec[0] == '0' && vec[1] == '0'){

		errorFLG = true;
		ret = 1;
	}
	return ret;
}

bool rangeCheck(int row,int col){

	return row >= 0 && row <= H-1 && col >= 0 && col <= W-1;
}

bool checkInvalidEQ(vector<pair<int,int>> vec){

	vector<char> L;
	for(int i = 0; i < vec.size(); i++){

		L.push_back(buf[vec[i].first][vec[i].second]);
	}

	//OP連続は不可
	for(int i = 0; i < L.size()-1; i++){
		if(isOP(L[i]) && isOP(L[i+1])){

			return false;
		}
	}

	if(L.size() >= 2 && L[0] == '0' && isNUM(L[1])){

		return false;
	}

	for(int i = 1; i < L.size(); i++){
		if(isOP(L[i-1]) && (i+1) < L.size() && isNUM(L[i+1]) && isZERO(L[i])){

			return false;
		}
	}
	if(isOP(L[0])||isOP(L.back())){

		return false;
	}

	return true;
}

void func(){

	SPACE.clear();
	MAP.clear();
	V.clear();
	COMBI.clear();

	space_IND = 0;

	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){

			check_hori[row][col] = false;
			check_vert[row][col] = false;
		}
	}

	for(int row = 0; row < H; row++){

		scanf("%s",buf[row]);
		for(int col = 0; col < W; col++){
			if(buf[row][col] == '.'){ //空白セル

				SPACE.push_back(make_pair(row,col));
				MAP[make_pair(row,col)] = space_IND++; //空白セルに番号を割り振る
			}
		}
	}

	scanf("%d",&N);

	char input[2];
	for(int i = 0; i < N; i++){

		scanf("%s",input);
		CAND[i] = input[0];
	}

	//配列の初期化
	for(int i = 0; i < N; i++){

		not_zero[i] = false;
		not_num[i] = false;
		not_op[i] = false;
	}

	//数式の候補を前計算
	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){
			if(buf[row][col] == '#' || buf[row][col] == '=')continue;

			if(!check_hori[row][col]){

				check_hori[row][col] = true;

				//右へ
				vector<pair<int,int>> toR;
				toR.push_back(make_pair(row,col));

				int last_col = col;

				for(int tmp_col = col+1; tmp_col < W; tmp_col++){
					if(buf[row][tmp_col] == '#' || buf[row][tmp_col] == '='){

						break;
					}
					last_col = tmp_col;

					toR.push_back(make_pair(row,tmp_col));
					check_hori[row][tmp_col] = true;
				}

				if((col > 0 && buf[row][col-1] == '=')||(last_col+1 < W && buf[row][last_col+1] == '=')){ //式の左か右に'='がある場合

					for(int i = 0; i < toR.size(); i++){

						hori_IND[toR[i].first][toR[i].second] = V.size();
					}
					if(!checkInvalidEQ(toR)){
						printf("No\n");
						return;
					}

					V.push_back(toR);
				}
			}


			if(!check_vert[row][col]){

				check_vert[row][col] = true;

				//下へ
				vector<pair<int,int>> toD;
				toD.push_back(make_pair(row,col));

				int last_row = row;

				for(int tmp_row = row+1; tmp_row < H; tmp_row++){
					if(buf[tmp_row][col] == '#' || buf[tmp_row][col] == '=')break;

					last_row = tmp_row;

					toD.push_back(make_pair(tmp_row,col));
					check_vert[tmp_row][col] = true;
				}

				if((row > 0 && buf[row-1][col] == '=') || (last_row+1 < H && buf[last_row+1][col] == '=')){ //式の上か下に'='がある場合

					for(int i = 0; i < toD.size(); i++){

						vert_IND[toD[i].first][toD[i].second] = V.size();
					}
					if(!checkInvalidEQ(toD)){
						printf("No\n");
						return;
					}

					V.push_back(toD);
				}
			}
		}
	}

	//比較する数式を前計算
	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){
			if(buf[row][col] != '=')continue;

			int a,b;

			if(col > 0 && col+1 < W && buf[row][col-1] != '#' && buf[row][col+1] != '#'){

				a = hori_IND[row][col-1];
				b = hori_IND[row][col+1];

				COMBI.push_back(make_pair(a,b));
			}

			if(row > 0 && row+1 < H && buf[row-1][col] != '#' && buf[row+1][col] != '#'){

				a = vert_IND[row-1][col];
				b = vert_IND[row+1][col];

				COMBI.push_back(make_pair(a,b));
			}
		}
	}

	//計算量を落とすための前処理
	for(int i = 0; i < V.size(); i++){
		for(int k = 0; k < V[i].size(); k++){
			pair<int,int> tmp = V[i][k]; //i個の数式の、k番目の場所

			if(buf[tmp.first][tmp.second] != '.')continue; //空白セルでないならSKIP

			int tmp_ind = MAP[tmp]; //空白セルのインデックスを取得

			if(k == 0){

				not_op[tmp_ind] = true; //先頭なので演算子不可
			}

			if(k == V[i].size()-1){

				not_op[tmp_ind] = true; //数式の末尾に演算子を置くのは不可
			}

			//左に演算子がある場合
			if(k > 0){
				pair<int,int> pre = V[i][k-1];
				if(isOP(buf[pre.first][pre.second])){

					not_op[tmp_ind] = true; //演算子の連続は不可
				}
			}

			//右に演算子があれば不可
			if(k+1 < V[i].size()){
				pair<int,int> next = V[i][k+1];
				if(isOP(buf[next.first][next.second])){

					not_op[tmp_ind] = true; //演算子の連続は不可
				}
			}

			//2つ左に演算子があって、1つ左に0があれば、数字は不可
			if(k >= 2){
				pair<int,int> pre_pre = V[i][k-2];
				pair<int,int> pre = V[i][k-1];
				if(isOP(buf[pre_pre.first][pre_pre.second]) && isZERO(buf[pre.first][pre.second])){

					not_num[tmp_ind] = true;
				}
			}

			//左に演算子があって、右に数字があれば、0は不可
			if(k > 0 && k+1 < V[i].size()){
				pair<int,int> pre = V[i][k-1];
				pair<int,int> next = V[i][k+1];
				if(isOP(buf[pre.first][pre.second]) && isNUM(buf[next.first][next.second])){

					not_zero[tmp_ind] = true;
				}
			}
		}
	}

	num_ORD = 0;


	//空白セルに候補値を割り当て
	for(int i = 0; i < N; i++){

		char ch = CAND[i];
		if((isZERO(ch) && not_zero[0]) || (isOP(ch) && not_op[0]) || (isNUM(ch) && not_num[0]))continue;

		used[i] = true;
		WORK[0] = '0'+i;
		dfs(1);
		used[i] = false;
	}

	for(int loop = 0; loop < num_ORD; loop++){

		//表を埋める
		for(int i = 0; i < N; i++){
			pair<int,int> tmp = SPACE[i];

			int tmp_ind = ORD[loop][i]-'0';

			buf[tmp.first][tmp.second] = CAND[tmp_ind];
		}

		errorFLG = false;
		bool FLG = true;

		for(int i = 0; i < COMBI.size(); i++){

			int a = COMBI[i].first;

			int tmp_ind = 0;
			for(int k = 0; k < V[a].size(); k++){

				pair<int,int> pos = V[a][k];
				eq[tmp_ind] = buf[pos.first][pos.second];
				eq[tmp_ind+1] = '=';
				tmp_ind++;
			}

			INDEX = 0;
			ll result1 = calc_E(eq);

			if(errorFLG)break;


			int b = COMBI[i].second;
			tmp_ind = 0;
			for(int k = 0; k < V[b].size(); k++){

				pair<int,int> pos = V[b][k];
				eq[tmp_ind] = buf[pos.first][pos.second];
				eq[tmp_ind+1] = '=';
				tmp_ind++;
			}

			INDEX = 0;
			ll result2 = calc_E(eq);

			if(errorFLG)break;

			if(result1 != result2){

				FLG = false;
				break;
			}
		}
		if(errorFLG)continue;
		if(FLG){

			printf("Yes\n");
			return;
		}
	}

	printf("No\n");
}


int main(){

	while(true){
		scanf("%d %d",&H,&W);
		if(H == 0 && W == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 520
memory_kb: 38880
final_rank: 19

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
#define chmin(x,y) x = min(x,y)
#define chmax(x,y) x = max(x,y)
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000 //オーバーフローに注意
#define MOD 998244353
//#define MOD 1000000007
#define EPS 0.000000001


#define SIZE 105
#define SIZE2 12


bool DEBUG = false;


int H,W,N;
int space_IND;
int hori_IND[SIZE][SIZE],vert_IND[SIZE][SIZE];
char buf[SIZE2][SIZE2],CAND[SIZE2];
char eq[SIZE];
bool used[SIZE],check_hori[SIZE][SIZE],check_vert[SIZE][SIZE];
bool not_zero[SIZE],not_num[SIZE],not_op[SIZE];
vector<vector<pair<int,int>>> V;
vector<pair<int,int>> SPACE,COMBI;
int num_ORD;
char ORD[3628800][10],WORK[12];
bool errorFLG;
map<pair<int,int>,int> MAP;


ll calc_E(char line[SIZE]);
ll calc_T(char line[SIZE]);
ll calc_F(char line[SIZE]);
ll calc_NUM(char line[SIZE]);

bool isOP(char ch){

	return (ch == '+' || ch == '-' || ch == '*' || ch == '/');
}

bool isNUM(char ch){

	return ch >= '0' && ch <= '9';
}

bool isZERO(char ch){

	return ch == '0';
}

void dfs(int len){
	if(len == N){

		for(int i = 0; i < len; i++){

			ORD[num_ORD][i] = WORK[i];
		}
		num_ORD++;
		return;
	}

	for(int i = 0; i < N; i++){
		if(used[i])continue;

		char ch = CAND[i];
		if((isZERO(ch) && not_zero[len]) || (isOP(ch) && not_op[len]) || (isNUM(ch) && not_num[len]))continue;

		used[i] = true;
		WORK[len] = '0'+i;
		dfs(len+1);
		used[i] = false;
	}
}

int INDEX;

ll calc_E(char line[SIZE]){

	ll ret = calc_T(line);

	while(true){

		if(line[INDEX] == '+'){

			INDEX++;
			ret += calc_T(line);

		}else if(line[INDEX] == '-'){

			INDEX++;
			ret -= calc_T(line);

		}else{

			break;
		}
	}

	return ret;
}

ll calc_T(char line[SIZE]){

	ll ret = calc_F(line);

	while(true){

		if(line[INDEX] == '*'){

			INDEX++;
			ret *= calc_F(line);

		}else if(line[INDEX] == '/'){

			INDEX++;
			ll tmp = calc_F(line);
			if(tmp == 0 || (ret%tmp != 0)){

				errorFLG = true;
				tmp = HUGE_NUM;
			}
			ret /= tmp;

		}else{

			break;
		}
	}

	return ret;
}

ll calc_F(char line[SIZE]){

	if(line[INDEX] == '('){
		INDEX++;
		ll ret = calc_E(line);
		INDEX++;

		return ret;
	}else{

		return calc_NUM(line);
	}
}

ll calc_NUM(char line[SIZE]){

	ll ret = 0;

	vector<char> vec;

	while(line[INDEX] >= '0' && line[INDEX] <= '9'){

		ret = 10*ret + line[INDEX]-'0';
		vec.push_back(line[INDEX]);
		INDEX++;
	}
	if(vec.size() == 0){
		errorFLG = true;
		ret = 1;
	}
	if(vec.size() >= 2 && vec[0] == '0' && vec[1] == '0'){

		errorFLG = true;
		ret = 1;
	}
	return ret;
}

bool rangeCheck(int row,int col){

	return row >= 0 && row <= H-1 && col >= 0 && col <= W-1;
}

bool checkInvalidEQ(vector<pair<int,int>> vec){

	vector<char> L;
	for(int i = 0; i < vec.size(); i++){

		L.push_back(buf[vec[i].first][vec[i].second]);
	}

	//OP連続は不可
	for(int i = 0; i < L.size()-1; i++){
		if(isOP(L[i]) && isOP(L[i+1])){

			return false;
		}
	}

	if(L.size() >= 2 && L[0] == '0' && isNUM(L[1])){

		return false;
	}

	for(int i = 1; i < L.size(); i++){
		if(isOP(L[i-1]) && (i+1) < L.size() && isNUM(L[i+1]) && isZERO(L[i])){

			return false;
		}
	}
	if(isOP(L[0])||isOP(L.back())){

		return false;
	}

	return true;
}

void func(){

	SPACE.clear();
	MAP.clear();
	V.clear();
	COMBI.clear();

	space_IND = 0;

	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){

			check_hori[row][col] = false;
			check_vert[row][col] = false;
		}
	}

	for(int row = 0; row < H; row++){

		scanf("%s",buf[row]);
		for(int col = 0; col < W; col++){
			if(buf[row][col] == '.'){ //空白セル

				SPACE.push_back(make_pair(row,col));
				MAP[make_pair(row,col)] = space_IND++; //空白セルに番号を割り振る
			}
		}
	}

	scanf("%d",&N);

	char input[2];
	for(int i = 0; i < N; i++){

		scanf("%s",input);
		CAND[i] = input[0];
	}

	//配列の初期化
	for(int i = 0; i < N; i++){

		not_zero[i] = false;
		not_num[i] = false;
		not_op[i] = false;
	}

	//数式の候補を前計算
	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){
			if(buf[row][col] == '#' || buf[row][col] == '=')continue;

			if(!check_hori[row][col]){

				check_hori[row][col] = true;

				//右へ
				vector<pair<int,int>> toR;
				toR.push_back(make_pair(row,col));

				int last_row = row,last_col = col;

				for(int tmp_col = col+1; tmp_col < W; tmp_col++){
					if(buf[row][tmp_col] == '#' || buf[row][tmp_col] == '='){

						break;
					}
					last_col = tmp_col;

					toR.push_back(make_pair(row,tmp_col));
					check_hori[row][tmp_col] = true;
				}

				if((col > 0 && buf[row][col-1] == '=')||(last_col+1 < W && buf[row][last_col+1] == '=')){ //式の左か右に'='がある場合

					for(int i = 0; i < toR.size(); i++){

						hori_IND[toR[i].first][toR[i].second] = V.size();
					}
					if(!checkInvalidEQ(toR)){
						printf("No\n");
						return;
					}

					V.push_back(toR);
				}
			}


			if(!check_vert[row][col]){

				check_vert[row][col] = true;

				//下へ
				vector<pair<int,int>> toD;
				toD.push_back(make_pair(row,col));

				int last_row = row;

				for(int tmp_row = row+1; tmp_row < H; tmp_row++){
					if(buf[tmp_row][col] == '#' || buf[tmp_row][col] == '=')break;

					last_row = tmp_row;

					toD.push_back(make_pair(tmp_row,col));
					check_vert[tmp_row][col] = true;
				}

				if((row > 0 && buf[row-1][col] == '=') || (last_row+1 < H && buf[last_row+1][col] == '=')){ //式の上か下に'='がある場合

					for(int i = 0; i < toD.size(); i++){

						vert_IND[toD[i].first][toD[i].second] = V.size();
					}
					if(!checkInvalidEQ(toD)){
						printf("No\n");
						return;
					}

					V.push_back(toD);
				}
			}
		}
	}

	//比較する数式を前計算
	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){
			if(buf[row][col] != '=')continue;

			int a,b;

			if(col > 0 && col+1 < W && buf[row][col-1] != '#' && buf[row][col+1] != '#'){

				a = hori_IND[row][col-1];
				b = hori_IND[row][col+1];

				//printf("hori (%d,%d)\n",a,b);

				COMBI.push_back(make_pair(a,b));
			}

			if(row > 0 && row+1 < H && buf[row-1][col] != '#' && buf[row+1][col] != '#'){

				a = vert_IND[row-1][col];
				b = vert_IND[row+1][col];

				//printf("vert (%d,%d)\n",a,b);

				COMBI.push_back(make_pair(a,b));
			}
		}
	}

	if(DEBUG){

		for(int i = 0; i < COMBI.size(); i++){

			printf("COMBI:%d (%d,%d)\n",i,COMBI[i].first,COMBI[i].second);
		}
	}

	//計算量を落とすための前処理
	for(int i = 0; i < V.size(); i++){
		for(int k = 0; k < V[i].size(); k++){
			pair<int,int> tmp = V[i][k]; //i個の数式の、k番目の場所

			if(buf[tmp.first][tmp.second] != '.')continue; //空白セルでないならSKIP

			int tmp_ind = MAP[tmp]; //空白セルのインデックスを取得

			if(k == 0){

				not_op[tmp_ind] = true; //先頭なので演算子不可
			}

			if(k == V[i].size()-1){

				not_op[tmp_ind] = true; //数式の末尾に演算子を置くのは不可
			}

			//左に演算子がある場合
			if(k > 0){
				pair<int,int> pre = V[i][k-1];
				if(isOP(buf[pre.first][pre.second])){

					not_op[tmp_ind] = true; //演算子の連続は不可
				}
			}

			//右に演算子があれば不可
			if(k+1 < V[i].size()){
				pair<int,int> next = V[i][k+1];
				if(isOP(buf[next.first][next.second])){

					not_op[tmp_ind] = true; //演算子の連続は不可
				}
			}

			//2つ左に演算子があって、1つ左に0があれば、数字は不可
			if(k >= 2){
				pair<int,int> pre_pre = V[i][k-2];
				pair<int,int> pre = V[i][k-1];
				if(isOP(buf[pre_pre.first][pre_pre.second]) && isZERO(buf[pre.first][pre.second])){

					not_num[tmp_ind] = true;
				}
			}

			//左に演算子があって、右に数字があれば、0は不可
			if(k > 0 && k+1 < V[i].size()){
				pair<int,int> pre = V[i][k-1];
				pair<int,int> next = V[i][k+1];
				if(isOP(buf[pre.first][pre.second]) && isNUM(buf[next.first][next.second])){

					not_zero[tmp_ind] = true;
				}
			}
		}
	}

	num_ORD = 0;


	//空白セルに候補値を割り当て
	for(int i = 0; i < N; i++){

		char ch = CAND[i];
		if((isZERO(ch) && not_zero[0]) || (isOP(ch) && not_op[0]) || (isNUM(ch) && not_num[0]))continue;

		used[i] = true;
		WORK[0] = '0'+i;
		dfs(1);
		used[i] = false;
	}

	if(DEBUG){

		for(int i = 0; i < num_ORD; i++){
			for(int k = 0; k < N; k++){

				printf("%c",ORD[i][k]);
			}
			printf("\n");
		}
		//return;
	}


	for(int loop = 0; loop < num_ORD; loop++){

		if(DEBUG){
		printf("\nloop:%d\n",loop);
		}

		//表を埋める
		for(int i = 0; i < N; i++){
			pair<int,int> tmp = SPACE[i];

			int tmp_ind = ORD[loop][i]-'0';
			//printf("buf[%d][%d]を埋める ",tmp.first,tmp.second);

			buf[tmp.first][tmp.second] = CAND[tmp_ind];

			//printf("ch:%c\n",buf[tmp.first][tmp.second]);
		}
/*
		if(DEBUG){
			printf("\n■デバッグ\n");
			for(int row = 0; row < H; row++){
				for(int col = 0; col < W; col++){

					printf("%c",buf[row][col]);
				}
				printf("\n");
			}
		}*/
		//continue;

		errorFLG = false;
		bool FLG = true;

		for(int i = 0; i < COMBI.size(); i++){

			int a = COMBI[i].first;

			int tmp_ind = 0;
			for(int k = 0; k < V[a].size(); k++){

				pair<int,int> pos = V[a][k];
				eq[tmp_ind] = buf[pos.first][pos.second];
				eq[tmp_ind+1] = '=';
				tmp_ind++;
			}

			INDEX = 0;
			ll result1 = calc_E(eq);

			if(errorFLG)break;

			/*printf("result1:%lld\n",result1);
			for(int k = 0; k < INDEX; k++){

							printf("%c",eq[k]);
						}
						printf("\n");*/


			int b = COMBI[i].second;
			tmp_ind = 0;
			for(int k = 0; k < V[b].size(); k++){

				pair<int,int> pos = V[b][k];
				eq[tmp_ind] = buf[pos.first][pos.second];
				eq[tmp_ind+1] = '=';
				tmp_ind++;
			}

			INDEX = 0;
			ll result2 = calc_E(eq);

			if(errorFLG)break;

			/*printf("result2:%lld\n",result2);
						for(int k = 0; k < INDEX; k++){

										printf("%c",eq[k]);
									}
									printf("\n");*/

			if(result1 != result2){

				FLG = false;
				break;
			}
		}
		if(errorFLG)continue;
		if(FLG){

			/*printf("\n■デバッグ\n");
						for(int row = 0; row < H; row++){
							for(int col = 0; col < W; col++){

								printf("%c",buf[row][col]);
							}
							printf("\n");
						}
			for(int k = 0; k < INDEX; k++){

				printf("%c",eq[k]);
			}
			printf("\n");*/

			printf("Yes\n");
			return;
		}
	}


	printf("No\n");
}


int main(){

	while(true){
		scanf("%d %d",&H,&W);
		if(H == 0 && W == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 530
memory_kb: 38660
final_rank: 20

code_snippet: #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) {
    return (ull)rng() % B;
}
inline double time() {
    return static_cast<long double>(chrono::duration_cast<chrono::nanoseconds>(chrono::steady_clock::now().time_since_epoch()).count()) * 1e-9;
}

bool is_op(char c) {
    return (c == '+' or c == '-' or c == '*' or c == '/');
}

pair<int,bool> eval(string s) {
    if (is_op(s[0]) or is_op(s.back())) return {0,false};
    for (int i = 1; i < s.size(); i++) {
        if (is_op(s[i-1]) and is_op(s[i])) return {0,false};
        if ((i-1 == 0 or !isdigit(s[i-2])) and s[i-1] == '0' and isdigit(s[i])) return {0,false};
    }
    vector<int> v;
    vector<char> op;
    int cur = 0;
    for (char c:s) {
        if (isdigit(c)) {
            cur = cur*10+c-'0';
        }
        else {
            v.push_back(cur);
            cur = 0;
            op.push_back(c);
        }
    }
    v.push_back(cur);
    assert(op.size() + 1 == v.size());
    {
        vector<int> nv = {v[0]};
        vector<char> nop;
        for (int i = 0; i < op.size(); i++) {
            if (op[i] == '*') {
                nv.back() *= v[i+1];
            }
            else if (op[i] == '/') {
                if (v[i+1] == 0 or nv.back() % v[i+1]) {
                    return {0,false};
                }
                nv.back() /= v[i+1];
            }
            else {
                nv.push_back(v[i+1]);
                nop.push_back(op[i]);
            }
        }
        swap(v, nv); swap(op, nop);
    }
    {
        vector<int> nv = {v[0]};
        vector<char> nop;
        for (int i = 0; i < op.size(); i++) {
            if (op[i] == '+') {
                nv.back() += v[i+1];
            }
            else if (op[i] == '-') {
                nv.back() -= v[i+1];
            }
        }
        swap(v, nv); swap(op, nop);
    }
    return {v[0],true};
}

bool dfs(int &h, int &w, vector<string> &s, vector<char> &ad, int i, int j, int bit) {

    if (i == h) {
        return true;
    }
    if (j == w) {
        return dfs(h,w,s,ad,i+1,0,bit);
    }
    if (s[i][j] == '#') {
        if (j and s[i][j-1] != '#') {
            string eq1 = "";
            string eq2 = "";
            bool eql = false;
            int idx = j-1;
            while (0 <= idx and s[i][idx] != '#') {
                if (s[i][idx] == '=') {
                    if (eql) return false;
                    eql = true;
                }
                else {
                    if (!eql) eq1 += s[i][idx];
                    else eq2 += s[i][idx];
                }
                idx--;
            }
            if (idx+1 != j-1) {
                if (eq2.size() == 0) return false;
                reverse(eq1.begin(), eq1.end());
                reverse(eq2.begin(), eq2.end());

                auto r1 = eval(eq1);
                if (!r1.second) return false;
                auto r2 = eval(eq2);
                if (!r2.second) return false;
                if (r1.first != r2.first) return false;
            }
        }
        if (i and s[i-1][j] != '#') {
            string eq1 = "";
            string eq2 = "";
            bool eql = false;
            int idx = i-1;
            while (0 <= idx and s[idx][j] != '#') {
                if (s[idx][j] == '=') {
                    if (eql) return false;
                    eql = true;
                }
                else {
                    if (!eql) eq1 += s[idx][j];
                    else eq2 += s[idx][j];
                }
                idx--;
            }
            if (idx+1 != i-1) {
                if (eq2.size() == 0) return false;
                reverse(eq1.begin(), eq1.end());
                reverse(eq2.begin(), eq2.end());

                auto r1 = eval(eq1);
                if (!r1.second) return false;
                auto r2 = eval(eq2);
                if (!r2.second) return false;
                if (r1.first != r2.first) return false;
            }
        }
    }
    if (s[i][j] != '.') {
        return dfs(h,w,s,ad,i,j+1,bit);
    }
    else {
        for (int k = 0; k < ad.size(); k++) {
            if ((1<<k) & bit) continue;
            s[i][j] = ad[k];
            if (dfs(h,w,s,ad,i,j+1,bit+(1<<k))) {
                return true;
            }
            s[i][j] = '.';
        }
        return false;
    }
}

bool slv(int h, int w) {
    vector<string> s(h);
    for (int i = 0; i < h; i++) {
        cin >> s[i];
        s[i] += '#';
    }
    s.push_back(string(w+1, '#'));
    h++; w++;
    int n; cin >> n;
    vector<char> ad(n);
    for (int i = 0; i < n; i++) {
        cin >> ad[i];
    }
    return dfs(h,w,s,ad,0,0,0);
}

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int h,w;
    while (cin >> h >> w, h) {
        if (slv(h,w)) {
            cout << "Yes" << endl;
        }
        else {
            cout << "No" << endl;
        }
    }
}
accuracy: 1
time_ms: 200
memory_kb: 3388
final_rank: 3

code_snippet: #include <cstdio>
#include <cstdint>
#include <cctype>
#include <cassert>
#include <vector>
#include <string>
#include <algorithm>

constexpr int tsurai=123456789;

int parse_int(const std::string &s, size_t &i) {
  assert(isdigit(s[i]));
  int res=s[i]-'0';
  while (++i < s.length() && isdigit(s[i])) {
    res = res*10 + s[i]-'0';
  }
  return res;
}

int fourt(const std::string &s, size_t &i) {
  int res=0;
  char sgn='+';
  while (i < s.length() && isdigit(s[i])) {
    int cur=parse_int(s, i);
    while (i < s.length() && s[i] != '=') {
      if (s[i] == '*') {
        cur *= parse_int(s, ++i);
      } else if (s[i] == '/') {
        int tmp=parse_int(s, ++i);
        if (tmp == 0 || cur % tmp) return tsurai;
        cur /= tmp;
      } else {
        break;
      }
    }
    if (sgn == '+') {
      res += cur;
    } else {
      res -= cur;
    }
    if (i < s.length() && s[i] != '=') {
      sgn = s[i++];
    }
  }
  return res;
}

bool valid(const std::vector<std::string> &eqs, const std::vector<char> &cs) {
  for (/* not const */ std::string eq: eqs) {
    for (char &ch: eq)
      if (ch >= 'A' && ch <= 'Z')
        ch = cs[ch-'A'];

    if (eq[0] == '=' || !isdigit(eq.back()))
      return false;
    if (std::count(eq.begin(), eq.end(), '=') != 1)
      return false;

    for (size_t i=0; i+1<eq.length(); ++i) {
      if (isdigit(eq[i])) continue;
      if (!isdigit(eq[i+1])) return false;
    }

    for (size_t i=0; i<eq.length(); ++i) {
      if (!isdigit(eq[i])) continue;
      if (eq[i] != '0') {
        do {
          ++i;
        } while (i < eq.length() && isdigit(eq[i]));
      } else {
        if (i+1 < eq.length() && isdigit(eq[i+1]))
          return false;
      }
    }

    size_t i=0;
    if (!isdigit(eq[i])) return false;
    int lhs=fourt(eq, i);
    if (lhs == tsurai) return false;
    assert(eq[i] == '=');
    ++i;
    if (!isdigit(eq[i])) return false;
    int rhs=fourt(eq, i);
    if (rhs == tsurai) return false;
    assert(i == eq.length());
    
    if (lhs != rhs)
      return false;
  }
  return true;
}

int testcase_ends() {
  size_t H, W;
  scanf("%zu %zu", &H, &W);

  if (H == 0 && W == 0)
    return 1;

  size_t ph='A';  // placeholder
  std::vector<std::string> s(H);
  for (size_t i=0; i<H; ++i) {
    char buf[16];
    scanf("%s", buf);
    s[i] = buf;
    for (size_t j=0; j<W; ++j) {
      if (s[i][j] == '.')
        s[i][j] = ph++;
    }
  }

  std::vector<std::string> eqs;
  for (size_t i=0; i<H; ++i) {
    std::string eq="";
    for (size_t j=0; j<W; ++j) {
      if (s[i][j] != '#') {
        eq += s[i][j];
      } else {
        if (eq.size() >= 3)
          eqs.emplace_back(eq);
        eq = "";
      }
    }
    if (eq.size() >= 3)
      eqs.emplace_back(eq);
  }

  for (size_t j=0; j<W; ++j) {
    std::string eq="";
    for (size_t i=0; i<H; ++i) {
      if (s[i][j] != '#') {
        eq += s[i][j];
      } else {
        if (eq.size() >= 3)
          eqs.emplace_back(eq);
        eq = "";
      }
    }
    if (eq.size() >= 3)
      eqs.emplace_back(eq);
  }

  size_t n;
  scanf("%zu", &n);
  std::vector<char> cs(n);
  for (size_t i=0; i<n; ++i)
    scanf(" %c", &cs[i]);

  std::sort(cs.begin(), cs.end());
  do {
    if (valid(eqs, cs))
      return !printf("Yes\n");
  } while (std::next_permutation(cs.begin(), cs.end()));
  printf("No\n");
  return 0;
}

int main() {
  while (!testcase_ends()) {}
}
accuracy: 1
time_ms: 590
memory_kb: 2812
final_rank: 12

code_snippet: #include <cstdio>
#include <cctype>
#include <cassert>
#include <cstdint>
#include <string>
#include <vector>
#include <algorithm>

#define fprintf(...) (void)0

int parse_int(std::string &s, size_t &i) {
  assert(isdigit(s[i]));
  int res=s[i++]-'0';
  while (isdigit(s[i])) {
    res = res*10 + s[i++]-'0';
  }
  return res;
}

int parse(std::string &s, size_t &i, bool &succ) {
  if (i == s.length()) {
    succ = false;
    return -1;
  }

  if (s[i] == '+' || s[i] == '-') {
    succ = false;
    return -1;
  }

  int res=0;
  char sgn='+';
  while (i < s.length()) {
    assert(isdigit(s[i]));

    int cur=parse_int(s, i);
    while (true) {
      if (s[i] == '*') {
        cur *= parse_int(s, ++i);
      } else if (s[i] == '/') {
        int tmp=parse_int(s, ++i);
        if (tmp == 0 || cur % tmp != 0) {
          succ = false;
          return -1;
        }
        cur /= tmp;
      } else {
        break;
      }
    }

    if (sgn == '+') {
      res += cur;
    } else if (sgn == '-') {
      res -= cur;
    }

    if (i == s.length() || s[i] == '=')
      return res;

    sgn = s[i++];
  }
  return res;
}

bool solved(const std::vector<std::string> &eqs, const std::vector<char> &ch) {
  fprintf(stderr, ": ");
  for (size_t i=0; i<ch.size(); ++i)
    fprintf(stderr, "%c%c", ch[i], i+1<ch.size()? ' ':'\n');

  for (auto eq: eqs) {
    size_t i=0;

    for (char &c: eq)
      if (c >= 'A' && c <= 'Z')
        c = ch[c-'A'];

    fprintf(stderr, "# %s\n", eq.c_str());

    if (eq[0] == '=' || eq.back() == '=') return false;
    if (!isdigit(eq[0]) || !isdigit(eq.back())) return false;
    for (size_t i=0; i+1<eq.length(); ++i) {
      if (isdigit(eq[i])) continue;
      if (!isdigit(eq[i+1])) return false;
    }

    for (size_t i=0; i<eq.length(); ++i) {
      if (!isdigit(eq[i])) continue;
      if (eq[i] == '0') {
        if (i+1 < eq.length() && isdigit(eq[i+1]))
          return false;
      }
      while (i+1 < eq.length() && isdigit(eq[i+1])) {
        ++i;
      }
    }

    if (std::count(eq.begin(), eq.end(), '=') != 1)
      return false;

    bool succ=true;
    int lhs=parse(eq, i, succ);
    if (!succ) return false;
    assert(eq[i] == '=');
    ++i;
    succ = true;
    int rhs=parse(eq, i, succ);
    if (!succ) return false;

    fprintf(stderr, "%s: %d %d\n", eq.c_str(), lhs, rhs);

    if (lhs != rhs)
      return false;
  }
  return true;
}

int testcase_ends() {
  size_t H, W;
  scanf("%zu %zu", &H, &W);

  if (H == 0 && W == 0) return 1;

  std::vector<std::string> g(H);
  for (size_t i=0; i<H; ++i) {
    char buf[16];
    scanf("%s", buf);
    g[i] = buf;
  }

  size_t n;
  scanf("%zu", &n);
  std::vector<char> ch(n);
  for (size_t i=0; i<n; ++i) {
    scanf(" %c", &ch[i]);
  }

  char ph='A';
  for (size_t i=0; i<H; ++i)
    for (size_t j=0; j<W; ++j)
      if (g[i][j] == '.')
        g[i][j] = ph++;

  std::vector<std::string> eqs;

  for (size_t i=0; i<H; ++i) {
    std::string eq="";
    for (size_t j=0; j<W; ++j) {
      if (g[i][j] == '#') {
        if (eq.size() >= 3) {
          eqs.emplace_back(eq);
        }
        eq = "";
        continue;
      }

      eq += g[i][j];
    }
    if (eq.size() >= 3)
      eqs.emplace_back(eq);
  }

  for (size_t j=0; j<W; ++j) {
    std::string eq="";
    for (size_t i=0; i<H; ++i) {
      if (g[i][j] == '#') {
        if (eq.size() >= 3) {
          eqs.emplace_back(eq);
        }
        eq = "";
        continue;
      }

      eq += g[i][j];
    }
    if (eq.size() >= 3)
      eqs.emplace_back(eq);
  }

  std::sort(ch.begin(), ch.end());
  do {
    if (solved(eqs, ch)) {
      printf("Yes\n");
      return 0;
    }
  } while (std::next_permutation(ch.begin(), ch.end()));

  printf("No\n");
  return 0;
}

int main() {
  while (!testcase_ends()) {}
}
accuracy: 1
time_ms: 610
memory_kb: 2788
final_rank: 13

code_snippet: // AOJ 1022
#include<iostream>
#include<string>
#include<map>
#include<algorithm>
#include<vector>
#define value first
#define p second
using namespace std;
typedef pair<int,int> result;
 
const int OutOfIntExc = 1,
          NegIntExc = 2,
          NotEquationExc = 3,
          NotNumExc = 4,
          LackNumExc = 5,
          IterExceedExc = 6;
 
result equation(const string &s, int p = 0);
result expression(const string &s, int p = 0);
result factor(const string &s, int p = 0);
result term(const string &s, int p = 0);
 
result equation(const string &s, int p) {
//  cout << "? " << s << " ";
  if (s[p] == '=') { throw NotEquationExc; }
  result r = expression(s, p);
  if (s[r.p] != '=') { throw NotEquationExc; }
   
  r.p++; // skip '=';
  result t = expression(s, r.p);
  t.value = (int)(r.value == t.value);
 
//  cout << (t.value ? "T" : "F") << endl;
   
  return t;
}
 
 
result expression(const string &s, int p) {
  result r = factor(s, p);
  while (s[r.p] == '+' or s[r.p] == '-') {
    result r_ = factor(s, r.p+1);
    r.value += (s[r.p] == '+' ? r_.value : - r_.value);
    if (r.value < 0) { throw NegIntExc; }
    r.p = r_.p;
  }
  return r;
}
 
result factor(const string &s, int p) {
  result r = term(s, p);
  while (s[r.p] == '*' or s[r.p] == '/') {
    result r_ = term(s, r.p+1);
    if (s[r.p] == '*') {
      r.value *= r_.value;
    } else {
      if (r_.value == 0 or r.value % r_.value != 0) {
        throw OutOfIntExc;
      }
      r.value /= r_.value;
    }
    r.p = r_.p;
  }
  return r;
}
 
result term(const string &s, int p) {
  if (not isdigit(s[p])) { throw LackNumExc; }
  int value = 0;
  bool flag = false;
 
  while (isdigit(s[p])) {
    if (flag and value == 0) { throw NotNumExc; }
    flag = true;
    value = value * 10 + (s[p++] - '0');
  }
  return result(value, p);
}
 
#define REP(i,n) for(int i=0;i<(int)(n);i++)
int H, W, n;
const int HMAX = 200, WMAX = 200, NMAX = 200;
char TABLE[HMAX][WMAX];
bool PRINTED[HMAX][WMAX], HBEGIN[HMAX][WMAX], VBEGIN[HMAX][WMAX];
char BLOCK[NMAX];
 
bool legal(int x, int y) {
  return 0 <= x and x < W and 0 <= y and y < H;
}
 
vector<pair<int,int>> blanks;
 
void fill_blank() {
  int i = 0;
  REP(i, n) {
    int x = blanks[i].first, y = blanks[i].second;
    TABLE[x][y] = BLOCK[i];
  }
}
 
string getv(int x, int y) {
  string str;
  while (legal(x, y) and TABLE[x][y] != '#') {
    str.push_back(TABLE[x][y]);
    y++;
  }
  return str;
}
 
string geth(int x, int y) {
  string str;
  while (legal(x, y) and TABLE[x][y] != '#') {
    str.push_back(TABLE[x][y]);
    x++;
  }
  return str;
}
 
bool is_operand(char c) {
  return c == '=' or c == '+' or c == '-' or c == '*' or c == '/';
}
 
bool is_illegal_operand() {
  REP(y, H) REP(x, W) {
    if (PRINTED[x][y]) continue;
    if (not is_operand(TABLE[x][y])) continue;
    const int dx[4] = {0, 1, 0, -1}, dy[4] = {-1, 0, 1, 0};
    REP(i, 4) {
      int nx = x + dx[i], ny = y + dy[i];
      if (legal(nx, ny) and is_operand(TABLE[nx][ny])) {
        return true;
      }
    }
  }
 
  REP(y, H) REP(x,W) {
    if ((VBEGIN[x][y] or HBEGIN[x][y]) and is_operand(TABLE[x][y])) {
      return true;
    }
  }
  return false;
}
 
int hbadx, hbady, vbadx, vbady;
bool hbadflag, vbadflag;
string hbadeq, vbadeq;
 
bool solved() {
  if (hbadflag and geth(hbadx, hbady) == hbadeq) return false;
  if (vbadflag and geth(vbadx, vbady) == vbadeq) return false;
  REP(y, H) REP(x, W) {
    if (not HBEGIN[x][y]) continue;
    string eq = geth(x, y);
    try {
      result e = equation(eq);
      if (e.value == 0) {
        hbadflag = true;
        hbadx = x, hbady = y;
        hbadeq = eq;
        return false;
      }
    } catch (int ex) {
      hbadflag = true;
      hbadx = x, hbady = y;
      hbadeq = eq;
      return false;
    }
  }
 
  REP(y, H) REP(x, W) {
    if (not VBEGIN[x][y]) continue;
    string eq = getv(x, y);
    try {
      result e = equation(eq);
      if (e.value == 0) {
        vbadflag = true;
        vbadx = x, vbady = y;
        vbadeq = eq;
        return false;
      }
    } catch(int ex) {
      vbadflag = true;
      vbadx = x, vbady = y;
      vbadeq = eq;
      return false;
    }
  }
  return true;
}
 
bool solve() {
  sort(BLOCK, BLOCK + n);
  do {
    fill_blank();
    if (is_illegal_operand()) continue;
    if (solved()) { return true; }
  } while (next_permutation(BLOCK, BLOCK + n));
}
 
void init() {
  blanks.clear();
  REP(y, H) REP(x, W) {
    hbadflag = vbadflag = false;
    PRINTED[x][y] = false;
    HBEGIN[x][y] = false;
    VBEGIN[x][y] = false;
  }
}
 
int main() {
  while (cin >> H >> W and H + W) {
    init();
 
    REP(y, H) {
      string row;
      cin >> row;
      REP(x, W) {
        TABLE[x][y] = row[x];
        PRINTED[x][y] = row[x] != '.';
        if (row[x] == '.') {
          blanks.push_back(make_pair(x, y));
        }
      }
    }
 
    REP(y, H) REP(x, W) {
      if (TABLE[x][y]!='#' and legal(x+1,y) and TABLE[x+1][y]!='#'
          and (!legal(x-1,y) or TABLE[x-1][y] == '#')) {
        HBEGIN[x][y] = true;
      }
      if (TABLE[x][y]!='#' and legal(x,y+1) and TABLE[x][y+1]!='#'
          and (!legal(x,y-1) or TABLE[x][y-1] == '#')) {
        VBEGIN[x][y] = true;
      }
    }
 
    cin >> n;
    REP(i, n) { cin >> BLOCK[i]; }
 
    cout << (solve() ? "Yes" : "No") << endl;
  }
}
accuracy: 1
time_ms: 800
memory_kb: 1312
final_rank: 16

code_snippet: #include<bits/stdc++.h>
#define rep(i,n) for(int i=0;i<(int)(n);i++)
using namespace std;

const int inf = 1e9;

int h,w,n;
string g[10];
char c[10];
bool use[10];
int l[10][10], r[10][10], u[10][10], d[10][10];

inline bool valid(const string &s){
  rep(i,s.size()){
    if(s[i]=='0' && (i==0 || !isdigit(s[i-1])) && (i+1<(int)s.size() && isdigit(s[i+1]))){
      return false;
    }
    if(!isdigit(s[i]) && (i==0 || !isdigit(s[i-1]))){
      return false;
    }
  }
  return isdigit(s.back());
}

int parse(int L, int R, const string &s){
  for(int i=R-1;i>=L;i--){
    if(s[i] == '+' || s[i] == '-'){
      int a = parse(L,i,s), b = parse(i+1,R,s);
      if(a==inf || b==inf)return inf;
      if(s[i] == '+')return a+b;
      if(s[i] == '-')return a-b;
    }
  }

  for(int i=R-1;i>=L;i--){
    if(s[i] == '*' || s[i] == '/'){
      int a = parse(L,i,s), b = parse(i+1,R,s);
      if(a==inf || b==inf)return inf;
      if(s[i] == '*')return a*b;
      if(s[i] == '/'){
	if(b==0 || a%b)return inf;
	return a/b;
      }
    }
  }

  int res = 0;
  for(int i=L;i<R;i++)res = res*10 + (int)(s[i]-'0');
  return res;
}

inline bool check(const string &s){
  if(!valid(s))return false;

  int p = 0;
  while(s[p]!='=')p++;
  assert(p!=(int)s.size());
  int a = parse(0,p,s);
  int b = parse(p+1,s.size(),s);
  if(a==inf || b==inf)return false;
  return a==b;
}

bool solve(int y, int x){
  if(y==h)return true;

  int ny = y, nx = x+1;
  if(nx==w)ny++, nx=0;

  if(g[y][x] != '.')return solve(ny,nx);

  rep(i,n){
    if(!use[i]){
      use[i] = 1;
      g[y][x] = c[i];

      bool f = true;
      if(l[y][x]>=0){
	string s;
	for(int j=l[y][x];j<r[y][x];j++)s += g[y][j];
	if(!check(s))f = false;
      }

      if(f && u[y][x]>=0){
	string s;
	for(int j=u[y][x];j<d[y][x];j++)s += g[j][x];
	if(!check(s))f = false;
      }

      if(f && solve(ny,nx))return true;

      g[y][x] = '.';
      use[i] = 0;
    }
  }
  return false;
}

int main(){
  cin.tie(0); ios::sync_with_stdio(0);
  while(cin >> h >> w, h){
    rep(i,h)cin >> g[i];
    cin >> n;
    rep(i,n)cin >> c[i];

    memset(l,-1,sizeof(l)); memset(r,-1,sizeof(r));
    memset(u,-1,sizeof(u)); memset(d,-1,sizeof(d));
    rep(i,h)rep(j,w){
      if(g[i][j] == '.'){
	int cnt = 0;
	for(int k=j+1;k<w;k++){
	  if(g[i][k] == '.')cnt++;
	  if(g[i][k] == '#')break;
	}
	if(cnt==0){
	  l[i][j] = 0; r[i][j] = w;
	  for(int k=j-1;k>=0;k--){
	    if(g[i][k] == '#'){
	      l[i][j] = k+1;
	      break;
	    }
	  }
	  for(int k=j+1;k<w;k++){
	    if(g[i][k] == '#'){
	      r[i][j] = k;
	      break;
	    }
	  }
	  if(r[i][j]-l[i][j]<3)r[i][j] = l[i][j] = -1;
	}

	cnt = 0;
	for(int k=i+1;k<h;k++){
	  if(g[k][j] == '.')cnt++;
	  if(g[k][j] == '#')break;
	}
	if(cnt==0){
	  u[i][j] = 0; d[i][j] = h;
	  for(int k=i-1;k>=0;k--){
	    if(g[k][j] == '#'){
	      u[i][j] = k+1;
	      break;
	    }
	  }
	  for(int k=i+1;k<h;k++){
	    if(g[k][j] == '#'){
	      d[i][j] = k;
	      break;
	    }
	  }
	  if(d[i][j]-u[i][j]<3)d[i][j] = u[i][j] = -1;
	}
      }
    }
    
    memset(use,0,sizeof(use));
    if(solve(0,0))cout << "Yes" << endl;
    else cout << "No" << endl;
  }
}
accuracy: 1
time_ms: 530
memory_kb: 1208
final_rank: 8

code_snippet: #include<bits/stdc++.h>
#define rep(i,n) for(int i=0;i<(int)(n);i++)
using namespace std;
typedef long long ll;

const ll inf = 1e15;

int h,w,n;
string g[10];
char c[10];
bool use[10];
int l[10][10], r[10][10], u[10][10], d[10][10];

inline bool valid(const string &s){
  rep(i,s.size()){
    if( s[i]=='0' && (i==0 || !isdigit(s[i-1])) && (i+1<(int)s.size() && isdigit(s[i+1]))){
      return false;
    }
    if( i>0 && !isdigit(s[i]) && !isdigit(s[i-1])){
      return false;
    }
  }
  if(!isdigit(s[0]) || !isdigit(s.back()))return false;
  return true;
}

ll parse(int L, int R, const string &s){
  assert(R!=L);
  for(int i=R-1;i>=L;i--){
    if(s[i] == '+' || s[i] == '-'){
      ll a = parse(L,i,s), b = parse(i+1,R,s);
      if(a==inf || b==inf)return inf;
      if(s[i] == '+')return a+b;
      if(s[i] == '-')return a-b;
    }
  }

  for(int i=R-1;i>=L;i--){
    if(s[i] == '*' || s[i] == '/'){
      ll a = parse(L,i,s), b = parse(i+1,R,s);
      if(a==inf || b==inf)return inf;
      if(s[i] == '*')return a*b;
      if(s[i] == '/'){
	if(b==0 || a%b)return inf;
	return a/b;
      }
    }
  }

  ll res = 0;
  for(int i=L;i<R;i++)res = res*10LL + (ll)(s[i]-'0');
  return res;
}

inline bool check(const string &s){
  if(!valid(s))return false;

  int p = 0;
  while(s[p]!='=')p++;
  assert(p!=(int)s.size());
  ll a = parse(0,p,s);
  ll b = parse(p+1,s.size(),s);
  if(a==inf || b==inf)return false;
  return a==b;
}

bool solve(int y, int x){
  if(y==h)return true;

  int ny = y, nx = x+1;
  if(nx==w)ny++, nx=0;

  if(g[y][x] != '.')return solve(ny,nx);

  rep(i,n){
    if(!use[i]){
      use[i] = 1;
      g[y][x] = c[i];

      bool f = true;
      if(l[y][x]>=0){
	string s;
	for(int j=l[y][x];j<r[y][x];j++)s += g[y][j];
	if(!check(s))f = false;
      }

      if(f && u[y][x]>=0){
	string s;
	for(int j=u[y][x];j<d[y][x];j++)s += g[j][x];
	if(!check(s))f = false;
      }

      if(f && solve(ny,nx))return true;

      g[y][x] = '.';
      use[i] = 0;
    }
  }
  return false;
}

int main(){
  cin.tie(0); ios::sync_with_stdio(0);
  while(cin >> h >> w, h){
    rep(i,h)cin >> g[i];
    cin >> n;
    rep(i,n)cin >> c[i];

    bool f = true;
    rep(i,h)rep(j,w){
      if(j==0 || g[i][j-1]=='#'){
	string tmp;
	rep(k,w){
	  if(g[i][k] == '#')break;
	  tmp += g[i][k];
	}
	if(tmp.size()>=3 && tmp.find('.')==string::npos && !check(tmp))f = false;
      }

      if(i==0 || g[i-1][j]=='#'){
	string tmp;
	rep(k,h){
	  if(g[k][j] == '#')break;
	  tmp += g[k][j];
	}
	if(tmp.size()>=3 && tmp.find('.')==string::npos && !check(tmp))f = false;
      }
    }

    if(!f){
      cout << "No" << endl;
      continue;
    }

    memset(l,-1,sizeof(l)); memset(r,-1,sizeof(r));
    memset(u,-1,sizeof(u)); memset(d,-1,sizeof(d));
    rep(i,h)rep(j,w){
      if(g[i][j] == '.'){
	int cnt = 0;
	for(int k=j+1;k<w;k++){
	  if(g[i][k] == '.')cnt++;
	  if(g[i][k] == '#')break;
	}
	if(cnt==0){
	  l[i][j] = 0; r[i][j] = w;
	  for(int k=j-1;k>=0;k--){
	    if(g[i][k] == '#'){
	      l[i][j] = k+1;
	      break;
	    }
	  }
	  for(int k=j+1;k<w;k++){
	    if(g[i][k] == '#'){
	      r[i][j] = k;
	      break;
	    }
	  }
	  if(r[i][j]-l[i][j]<3)r[i][j] = l[i][j] = -1;
	}

	cnt = 0;
	for(int k=i+1;k<h;k++){
	  if(g[k][j] == '.')cnt++;
	  if(g[k][j] == '#')break;
	}
	if(cnt==0){
	  u[i][j] = 0; d[i][j] = h;
	  for(int k=i-1;k>=0;k--){
	    if(g[k][j] == '#'){
	      u[i][j] = k+1;
	      break;
	    }
	  }
	  for(int k=i+1;k<h;k++){
	    if(g[k][j] == '#'){
	      d[i][j] = k;
	      break;
	    }
	  }
	  if(d[i][j]-u[i][j]<3)d[i][j] = u[i][j] = -1;
	}
      }
    }
    
    memset(use,0,sizeof(use));
    if(solve(0,0))cout << "Yes" << endl;
    else cout << "No" << endl;
  }
}
accuracy: 1
time_ms: 510
memory_kb: 1216
final_rank: 6

code_snippet: // AOJ 1022
#include<iostream>
#include<string>
#include<map>
#include<algorithm>
#include<vector>
#define value first
#define p second
using namespace std;
typedef pair<int,int> result;

const int OutOfIntExc = 1,
          NegIntExc = 2,
          NotEquationExc = 3,
          NotNumExc = 4,
          LackNumExc = 5,
          IterExceedExc = 6;

result equation(const string &s, int p = 0);
result expression(const string &s, int p = 0);
result factor(const string &s, int p = 0);
result term(const string &s, int p = 0);

result equation(const string &s, int p) {
//  cout << "? " << s << " ";
  if (s[p] == '=') { throw NotEquationExc; }
  result r = expression(s, p);
  if (s[r.p] != '=') { throw NotEquationExc; }
  
  r.p++; // skip '=';
  result t = expression(s, r.p);
  t.value = (int)(r.value == t.value);

//  cout << (t.value ? "T" : "F") << endl;
  
  return t;
}


result expression(const string &s, int p) {
  result r = factor(s, p);
  while (s[r.p] == '+' or s[r.p] == '-') {
    result r_ = factor(s, r.p+1);
    r.value += (s[r.p] == '+' ? r_.value : - r_.value);
    if (r.value < 0) { throw NegIntExc; }
    r.p = r_.p;
  }
  return r;
}

result factor(const string &s, int p) {
  result r = term(s, p);
  while (s[r.p] == '*' or s[r.p] == '/') {
    result r_ = term(s, r.p+1);
    if (s[r.p] == '*') {
      r.value *= r_.value;
    } else {
      if (r_.value == 0 or r.value % r_.value != 0) { 
        throw OutOfIntExc; 
      }
      r.value /= r_.value;
    }
    r.p = r_.p;
  }
  return r;
}

result term(const string &s, int p) {
  if (not isdigit(s[p])) { throw LackNumExc; }
  int value = 0;
  bool flag = false;

  while (isdigit(s[p])) {
    if (flag and value == 0) { throw NotNumExc; }
    flag = true;
    value = value * 10 + (s[p++] - '0');
  }
  return result(value, p);
}

#define REP(i,n) for(int i=0;i<(int)(n);i++)
int H, W, n;
const int HMAX = 200, WMAX = 200, NMAX = 200;
char TABLE[HMAX][WMAX];
bool PRINTED[HMAX][WMAX], HBEGIN[HMAX][WMAX], VBEGIN[HMAX][WMAX];
char BLOCK[NMAX];

bool legal(int x, int y) {
  return 0 <= x and x < W and 0 <= y and y < H;
}

vector<pair<int,int>> blanks;

void fill_blank() {
  int i = 0;
  REP(i, n) {
    int x = blanks[i].first, y = blanks[i].second;
    TABLE[x][y] = BLOCK[i];
  }
}

string getv(int x, int y) {
  string str;
  while (legal(x, y) and TABLE[x][y] != '#') { 
    str.push_back(TABLE[x][y]);
    y++; 
  }
  return str;
}

string geth(int x, int y) {
  string str;
  while (legal(x, y) and TABLE[x][y] != '#') { 
    str.push_back(TABLE[x][y]);
    x++; 
  }
  return str;
}

bool is_operand(char c) {
  return c == '=' or c == '+' or c == '-' or c == '*' or c == '/';
}

bool is_illegal_operand() {
  REP(y, H) REP(x, W) {
    if (PRINTED[x][y]) continue;
    if (not is_operand(TABLE[x][y])) continue;
    const int dx[4] = {0, 1, 0, -1}, dy[4] = {-1, 0, 1, 0};
    REP(i, 4) {
      int nx = x + dx[i], ny = y + dy[i];
      if (legal(nx, ny) and is_operand(TABLE[nx][ny])) {
        return true;
      }
    }
  }

  REP(y, H) REP(x,W) {
    if ((VBEGIN[x][y] or HBEGIN[x][y]) and is_operand(TABLE[x][y])) {
      return true;
    }
  }
  return false;
}

int hbadx, hbady, vbadx, vbady;
bool hbadflag, vbadflag;
string hbadeq, vbadeq;

bool solved() {
  if (hbadflag and geth(hbadx, hbady) == hbadeq) return false;
  if (vbadflag and geth(vbadx, vbady) == vbadeq) return false;
  REP(y, H) REP(x, W) {
    if (not HBEGIN[x][y]) continue;
    string eq = geth(x, y);
    try {
      result e = equation(eq);
      if (e.value == 0) {
        hbadflag = true;
        hbadx = x, hbady = y;
        hbadeq = eq;
        return false; 
      }
    } catch (int ex) {
      hbadflag = true;
      hbadx = x, hbady = y;
      hbadeq = eq;
      return false;
    }
  }

  REP(y, H) REP(x, W) {
    if (not VBEGIN[x][y]) continue;
    string eq = getv(x, y);
    try {
      result e = equation(eq);
      if (e.value == 0) {
        vbadflag = true;
        vbadx = x, vbady = y;
        vbadeq = eq;
        return false; 
      }
    } catch(int ex) {
      vbadflag = true;
      vbadx = x, vbady = y;
      vbadeq = eq;
      return false;
    }
  }
  return true;
}

bool solve() {
  sort(BLOCK, BLOCK + n);
  do {
    fill_blank();
    if (is_illegal_operand()) continue;
    if (solved()) { return true; }
  } while (next_permutation(BLOCK, BLOCK + n));
}

void init() {
  blanks.clear();
  REP(y, H) REP(x, W) {
    hbadflag = vbadflag = false;
    PRINTED[x][y] = false;
    HBEGIN[x][y] = false;
    VBEGIN[x][y] = false;
  }
}

int main() {
  while (cin >> H >> W and H + W) {
    init();

    REP(y, H) {
      string row;
      cin >> row;
      REP(x, W) {
        TABLE[x][y] = row[x];
        PRINTED[x][y] = row[x] != '.';
        if (row[x] == '.') {
          blanks.push_back(make_pair(x, y));
        }
      }
    }

    REP(y, H) REP(x, W) {
      if (TABLE[x][y]!='#' and legal(x+1,y) and TABLE[x+1][y]!='#'
          and (!legal(x-1,y) or TABLE[x-1][y] == '#')) {
        HBEGIN[x][y] = true;
      }
      if (TABLE[x][y]!='#' and legal(x,y+1) and TABLE[x][y+1]!='#'
          and (!legal(x,y-1) or TABLE[x][y-1] == '#')) {
        VBEGIN[x][y] = true;
      }
    }

    cin >> n;
    REP(i, n) { cin >> BLOCK[i]; }

    cout << (solve() ? "Yes" : "No") << endl;
  }
}
accuracy: 1
time_ms: 810
memory_kb: 1312
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define dump(...) cout<<"# "<<#__VA_ARGS__<<'='<<(__VA_ARGS__)<<endl
#define repi(i,a,b) for(int i=int(a);i<int(b);i++)
#define peri(i,a,b) for(int i=int(b);i-->int(a);)
#define rep(i,n) repi(i,0,n)
#define per(i,n) peri(i,0,n)
#define all(c) begin(c),end(c)
#define mp make_pair
#define mt make_tuple

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<string> vs;

template<typename T1,typename T2>
ostream& operator<<(ostream& os,const pair<T1,T2>& p){
	return os<<'('<<p.first<<','<<p.second<<')';
}

template<typename Tuple>
void print_tuple(ostream&,const Tuple&){}
template<typename Car,typename... Cdr,typename Tuple>
void print_tuple(ostream& os,const Tuple& t){
	print_tuple<Cdr...>(os,t);
	os<<(sizeof...(Cdr)?",":"")<<get<sizeof...(Cdr)>(t);
}
template<typename... Args>
ostream& operator<<(ostream& os,const tuple<Args...>& t){
	print_tuple<Args...>(os<<'(',t);
	return os<<')';
}

template<typename Ch,typename Tr,typename C>
basic_ostream<Ch,Tr>& operator<<(basic_ostream<Ch,Tr>& os,const C& c){
	os<<'[';
	for(auto i=begin(c);i!=end(c);++i)
		os<<(i==begin(c)?"":" ")<<*i;
	return os<<']';
}

constexpr int INF=1e9;
constexpr int MOD=1e9+7;
constexpr double EPS=1e-9;

tuple<int,int> number(const string& s,int i)
{
	int x=0;
	if(i>=s.size() || !isdigit(s[i])) return mt(INF,-1);
	for(int len=0;i<s.size() && isdigit(s[i]);i++,len++){
		if(len==1 && x==0) return mt(INF,-1);
		x=x*10+s[i]-'0';
	}
	return mt(x,i);
}
tuple<int,int> term(const string& s,int i)
{
	int x; tie(x,i)=number(s,i);
	if(i==-1) return mt(INF,-1);
	while(i<s.size() && (s[i]=='*' || s[i]=='/')){
		char op=s[i];
		int y; if(get<1>(tie(y,i)=number(s,i+1))==-1) return mt(INF,-1);
		if(op=='*') x*=y;
		if(op=='/'){
			if(y==0 || x%y>0) return mt(INF,-1);
			x/=y;
		}
	}
	return mt(x,i);
}
tuple<int,int> expr(const string& s,int i)
{
	int x; if(get<1>(tie(x,i)=term(s,i))==-1) return mt(INF,-1);
	while(i<s.size()){
		char op=s[i];
		if(op!='+' && op!='-') return mt(INF,-1);
		int y; if(get<1>(tie(y,i)=term(s,i+1))==-1) return mt(INF,-1);
		if(op=='+') x+=y;
		if(op=='-') x-=y;
	}
	return mt(x,i);
}

bool check(const vector<char*>& f)
{
	string s; for(char* p:f) s+=*p;
	if(count(all(s),'=')!=1) return false;
	int eq=s.find('=');
	if(eq==0 || eq==s.size()-1) return false;
	string a=s.substr(0,eq),b=s.substr(eq+1);
	auto x=get<0>(expr(a,0)),y=get<0>(expr(b,0));
	return x!=INF && y!=INF && x==y;
}

bool solve(int i,vs& grid,string& cs,const vi& is,const vi& js,const vector<vector<char*>>& fs,const vvi& ds)
{
	if(i==cs.size()) return true;
	
	for(char& c:cs) if(c!='X'){
		grid[is[i]][js[i]]=c; c='X';
		if(all_of(all(ds[i]),[&](int j){return check(fs[j]);}))
			if(solve(i+1,grid,cs,is,js,fs,ds))
				return true;
		c=grid[is[i]][js[i]];
	}
	return false;
}

int main()
{
	for(int h,w;cin>>h>>w && h|w;){
		vs grid(h);
		rep(i,h) cin>>grid[i];
		int n; cin>>n;
		string cs(n,'~');
		rep(i,n) cin>>cs[i];
		
		vi is,js;
		rep(i,h) rep(j,w) if(grid[i][j]=='.'){
			is.push_back(i);
			js.push_back(j);
		}
		vector<vector<char*>> fs;
		rep(i,h) rep(j,w) if(grid[i][j]!='#'){
			if((i==0 || grid[i-1][j]=='#') && i<h-1 && grid[i+1][j]!='#'){
				vector<char*> f;
				for(int k=i;k<h && grid[k][j]!='#';k++)
					f.push_back(&grid[k][j]);
				fs.push_back(f);
			}
			if((j==0 || grid[i][j-1]=='#') && j<w-1 && grid[i][j+1]!='#'){
				vector<char*> f;
				for(int k=j;k<w && grid[i][k]!='#';k++)
					f.push_back(&grid[i][k]);
				fs.push_back(f);
			}
		}
		
		if(any_of(all(fs),[&](const vector<char*>& f)->bool{
				string s; for(char* p:f) s+=*p;
				return s.find('.')==-1 && !check(f);
			})){
			cout<<"No!"<<endl;
			continue;
		}
		
		vvi ds(n);
		{
			vi vis(fs.size());
			rep(i,n){
				grid[is[i]][js[i]]='?';
				rep(j,fs.size()) if(!vis[j]){
					string s; for(char* p:fs[j]) s+=*p;
					if(s.find('.')==-1)
						ds[i].push_back(j),vis[j]=1;
				}
			}
			rep(i,n) grid[is[i]][js[i]]='.';
		}
		
		cout<<(solve(0,grid,cs,is,js,fs,ds)?"Yes":"No")<<endl;
	}
}
accuracy: 1
time_ms: 620
memory_kb: 1240
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define dump(...) cout<<"# "<<#__VA_ARGS__<<'='<<(__VA_ARGS__)<<endl
#define repi(i,a,b) for(int i=int(a);i<int(b);i++)
#define peri(i,a,b) for(int i=int(b);i-->int(a);)
#define rep(i,n) repi(i,0,n)
#define per(i,n) peri(i,0,n)
#define all(c) begin(c),end(c)
#define mp make_pair
#define mt make_tuple

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<string> vs;

template<typename T1,typename T2>
ostream& operator<<(ostream& os,const pair<T1,T2>& p){
	return os<<'('<<p.first<<','<<p.second<<')';
}

template<typename Tuple>
void print_tuple(ostream&,const Tuple&){}
template<typename Car,typename... Cdr,typename Tuple>
void print_tuple(ostream& os,const Tuple& t){
	print_tuple<Cdr...>(os,t);
	os<<(sizeof...(Cdr)?",":"")<<get<sizeof...(Cdr)>(t);
}
template<typename... Args>
ostream& operator<<(ostream& os,const tuple<Args...>& t){
	print_tuple<Args...>(os<<'(',t);
	return os<<')';
}

template<typename Ch,typename Tr,typename C>
basic_ostream<Ch,Tr>& operator<<(basic_ostream<Ch,Tr>& os,const C& c){
	os<<'[';
	for(auto i=begin(c);i!=end(c);++i)
		os<<(i==begin(c)?"":" ")<<*i;
	return os<<']';
}

constexpr int INF=1e9;
constexpr int MOD=1e9+7;
constexpr double EPS=1e-9;

inline pii number(const string& s,int i)
{
	int x=0;
	if(i>=s.size() || !isdigit(s[i])) return mp(INF,-1);
	for(int len=0;i<s.size() && isdigit(s[i]);i++,len++){
		if(len==1 && x==0) return mp(INF,-1);
		x=x*10+s[i]-'0';
	}
	return mp(x,i);
}
inline pii term(const string& s,int i)
{
	int x; tie(x,i)=number(s,i);
	if(i==-1) return mp(INF,-1);
	while(i<s.size() && (s[i]=='*' || s[i]=='/')){
		char op=s[i];
		int y; tie(y,i)=number(s,i+1);
		if(i==-1) return mp(INF,-1);
		if(op=='*') x*=y;
		if(op=='/'){
			if(y==0 || x%y>0) return mp(INF,-1);
			x/=y;
		}
	}
	return mp(x,i);
}
inline pii expr(const string& s,int i)
{
	int x; tie(x,i)=term(s,i);
	if(i==-1) return mp(INF,-1);
	while(i<s.size()){
		char op=s[i];
		if(op!='+' && op!='-') return mp(INF,-1);
		int y; tie(y,i)=term(s,i+1);
		if(i==-1) return mp(INF,-1);
		if(op=='+') x+=y;
		if(op=='-') x-=y;
	}
	return mp(x,i);
}
int expr(const string& s)
{
	return expr(s,0).first;
}

bool check(const vs& grid,const vector<pii>& f)
{
	string s;
	for(auto p:f) s+=grid[p.first][p.second];
	if(count(all(s),'=')!=1) return false;
	int eq=s.find('=');
	if(eq==0 || eq==s.size()-1) return false;
	string a=s.substr(0,eq),b=s.substr(eq+1);
	
	int x=expr(a),y=expr(b);
	//dump(mt(s,x,y));
	if(x==INF || y==INF || x!=y)
		return false;
	return true;
}

bool solve(int i,vs& grid,string& cs,vector<pii>& ps,vector<vector<pii>>& fs,vvi& ds)
{
	int n=ps.size();
	if(i==n) return true;
	
	for(char& c:cs) if(c!='X'){
		grid[ps[i].first][ps[i].second]=c; c='X';
		if(all_of(all(ds[i]),[&](int j){return check(grid,fs[j]);}))
			if(solve(i+1,grid,cs,ps,fs,ds))
				return true;
		c=grid[ps[i].first][ps[i].second];
	}
	return false;
}

int main()
{
	for(int h,w;cin>>h>>w && h|w;){
		vs grid(h);
		rep(i,h) cin>>grid[i];
		int n; cin>>n;
		string cs(n,'~');
		rep(i,n) cin>>cs[i];
		
		vector<pii> ps;
		vector<vector<pii>> fs;
		rep(i,h) rep(j,w){
			if(grid[i][j]=='.') ps.emplace_back(i,j);
			if(grid[i][j]!='#'){
				if((i==0 || grid[i-1][j]=='#') && i<h-1 && grid[i+1][j]!='#'){
					vector<pii> f;
					for(int k=i;k<h && grid[k][j]!='#';k++)
						f.emplace_back(k,j);
					fs.emplace_back(f);
				}
				if((j==0 || grid[i][j-1]=='#') && j<w-1 && grid[i][j+1]!='#'){
					vector<pii> f;
					for(int k=j;k<w && grid[i][k]!='#';k++)
						f.emplace_back(i,k);
					fs.emplace_back(f);
				}
			}
		}
		
		vvi ds(n+1);
		{
			vi vis(fs.size());
			rep(i,n+1){
				rep(j,fs.size()) if(!vis[j]){
					string s;
					for(auto p:fs[j]) s+=grid[p.first][p.second];
					if(count(all(s),'.')==0){
						ds[i].push_back(j);
						vis[j]=1;
					}
				}
				if(i<n) grid[ps[i].first][ps[i].second]='?';
			}
			rep(i,n)
				grid[ps[i].first][ps[i].second]='.';
			rotate(begin(ds),1+all(ds));
		}
		
		if(!all_of(all(ds[n]),[&](int j){return check(grid,fs[j]);})){
			cout<<"No"<<endl;
			continue;
		}
		cout<<(solve(0,grid,cs,ps,fs,ds)?"Yes":"No")<<endl;
	}
}
accuracy: 1
time_ms: 620
memory_kb: 1240
final_rank: 10

code_snippet: #include <bits/stdc++.h>

#define REP(i,n) for(int i=0;i<(int)(n);i++)

using namespace std;

pair<int,int> num(const string &f, int i) {
  int n = 0;
  if (i >= f.size() || !isdigit(f[i])) throw "puee";
  while(i < f.size()) {
    if(!isdigit(f[i])) return make_pair(n,i);
    n *= 10;
    n += f[i] - '0';
    ++i;
  }
  return make_pair(n,i);
}

bool ispm(char c) { return c == '+' || c == '-'; }
bool istd(char c) { return c == '*' || c == '/'; }

pair<int,int> mult(const string &f, int i) {
  int n;
  tie(n,i) = num(f,i);
  while(i != f.size() && istd(f[i])) {
    auto np = num(f,i+1);
    if(f[i] == '*') {
      n *= np.first;
    }else if(f[i] == '/') {
      if (np.first == 0) throw "guee";
      n /= np.first;
    }
    i = np.second;
  }
  return make_pair(n,i);
}

pair<int,int> add(const string &f, int i) {
  int n;
  tie(n,i) = mult(f,i);
  while(i != f.size() && ispm(f[i])) {
    auto np = mult(f,i+1);
    if(f[i] == '+') {
      n += np.first;
    }else if(f[i] == '-') {
      n -= np.first;
    }
    i = np.second;
  }
  return make_pair(n,i);
}

bool is_valid(const string &f, int st, int ed) {
  int p,q;
  try {
    tie(p,st) = add(f, st);
    if (st >= ed) return false;
    tie(q,st) = add(f, st+1);
  } catch(...) {
    return false;
  }
  return st == ed && p == q;
}

bool is_invalid(const string &f, int st, int ed) {
  string s = "+-*/=";
  bool prev = true;
  for(int i=st;i < ed; ++i) {
    if(s.find(f[i]) != string::npos) {
      if (prev) return true;
      prev = true;
    } else {
      prev = false;
    }
  }
  return prev;
}

bool is_closed(const string &f, int st, int ed) {
  for(int i=st;i < ed;++i) if (f[i] == '.') return false;
  return true;
}

bool is_valid_2_impl(const vector<string> &tb) {
  for(auto &line : tb) {
    int old = 0;
    REP(i,line.size()) {
      if(!i) continue;
      if (line[i] == '#') {
        if (i-old-1 >= 3){
          if(is_closed(line,old+1,i)
              && !is_valid(line,old+1,i)) return false;
        }
        old = i;
      }
    }
  }
  return true;
}

bool is_valid_2(const vector<string> &tb) {
  if(!is_valid_2_impl(tb)) return false;
  vector<string> tr(tb[0].size());
  REP(i,tb.size())
    REP(j,tb[0].size())
      tr[j] += tb[i][j];
  return is_valid_2_impl(tr);
}

bool is_bad(const string &str, int s, int t) {
  return is_invalid(str,s,t) ||
    (is_closed(str,s,t) && !is_valid(str,s,t));
}

bool search(vector<string> &tb, vector<tuple<int,int>> op, const vector<string> &v) {
  if (op.empty()) return true;
  int i,j;
  tie(i,j) = op.back();
  op.pop_back();
  int n=v.size();
  REP(k,n) {
    auto cp = v;
    cp.erase(begin(cp)+k);
    tb[i][j] = v[k][0];
    int s,t;
    s=t=i;
    while(tb[s][j] != '#') --s;
    while(tb[t][j] != '#') ++t;
    ++s;
    int l=t-s;
    if (t-s >= 3) {
      string str;
      REP(m,l) str += tb[s+m][j];
      if(is_bad(str,0,l)) continue;
    }
    s=t=j;
    while(tb[i][s] != '#') --s;
    while(tb[i][t] != '#') ++t;
    ++s;
    if(t-s >= 3 && is_bad(tb[i],s,t)) continue;
    if (search(tb,op,cp)){
      tb[i][j] = '.';
      return true;
    }
  }
  tb[i][j] = '.';
  return false;
}

int main() {
  while(1){
    int h,w;
    cin>>h>>w;
    if(!h) break;
    vector<string> tb(h+2,string(w+2,'#'));
    REP(i,h){
      string l;
      cin>>l;
      tb[i+1] = '#' + l + '#';
    }
    h+=2;w+=2;
    int n;
    cin>>n;
    vector<string> v(n);
    REP(i,n) cin>>v[i];
    vector<tuple<int,int>> op;
    REP(i,h)REP(j,w)if(tb[i][j]=='.')op.emplace_back(i,j);
    if (!is_valid_2(tb)) {
      cout << "No" << endl;
      continue;
    }
    bool ans = search(tb,op,v);
    if (ans)
      cout << "Yes" << endl;
    else
      cout << "No" << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 650
memory_kb: 1228
final_rank: 14

code_snippet: #include <bits/stdc++.h>

#define REP(i,n) for(int i=0;i<(int)(n);i++)

using namespace std;

pair<int,int> num(const string &f, int i) {
  int n = 0;
  if (i >= f.size() || f[i] < '0' || f[i] > '9') throw "puee";
  while(i < f.size()) {
    if(f[i] < '0' || f[i] > '9') return make_pair(n,i);
    n *= 10;
    n += f[i] - '0';
    ++i;
  }
  return make_pair(n,i);
}

pair<int,int> mult(const string &f, int i) {
  auto p = num(f,i);
  while(p.second != f.size()) {
    if(f[p.second] == '*') {
      auto np = num(f,p.second+1);
      p.first *= np.first;
      p.second = np.second;
    }else if(f[p.second] == '/') {
      auto np = num(f,p.second+1);
      if (np.first == 0) throw "guee";
      p.first /= np.first;
      p.second = np.second;
    }else break;
  }
  return p;
}

pair<int,int> add(const string &f, int i) {
  auto p = mult(f,i);
  while(p.second != f.size()) {
    if(f[p.second] == '+') {
      auto np = mult(f,p.second+1);
      p.first += np.first;
      p.second = np.second;
    }else if(f[p.second] == '-') {
      auto np = mult(f,p.second+1);
      p.first -= np.first;
      p.second = np.second;
    }else break;
  }
  return p;
}

bool is_valid(const string &f, int st, int ed) {
  auto p = add(f, st);
  if (p.second >= ed) return false;
  auto q = add(f, p.second+1);
  return q.second == ed && p.first == q.first;
}

bool is_invalid(const string &f, int st, int ed) {
  string s = "+-*/=";
  bool prev = true;
  for(int i=st;i < ed; ++i) {
    if(s.find(f[i]) != string::npos) {
      if (prev) return true;
      prev = true;
    } else {
      prev = false;
    }
  }
  return prev;
}

bool is_closed(const string &f, int st, int ed) {
  for(int i=st;i < ed;++i) if (f[i] == '.') return false;
  return true;
}

bool is_valid_2_impl(const vector<string> &tb) {
  for(auto &line : tb) {
    int old = 0;
    REP(i,line.size()) {
      if(!i) continue;
      if (line[i] == '#') {
        if (i-old-1 >= 3){
          if(is_closed(line,old+1,i)
              && !is_valid(line,old+1,i)) return false;
        }
        old = i;
      }
    }
  }
  return true;
}

bool is_valid_2(const vector<string> &tb) {
  if(!is_valid_2_impl(tb)) return false;
  vector<string> tr(tb[0].size());
  REP(i,tb.size()){
    REP(j,tb[0].size()){
      tr[j] += tb[i][j];
    }
  }
  return is_valid_2_impl(tr);
}

bool search(vector<string> &tb, vector<tuple<int,int>> op, const vector<string> &v) {
  if (op.empty()) return true;
  int i,j;
  tie(i,j) = op.back();
  op.pop_back();
  int n=v.size();
  REP(k,n) {
    auto cp = v;
    cp.erase(begin(cp)+k);
    tb[i][j] = v[k][0];
    int s,t;
    s=t=i;
    while(tb[s][j] != '#') --s;
    while(tb[t][j] != '#') ++t;
    ++s;
    if (t-s >= 3) {
      string str;
      REP(l,t-s) str += tb[s+l][j];
      if (is_invalid(str,0,str.size())) continue;
      try {
        if(is_closed(str,0,str.size())
            && !is_valid(str,0,str.size())) continue;
      } catch(...) {
        continue;
      }
    }
    s=t=j;
    while(tb[i][s] != '#') --s;
    while(tb[i][t] != '#') ++t;
    ++s;
    if(t-s >= 3) {
      if (is_invalid(tb[i],s,t)) continue;
      try{
        if(is_closed(tb[i],s,t) && !is_valid(tb[i],s,t)) continue;
      } catch(...) {
        continue;
      }
    }
    if (search(tb,op,cp)){
      tb[i][j] = '.';
      return true;
    }
  }
  tb[i][j] = '.';
  return false;
}

int main() {
  while(1){
    int h,w;
    cin>>h>>w;
    if(!h) break;
    vector<string> tb(h+2,string(w+2,'#'));
    REP(i,h){
      string l;
      cin>>l;
      tb[i+1] = '#' + l + '#';
    }
    h+=2;w+=2;
    int n;
    cin>>n;
    vector<string> v(n);
    REP(i,n) cin>>v[i];
    vector<tuple<int,int>> op;
    REP(i,h)REP(j,w)if(tb[i][j]=='.')op.emplace_back(i,j);
    if (!is_valid_2(tb)) {
      cout << "No" << endl;
      continue;
    }
    bool ans = search(tb,op,v);
    if (ans)
      cout << "Yes" << endl;
    else
      cout << "No" << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 670
memory_kb: 1232
final_rank: 15

code_snippet: #include <algorithm>
#include <array>
#include <cctype>
#include <cstdlib>
#include <iostream>
#include <utility>
#include <vector>
#include <unordered_set>
using namespace std;

constexpr int MAX_SIZE = 10;
constexpr int MAX_N = 10;

int h, w;
array<string, MAX_SIZE> puzzle;

int n;
array<char, MAX_N> in;

array<bool, MAX_N> used;
array<char, 128> letters;
array<bool, 128> is_operator;
array<bool, MAX_N> not_operator;
array<bool, MAX_N> not_zero;
array<unordered_set<int>, MAX_N> left_idx, right_idx;

int number(string::const_iterator &it) {
	int res = 0;
	while(isdigit(*it)) {
		res = res * 10 + (*it - '0');
		++it;
	}
	return res;
}

int factor(string::const_iterator &it) {
	if(isdigit(*it)) return number(it);
	throw "parse error";
}

int term(string::const_iterator &it) {
	int res = factor(it);
	while(true) {
		switch(*it) {
		case '*':
		{
			++it;
			res *= factor(it);
			break;
		}
		case '/':
		{
			++it;
			const int tmp = factor(it);
			if(tmp == 0) throw "division by zero";
			if(res % tmp) throw "division leaving a remainder";
			res /= tmp;
			break;
		}
		default:
			return res;
		}
	}
	return res;
}

int expr(string::const_iterator &it) {
	int res = term(it);

	while(true) {
		switch(*it) {
		case '+':
		{
			++it;
			res += term(it);
			break;
		}
		case '-':
		{
			++it;
			res -= term(it);
			break;
		}
		default:
			return res;
		}
	}
}

bool valid(const vector<int> &expression) {
	const int n = expression.size();
	string left = "", right = "";
	int i;

	for(i = 0; i < n; ++i) {
		if(expression[i] == '=') break;
		left += letters[expression[i]];
	}

	for(++i; i < n; ++i) {
		right += letters[expression[i]];
	}

	try {
		string::const_iterator l_it = left.cbegin(), r_it = right.cbegin();
		if(expr(l_it) != expr(r_it)) return false;
	}
	catch(const char *c) {
		return false;
	}
	return true;
}

void calc(int &x, int &y, int dx, int dy) {
	while(true) {
		const int nx = x + dx;
		const int ny = y + dy;
		if(0 <= nx && nx < w && 0 <= ny && ny < h && puzzle[ny][nx] != '#') {
			x = nx;
			y = ny;
		}
		else {
			return;
		}
	}
}

void update(const vector<int> &expression) {
	for(unsigned i = 0; i < expression.size(); ++i) {
		if(isdigit(expression[i])) {
			if(i && expression[i - 1] < MAX_SIZE) {
				not_zero[expression[i - 1]] = true;
			}
		}
		else if(expression[i] < MAX_SIZE) { // space
			if(i) {
				if(expression[i - 1] < MAX_SIZE) {
					left_idx[expression[i]].insert(expression[i - 1]);
					right_idx[expression[i - 1]].insert(expression[i]);
				}
				if(i + 1 == expression.size()) {
					not_operator[expression[i]] = true;
				}
			}
			else {
				not_operator[expression[i]] = true;
			}
		}
		else { // operator
			if(expression[i - 1] < MAX_SIZE) {
				not_operator[expression[i - 1]] = true;
			}
			if(i + 1 < expression.size() && expression[i + 1] < MAX_SIZE) {
				not_operator[expression[i + 1]] = true;
			}
		}
	}
}

vector<pair<int, vector<int>>> construct() {
	vector<vector<int>> idx(h, vector<int>(w, -1));
	int next = 0;

	vector<pair<int, vector<int>>> expressions;
	expressions.reserve(40);
	for(int i = 0; i < h; ++i) {
		for(int j = 0; j < w; ++j) {
			if(puzzle[i][j] == '=') {
				// vertical
				int s = i, g = i;
				calc(j, s, 0, -1);
				calc(j, g, 0, 1);

				if(s != i && g != i) {
					vector<int> expression;
					expression.reserve(g - s + 1);
					int max_index = -1;
					for(int k = s; k <= g; ++k) {
						if(puzzle[k][j] == '.') {
							if(idx[k][j] == -1) idx[k][j] = next++;
							expression.emplace_back(idx[k][j]);
							max_index = max(max_index, idx[k][j]);
						}
						else {
							expression.emplace_back(puzzle[k][j]);
						}
					}

					update(expression);
					expressions.emplace_back(max_index, expression);
				}

				// horizontal
				s = j, g = j;
				calc(s, i, -1, 0);
				calc(g, i, 1, 0);

				if(s != j && g != j) {
					vector<int> expression;
					expression.reserve(g - s + 1);
					int max_index = -1;
					for(int k = s; k <= g; ++k) {
						if(puzzle[i][k] == '.') {
							if(idx[i][k] == -1) idx[i][k] = next++;
							expression.emplace_back(idx[i][k]);
							max_index = max(max_index, idx[i][k]);
						}
						else {
							expression.emplace_back(puzzle[i][k]);
						}
					}

					update(expression);
					expressions.emplace_back(max_index, expression);
				}
			}
		}
	}

	sort(expressions.begin(), expressions.end());
	return expressions;
}

bool dfs(const vector<pair<int, vector<int>>> &expressions, int next, int idx) {
	while(next < expressions.size() && expressions[next].first < idx) {
		if(!valid(expressions[next].second)) return false;
		++next;
	}
	if(next == expressions.size()) return true;

	for(int i = 0; i < n; ++i) {
		if(used[i]) continue;
		if(is_operator[in[i]] && not_operator[idx]) continue;
		if(in[i] == '0' && not_zero[idx]) continue;
		if(i && !used[i - 1] && in[i] == in[i - 1]) continue;

		letters[idx] = in[i];
		const auto t_no = not_operator;
		const auto t_nz = not_zero;

		if(is_operator[in[i]]) {
			for(const auto &e : left_idx[idx]) not_operator[e] = true;
			for(const auto &e : right_idx[idx]) not_operator[e] = true;
		}
		else {
			for(const auto &e : left_idx[idx]) not_zero[e];
		}

		used[i] = true;
		if(dfs(expressions, next, idx + 1)) return true;
		used[i] = false;

		not_operator = t_no;
		not_zero = t_nz;
	}

	return false;
}

int main() {
	cin.tie(nullptr);
	ios::sync_with_stdio(false);

	is_operator.fill(false);
	is_operator['+'] = true;
	is_operator['-'] = true;
	is_operator['*'] = true;
	is_operator['/'] = true;
	iota(begin(letters), end(letters), 0);

	while(cin >> h >> w && h) {
		used.fill(false);
		not_operator.fill(false);
		not_zero.fill(false);
		for(int i = 0; i < n; ++i) {
			left_idx[i].clear();
			right_idx[i].clear();
		}

		for(int i = 0; i < h; ++i) {
			cin >> puzzle[i];
		}

		cin >> n;
		for(int i = 0; i < n; ++i) {
			cin >> in[i];
		}
		sort(in.begin(), in.begin() + n);

		const auto expressions = construct();
		cout << (dfs(expressions, 0, 0) ? "Yes\n" : "No\n");
	}

	return EXIT_SUCCESS;
}
accuracy: 1
time_ms: 150
memory_kb: 1304
final_rank: 2

code_snippet: #include <iostream>
#include <iomanip>
#include <sstream>
#include <cstdio>
#include <string>
#include <vector>
#include <algorithm>
#include <complex>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <cassert>
#include <climits>
#include <queue>
#include <set>
#include <map>
#include <valarray>
#include <bitset>
#include <stack>
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()
#define chmax(a,b) (a<b?(a=b,1):0)
#define chmin(a,b) (a>b?(a=b,1):0)
#define valid(y,x,h,w) (0<=y&&y<h&&0<=x&&x<w)
typedef long long ll;
typedef pair<int,int> pii;
const int INF = 1<<29;
const double PI = acos(-1);
const double EPS = 1e-8;

char str[1010];
typedef int Int;

Int term(int &i);
Int fact(int &i);

Int exp(int &i) {
  Int p = term(i);
  while(str[i]=='+' || str[i]=='-') {
    char c = str[i++];
    if (c == '+') {
      Int a = term(i);
      p += a;
    }
    else p -= term(i);
  }
  return p;
}

Int term(int &i) {
  Int p = fact(i);
  while(str[i]=='*' || str[i]=='/') {
    if (str[i++] == '*') {
      p *= fact(i);
    } else {
      int r = fact(i);
      if (r == 0) throw 0;
      if (p % r == 0) p /= r;
      else throw 0;
    }
  }
  return p;
}

Int fact(int &i) {
  Int p = 0;
  if (!isdigit(str[i])) throw 0;
  while(isdigit(str[i])) {
    p *= 10;
    p += str[i]-'0';
    i++;
  }
  return p;
}

Int parse() {
  int id = 0;
  Int res = exp(id);
  if (str[id]) throw 0;
  return res;
}

inline bool isoperator(char c) {
  return c=='+'||c=='-'||c=='*'||c=='/'||c=='=';
}

bool check(char *s) {
  try {
    int n = strlen(s);
    int pos = -1;
    REP(i,strlen(s)) if (s[i]=='=') pos = i;
    if (pos == -1 || pos == 0 || pos == n-1) return 0;
    for (int i=0; i<pos; ++i) str[i] = s[i]; str[pos] = 0;
    Int a = parse();
    for (int i=pos+1; i<n; ++i) str[i-pos-1] = s[i]; str[n-pos-1] = 0;
    Int b = parse();
    if (a == b) return 1;
    else return 0;
  } catch(int a) {
    return 0;
  }
}


char a[10][10];
char b[10];

char eq[100][11];

int h,w;

bool inserted[10][10];

pii pos[100];
int posNum;
int eqNum;
bool visited[10][10][2];

vector<pii> ididx[10][10];
int dotNum[100];

bool bfs(int y, int x, int dy, int dx) {
  char s[11];
  int idx = 0;
  vector<pii> v;
  vector<int> id;
  while(valid(y,x,h,w)) {
    visited[y][x][dy] = 1;
    if (a[y][x] == '#') break;
    if (a[y][x] == '.') {
      v.push_back(pii(y,x));
      id.push_back(idx);
    }
    s[idx++] = a[y][x];
    y += dy;
    x += dx;
  }
  if (idx >= 3) {
    s[idx] = 0;
    if (v.size() == 0 && !check(s)) return 0;
    dotNum[eqNum] = v.size();
    strcpy(eq[eqNum], s);
    REP(i,v.size()) {
      int y = v[i].first, x = v[i].second;
      ididx[y][x].push_back(pii(eqNum,id[i]));
      if (!inserted[y][x]) {
        pos[posNum++] = pii(y,x);
        inserted[y][x] = 1;
      }
    }
    eqNum++;
  }
  return 1;
}

bool checkOp(int id, int idx) {
  int n = strlen(eq[id]);
  if (idx==0 || idx==n-1) return 1;
  if (isoperator(eq[id][idx-1])) return 1;
  if (isoperator(eq[id][idx+1])) return 1;
  return 0;
}

const int dy[4] = {-1,0,1,0};
const int dx[4] = {0,1,0,-1};

bool isNumOnly(int now, int y, int x) {
  FOR(it, ididx[y][x]) {
    int id=it->first;
    int idx=it->second;
    if (checkOp(id,idx)) return 1;
  }
  return 0;
}

bool isHead(int now, int y, int x) {
  FOR(it, ididx[y][x]) {
    int id=it->first;
    int idx=it->second;
    if (idx==0 || isoperator(eq[id][idx-1]))return 1;
  }
  return 0;
}

bool numOnly[100];

int n;

bool dfs(int S, int now) {
  if (now == posNum) return 1;
  int y = pos[now].first;
  int x = pos[now].second;
  FOR(it, ididx[y][x]) {
    dotNum[it->first]--;
  }
  
  REP(i,n) {
    if (S>>i&1) continue;
    if (!isdigit(b[i]) && isNumOnly(now,y,x)) continue;
    // cout << y << " " << x << " " << now << " " << b[i] << endl;
    // if (b[i] == '0' && isHead(now,y,x)) continue;
    bool f = 1;
    FOR(it, ididx[y][x]) {
      int id = it->first;
      int idx = it->second;
      eq[id][idx] = b[i];
      if (dotNum[id] == 0) {
        f &= check(eq[id]);
      }
    }
    if (f) {
      if (dfs(S|1<<i,now+1)) return 1;
    }
  }
  FOR(it, ididx[y][x]) {
    eq[it->first][it->second] = '.';
    dotNum[it->first]++;
  }
  return 0;
}

int main() {
  while(cin>>h>>w,h||w) {
    REP(i,h)REP(j,w) {
      cin>>a[i][j];
    }
    cin >> n;
    REP(i,n)cin>>b[i];
    memset(inserted,0,sizeof(inserted));
    memset(visited,0,sizeof(visited));
    posNum = 0, eqNum = 0;
    REP(i,h)REP(j,w)ididx[i][j].clear();
    memset(dotNum,0,sizeof(dotNum));
    REP(i,h) {
      REP(j,w) {
        if (a[i][j] == '#') continue;
        if (!visited[i][j][1]) bfs(i,j,1,0);
        if (!visited[i][j][0]) bfs(i,j,0,1);
      }
    }
    memset(numOnly,0,sizeof(numOnly));
    REP(i,posNum) {
      FOR(it, ididx[pos[i].first][pos[i].second]) {
        numOnly[i] = checkOp(it->first,it->second);
      }
    }
    // REP(i,eqNum) cout << eq[i] << endl;
    // REP(i,posNum) {
    //   cout << numOnly[i] << endl;
    //   cout << pos[i].first << " " << pos[i].second << endl;
    //   FOR(it, ididx[pos[i].first][pos[i].second]) {
    //     cout << it->first << ":" << it->second << endl;
    //   }cout << endl;
    // }
    cout << (dfs(0,0)?"Yes":"No") << endl;
  }
}
accuracy: 1
time_ms: 510
memory_kb: 1288
final_rank: 7

code_snippet: #include <iostream>
#include <vector>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cctype>
using namespace std;

#define INF 999999999

int h, w, n;
char t[12][12];
char p[12];

vector<int> blankX;
vector<int> blankY;

bool used[12];
bool isOperator[128];

//式の開始地点でないなら, -1が入る
//式の開始地点なら, どの座標の空白が埋まれば式判定できるか
//空白が埋まらなくても式判定できるなら, -2が入る
int gx0[12][12], gy0[12][12];
int gx1[12][12], gy1[12][12];

//構文解析用変数
int idxX;
int idxY;
int dir;

//右 下 左 上
int dx[] = {1, 0, -1, 0};
int dy[] = {0, 1, 0, -1};

//w*hの範囲内であるならばtrue
bool inBoard(int x, int y){
  return 0 <= x && x < w && 0 <= y && y < h;
}

//#でないマス目であるならばtrue
bool isWhite(int x, int y){
  if(!inBoard(x, y)) return false;
  return t[y][x] != '#';
}

//演算子が含まれるマスならばtrue
bool containsOperator(int x, int y){
  if(!inBoard(x, y)) return false;
  return isOperator[t[y][x]];
}

int N0(){
  if(!isdigit(t[idxY][idxX])){
    return INF;
  }

  string valStr;

  while(inBoard(idxX, idxY) && isdigit(t[idxY][idxX])){
    valStr += t[idxY][idxX];
    idxX += dx[dir];
    idxY += dy[dir];
  }

  if(valStr.length() == 1 || valStr[0] != '0'){
    return atoi(valStr.c_str());
  }
  return INF;
}

int Term(){
  int lv = N0();
  if(lv == INF) return INF;

  while(inBoard(idxX, idxY) && (t[idxY][idxX] == '*' || t[idxY][idxX] == '/')){
    char op = t[idxY][idxX];

    idxX += dx[dir];
    idxY += dy[dir];

    int rv = N0();
    if(rv == INF) return INF;

    if(op == '*'){
      lv *= rv;
    }
    else{
      if(rv == 0 || lv % rv != 0) return INF;
      lv /= rv;
    }
  }

  return lv;
}

int Ex(){
  int lv = Term();
  if(lv == INF) return INF;

  while(inBoard(idxX, idxY) && (t[idxY][idxX] == '+' || t[idxY][idxX] == '-')){
    char op = t[idxY][idxX];

    idxX += dx[dir];
    idxY += dy[dir];

    int rv = Term();
    if(rv == INF) return INF;

    if(op == '+') lv += rv;
    else          lv -= rv;
  }

  return lv;
}

bool isCorrectEq(){
  //左辺
  int lv = Ex();
  if(lv == INF) return false;

  //イコールがあるかどうか
  if(!inBoard(idxX, idxY) || t[idxY][idxX] != '=') return false;
  idxX += dx[dir];
  idxY += dy[dir];

  //右辺
  int rv = Ex();
  if(rv == INF) return false;

  if(isWhite(idxX, idxY)){
    return false;
  }

  return lv == rv;
}

bool isCorrectBoard(int x, int y){
  /*
  cout<<x<<","<<y<<endl;
  for(int i = 0; i < h; i++){
    cout << t[i] << endl;
  }
  cout<<"--\n";
  */

  for(int i = 0; i < h; i++){
    for(int j = 0; j < w; j++){
      if(gx0[i][j] == x && gy0[i][j] == y){
        idxX = j;
        idxY = i;
        dir = 0;

        if(!isCorrectEq()) return false;
      }
      if(gx1[i][j] == x && gy1[i][j] == y){
        idxX = j;
        idxY = i;
        dir = 1;

        if(!isCorrectEq()) return false;
      }
    }
  }

  return true;
}

bool dfs(int blankIdx){
  if(blankIdx == n){
    return true;
  }

  int x = blankX[blankIdx];
  int y = blankY[blankIdx];
  bool digitFlg = false;

  //必ず数字を入れなくてはいけないマスであるかチェック
  for(int i = 0; i < 4; i++){
    if(containsOperator(x + dx[i], y + dy[i])){
      digitFlg = true;
      break;
    }
  }
  if(isWhite(x + dx[0], y + dy[0]) + isWhite(x + dx[2], y + dy[2]) == 1){
    digitFlg = true;
  }
  if(isWhite(x + dx[1], y + dy[1]) + isWhite(x + dx[3], y + dy[3]) == 1){
    digitFlg = true;
  }

  //ピースを当てはめる
  for(int i = 0; i < n; i++){
    if(used[i]) continue;
    if(digitFlg && isOperator[p[i]]) continue;

    used[i] = true;
    t[y][x] = p[i];

    if(isCorrectBoard(x, y) && dfs(blankIdx + 1)) return true;

    used[i] = false;
  }

  return false;
}

int main(){
  isOperator['+'] = true;
  isOperator['-'] = true;
  isOperator['*'] = true;
  isOperator['/'] = true;
  isOperator['='] = true;

  while(cin >> h >> w, h || w){
    for(int i = 0; i < h; i++){
      cin >> t[i];
    }

    cin >> n;
    for(int i = 0; i < n; i++){
      cin >> p[i];
    }

    blankX.clear();
    blankY.clear();

    for(int i = 0; i < h; i++){
      for(int j = 0; j < w; j++){
        if(t[i][j] != '.') continue;
        blankX.push_back(j);
        blankY.push_back(i);
      }
    }

    memset(gx0, -1, sizeof(gx0));
    memset(gy0, -1, sizeof(gy0));
    memset(gx1, -1, sizeof(gx1));
    memset(gy1, -1, sizeof(gy1));

    for(int i = 0; i < h; i++){
      for(int j = 0; j < w; j++){
        if(t[i][j] == '#') continue;

        if(!isWhite(j + 1 * dx[2], i + 1 * dy[2]) &&
            isWhite(j + 1 * dx[0], i + 1 * dy[0]) &&
            isWhite(j + 2 * dx[0], i + 2 * dy[0])){
          int x = j;
          int y = i;

          gx0[i][j] = -2;
          gy0[i][j] = -2;

          while(inBoard(x, y) && isWhite(x, y)){
            if(t[y][x] == '.'){
              gx0[i][j] = x;
              gy0[i][j] = y;
            }
            x += dx[0];
            y += dy[0];
          }
        }
        if(!isWhite(j + 1 * dx[3], i + 1 * dy[3]) &&
            isWhite(j + 1 * dx[1], i + 1 * dy[1]) &&
            isWhite(j + 2 * dx[1], i + 2 * dy[1])){
          int x = j;
          int y = i;

          gx1[i][j] = -2;
          gy1[i][j] = -2;

          while(inBoard(x, y) && isWhite(x, y)){
            if(t[y][x] == '.'){
              gx1[i][j] = x;
              gy1[i][j] = y;
            }
            x += dx[1];
            y += dy[1];
          }
        }
      }
    }

    bool flg = isCorrectBoard(-2, -2);

    if(!flg){
      cout << "No\n";
      continue;
    }

    memset(used, 0, sizeof(used));
    cout << (dfs(0) ? "Yes" : "No") << endl;
  }
}
accuracy: 1
time_ms: 310
memory_kb: 1232
final_rank: 4

code_snippet: #include <cstdio>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <bitset>
#include <numeric>
#include <climits>
#include <cfloat>
using namespace std;

int n;                           // 空白の数
string p;                        // リストの文字
vector<vector<string> > formula; // パズル中の数式
string change;                   // 各空白に入れる文字
bool error;                      // 式計算のエラー有無

int calculate(const string& s, int a, int b)
{
    if(a > b){
        error = true;
        return 0;
    }

    int k = b;
    while(k >= a && s[k] != '+' && s[k] != '-')
        -- k;
    if(k >= a){
        int x = calculate(s, a, k-1);
        int y = calculate(s, k+1, b);
        if(s[k] == '+')
            return x + y;
        else
            return x - y;
    }

    if(b > a && s[a] == '0'){
        error = true;
        return 0;
    }

    k = b;
    while(k >= a && s[k] != '*' && s[k] != '/')
        -- k;
    if(k >= a){
        int x = calculate(s, a, k-1);
        int y = calculate(s, k+1, b);
        if(s[k] == '*'){
            return x * y;
        }else{
            if(y == 0 || x % y != 0){
                error = true;
                return 0;
            }
            return x / y;
        }
    }

    int ret = 0;
    for(int i=a; i<=b; ++i){
        ret *= 10;
        ret += s[i] - '0';
    }

    return ret;
}

bool check(const string& s)
{
    int k = s.find('=');
    if(k == string::npos || s.find('=', k+1) != string::npos)
        return false;

    error = false;
    bool ret = calculate(s, 0, k-1) == calculate(s, k+1, s.size()-1);
    return !error && ret;
}

bool solve(int x, bitset<10> bs)
{
    if(x == n)
        return true;

    for(int i=0; i<n; ++i){
        if(bs[i])
            continue;
        bs[i] = true;

        change[x] = p[i];
        bool ok = true;
        for(unsigned j=0; j<formula[x].size(); ++j){
            string t = formula[x][j];
            for(unsigned k=0; k<t.size(); ++k){
                if(isalpha(t[k]))
                    t[k] = change[t[k]-'a'];
            }
            if(!check(t))
                ok = false;
        }

        if(ok && solve(x+1, bs))
            return true;

        bs[i] = false;
    }

    return false;
}

int main()
{
    for(;;){
        int h, w;
        cin >> h >> w;
        if(h == 0)
            return 0;

        vector<string> s(h+2, string(w+2, '#'));
        int tmp = 0;
        for(int i=1; i<=h; ++i){
            for(int j=1; j<=w; ++j){
                cin >> s[i][j];
                if(s[i][j] == '.'){
                    s[i][j] = 'a' + tmp;
                    ++ tmp;
                }
            }
        }

        cin >> n;
        p.assign(n, ' ');
        for(int i=0; i<n; ++i)
            cin >> p[i];

        bool ng = false;
        formula.assign(n, vector<string>());
        for(int i=0; i<h+2; ++i){
            char c = 0;
            string t;
            for(int j=0; j<w+2; ++j){
                if(s[i][j] != '#'){
                    t += s[i][j];
                    if(isalpha(s[i][j]))
                        c = s[i][j];
                }else{
                    if(t.size() >= 3){
                        if(c == 0){
                            if(!check(t))
                                ng = true;
                        }else{
                            formula[c-'a'].push_back(t);
                        }
                    }
                    c = 0;
                    t = "";
                }
            }
        }
        for(int j=0; j<w+2; ++j){
            char c = 0;
            string t;
            for(int i=0; i<h+2; ++i){
                if(s[i][j] != '#'){
                    t += s[i][j];
                    if(isalpha(s[i][j]))
                        c = s[i][j];
                }else{
                    if(t.size() > 2){
                        if(c == 0){
                            if(!check(t))
                                ng = true;
                        }else{
                            formula[c-'a'].push_back(t);
                        }
                    }
                    c = 0;
                    t = "";
                }
            }
        }
        if(ng){
            cout << "No" << endl;
            continue;
        }

        change.assign(n, ' ');
        if(solve(0, 0))
            cout << "Yes" << endl;
        else
            cout << "No" << endl;
    }
}
accuracy: 1
time_ms: 580
memory_kb: 920
final_rank: 9

code_snippet: #include<cctype>
#include<cstdio>
#include<cstring>
#include<algorithm>

#define rep(i,n) for(int i=0;i<(n);i++)

using namespace std;

int idx;
char s[11];
bool res;

#define ASRT if(!res) return 0

int N(){
	if(!('1'<=s[idx] && s[idx]<='9')){ res=false; ASRT; }
	int a=0;
	while(isdigit(s[idx])) a=10*a+s[idx++]-'0';
	return a;
}

int N0(){
	int a;
	if(s[idx]=='0'){
		idx++;
		a=0;
	}
	else a=N();
	ASRT;
	return a;
}

int Ex2(){
	int a=N0();
	ASRT;
	while(s[idx]=='*' || s[idx]=='/'){
		char op=s[idx++];
		int b=N0();
		ASRT;
		if(op=='/' && (b==0 || a%b!=0)){ res=false; ASRT; }

		if(op=='*') a*=b;
		if(op=='/') a/=b;
	}
	return a;
}

int Ex1(){
	int a=Ex2();
	ASRT;
	while(s[idx]=='+' || s[idx]=='-'){
		char op=s[idx++];
		int b=Ex2();
		ASRT;

		if(op=='+') a+=b;
		if(op=='-') a-=b;
	}
	return a;
}

int Eq(){
	int a=Ex1();
	ASRT;
	if(s[idx++]!='='){ res=false; ASRT; }
	int b=Ex1();
	ASRT;
	if(a!=b || s[idx]) res=false;
	return 0;
}

bool parse(){
	if(strlen(s)<=2) return true;
	idx=0;
	res=true;
	Eq();
	return res;
}

int h,w;
char B[10][11];

bool calc_no_space(){
	rep(i,h){
		int p=-1;
		rep(j,w+1){
			if(j<w && B[i][j]!='#'){
				if(p==-1) p=j;
			}
			else{
				if(p!=-1){
					rep(k,j-p) s[k]=B[i][p+k];
					s[j-p]='\0';
					if(strchr(s,'.')==0 && !parse()) return false;
					p=-1;
				}
			}
		}
	}

	rep(j,w){
		int p=-1;
		rep(i,h+1){
			if(i<h && B[i][j]!='#'){
				if(p==-1) p=i;
			}
			else{
				if(p!=-1){
					rep(k,i-p) s[k]=B[p+k][j];
					s[i-p]='\0';
					if(strchr(s,'.')==0 && !parse()) return false;
					p=-1;
				}
			}
		}
	}

	return true;
}

char key[10];
int n,qx[10],qy[10];
bool dfs(int k,bool *used){
	if(k==n) return true;

	rep(l,n) if(!used[l]) {
		used[l]=true;
		B[qy[k]][qx[k]]=key[l];

		bool ok=true;
		int x1=qx[k],x2=qx[k];
		while(x1>=0 && B[qy[k]][x1]!='#') x1--; x1++;
		while(x2< w && B[qy[k]][x2]!='#') x2++;
		rep(j,x2-x1) s[j]=B[qy[k]][x1+j];
		s[x2-x1]='\0';
		if(count(s,s+x2-x1,'.')==0 && !parse()) ok=false;

		int y1=qy[k],y2=qy[k];
		while(y1>=0 && B[y1][qx[k]]!='#') y1--; y1++;
		while(y2< h && B[y2][qx[k]]!='#') y2++;
		rep(i,y2-y1) s[i]=B[y1+i][qx[k]];
		s[y2-y1]='\0';
		if(count(s,s+y2-y1,'.')==0 && !parse()) ok=false;

		if(ok && dfs(k+1,used)) return true;

		used[l]=false;
		B[qy[k]][qx[k]]='.';
	}

	return false;
}

int main(){
	for(;scanf("%d%d",&h,&w),h;){
		rep(i,h) scanf("%s",B[i]);
		scanf("%d",&n);
		rep(i,n) scanf(" %c",key+i);

		n=0;
		rep(i,h) rep(j,w) if(B[i][j]=='.') qx[n]=j, qy[n]=i, n++;

		bool used[10]={};
		puts(calc_no_space()&&dfs(0,used)?"Yes":"No");
	}

	return 0;
}
accuracy: 1
time_ms: 430
memory_kb: 740
final_rank: 5