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

Solution in C++ (judge verdict: Time Limit Exceeded)

#include <iostream>
#include <vector>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <algorithm>	// require sort next_permutation count __gcd reverse etc.
#include <cstdlib>	// require abs exit
#include <cstdio>	// require scanf printf
#include <functional>
#include <numeric>	// require accumulate
#include <cmath>
#include <climits>
#include <limits>
#include <cfloat>
#include <iomanip>	// require setw
#include <sstream>	// require stringstream 
#include <cstring>	// require memset
#include <cctype>	// require tolower, toupper
#include <fstream>	// require freopen
#include <ctime>
#define rep(i,n) for(int i=0;i<(n);i++)
#define ALL(A) A.begin(), A.end()
#define DEBUG 0

using namespace std;

typedef long long ll;
typedef pair<int, int> P;
const int UND = 1<<30;
int h, w;
char pz[12][12];
char cur[12][12];
bool used[12][12];

bool ans;

class Parser
{
public:
	string exp;
	int p;
	void Eq (void );
	int Ex (void );
	int N (void );
};

void Parser::Eq (void )
{
	int value1 = 0, value2 = 0;
#if DEBUG
	cout << "exp: " << exp << endl;
#endif
	value1 = Ex();

	if (value1 == UND ) ans = false;

	while (exp[p] == '+' || exp[p] == '-' ){
		int val = 0;
		if (exp[p] == '+' ){
			++p;
			val = Ex();
			if (val == UND ) ans = false;
			value1 += val;
		}else{
			++p;
			val = Ex();
			if (val == UND ) ans = false;
			value1 -= val;		
		} // end if
	} // end while

	if (exp[p] == '=' ){
		++p;
	} // end if

	value2 = Ex();			

	if (value2 == UND ) ans = false;

	while (exp[p] == '+' || exp[p] == '-' ){
		int val = 0;
		if (exp[p] == '+' ){
			++p;
			val = Ex();
			if (val == UND ) ans = false;
			value2 += val;
		}else{
			++p;
			val = Ex();
			if (val == UND ) ans = false;
			value2 -= val;		
		} // end if
	} // end while

	if (value1 != value2 )
		ans = false;
#if DEBUG
	cout << "ans: " << (ans ? "YES" : "NO" ) << endl;
#endif
}

int Parser::Ex (void )
{
	int value = N();

	if (value == UND ) ans = false;

	while (exp[p] == '*' || exp[p] == '/' ){
		if (exp[p] == '*' ){
			++p;
			int val = N();
			if (val == UND ){
				value = UND;
				ans = false;
			}else{
				value *= val;
			} // end if
		}else{
			++p;
			int val = N();
			if (value != UND && val != UND && val != 0 && value % val == 0 ){
				value /= val;
			}else{
				value = UND;
				ans = false;
			} // end if
		} // end if
	} // end while
	
	return value;
}

int Parser::N (void )
{
	int value = 0;
	int cnt = 0;
	char first = 0;
	if (!isdigit(exp[p] ) )
		return UND;

	while (isdigit(exp[p] ) ){
		if (cnt == 0 ){
			first = exp[p];
		} // end if
		value *= 10;
		value += (exp[p] - '0');
		cnt++;
		p++;
	} // end while

	if ( (first == '0' && cnt > 1 ) || (cnt > 2 ) )
		ans = false;

	return value;
}

void disp_pz (void )
{
	rep (i, h ){
		rep (j, w ){
			cout << cur[i][j];
		} // end rep
		cout << endl;
	} // end rep 
}


bool make_pz (vector<char> ope )
{
	memset (cur, 0, sizeof (cur ) );
	int k = 0;
	rep (i, h ){
		rep (j, w ){
			if (pz[i][j] == '.' ){
				if (!isdigit(ope[k] ) ){
					if (i == 0 && j == 0 ) return false;
 					if (i != 0 && pz[i-1][j] != '#' && !isdigit (pz[i-1][j] ) ) return false;
					if (j != 0 && pz[i][j-1] != '#' && !isdigit (pz[i][j-1] ) ) return false;
				} // end if
				cur[i][j] = ope[k];
				k++;
			}else{
				cur[i][j] = pz[i][j];
			} // end if
		} // end rep
	} // end rep
#if DEBUG
	disp_pz ();
	cout << endl;
#endif

	return true;
}

bool evaluate_exp (string exp )
{
//	cout << exp << endl;
	Parser parser;
	parser.exp = exp;
	parser.p = 0;
	ans = true;
	parser.Eq();

	return ans;	
}

bool is_correct (void )
{
	const int dir[][2] = { { 0, 0 }, { 1, 0 }, { 0, 1 } };

	memset (used, false, sizeof (used ) );
	stack<P> u;
	rep (i, h ){
		rep (j, w ){
			if (cur[i][j] != '#' ){
				int k1 = 0, k2 = 0;
				if (!used[i][j] ){
					k1 = 0, k2 = 2;
				}else{ // if (used[i][j] )
					int dsum = 0;
					rep (d, 3 ){
						int ni = i + dir[d][0];
						int nj = j + dir[d][1];
						if (ni < 0 || nj < 0 || ni >= h || nj >= w || cur[ni][nj] == '#' ) continue;
						if (!used[ni][nj] ){
							dsum += d;
						} // end if
					} // end rep
					switch (dsum ){
						case 1: k1 = 0, k2 = 1; break;
						case 2: k1 = 1, k2 = 2; break;
						case 3: k1 = 0, k2 = 2; break;
						default: k1 = 0, k2 = 0; break;
					} // end switch
				} // end if
				for (int k = k1; k < k2; k++ ){
					bool equ = false;
					string exp = "";
					for (int e = (k == 0 ? i : j ); e < (k == 0 ? h : w ); e++ ){
						int row = (k == 0 ? e : i );
						int col = (k == 0 ? j : e );
						if (cur[row][col] != '#' ){
							if (cur[row][col] != '=' ){
								exp += cur[row][col];
								used[row][col] = true;
								u.push (P (row, col ) );
							}else
							if (!equ ){
								exp += cur[row][col];
								used[row][col] = true;
								u.push (P (row, col ) );
								equ = true;
							}else{
								if (!evaluate_exp (exp ) )
									return false;
							} // end if
						}else{ // if (cur[row][col] == '#' )
							if (equ ){
								while (!u.empty() ) u.pop();
								if (!evaluate_exp (exp ) )
									return false;
								equ = false;
							}else{
								while (!u.empty() ){
									P c = u.top(); u.pop();
									used[c.first][c.second] = false;
								} // end while
							} // end if
							exp = "";
							break;
						} // end if
					} // end for
					if (!exp.empty() ){
						if (equ ){
							while (!u.empty() ) u.pop();
							if (!evaluate_exp (exp ) )
								return false;
						}else{
							while (!u.empty() ){
								P c = u.top(); u.pop();
								used[c.first][c.second] = false;
							} // end while
						} // end if
						exp = "";
					} // end if
				} // end for
			} // end if
		} // end rep
	} // end rep

	return true;
}

int main()
{
//	cut here before submit 
//	freopen ("testcase.indian_puzzle3", "r", stdin );
	while (cin >> h >> w && h && w ){
		memset (pz, 0, sizeof (pz ) );
		rep (i, h ){
			string in = "";
			cin >> in;
			rep (j, w ){
				pz[i][j] = in[j];
			} // end rep
		} // end rep

		int n;
		cin >> n;
		vector<char> ope (n, 0 );
		rep (i, n ){
			cin >> ope[i];
		} // end rep
		sort (ALL (ope ) );
		bool found = false;
		do{
			if (!make_pz (ope ) ) continue;

			if (is_correct () ){
				found = true;
				break;
			} // end if
		}while (next_permutation (ALL (ope ) ) );
		
		if (found ){
			printf ("Yes\n" );
		}else{
			printf ("No\n" );
		} // end if
	} // end while
		
	return 0;
}