#include<iostream>
#include<vector>
#include<string>
#include<bitset>
#include<algorithm>
#include<functional>

#define NIL (-1)
#define MAX 22
#define MAX_PIECES 10
#define BURIED 1
#define NONE 0
#define PZL 1
using namespace std;

class CPiece{
public:
	class piece{
	public:
		int si, sj;
		int H, W;
		short m[MAX][MAX];
		piece(){
			for(int i = 0; i < MAX; ++i)
				for(int j = 0; j < MAX; ++j)
					m[ i ][ j ] = NONE;
		}
		void Print() const{
			for(int i = 1; i <= H; ++i){
				for(int j = 1; j <= W; ++j)
					cout << (m[i][j]==PZL?'#':'.');
				cout << '\n';
			}
		}
		void DetermineSiSj(){
			for(int i = 1; i <= H; ++i)for(int j = 1; j <= W; ++j)if(m[i][j]==PZL){si=i-1;sj=j-1;return ;} 
		}
		bool operator==(const CPiece::piece &t) const {
			if( H == t.H && W == t.W ){
				for(int i = 1; i <= H; ++i)
					for(int j = 1; j <= W; ++j)
						if( m[i][j] != t.m[i][j] )
							return false;
				return true;
			}else
				return false;
		}
	};
	vector<piece> rots;
	void Minimize(){
		int offX = 0, offY = 0;
		for(int i = 1; i <= rots[0].H; ++i){
			bool bClearThisLine = true;
			for(int j = 1; j <= rots[0].W; ++j){
				if( rots[0].m[i][j] == PZL )
					bClearThisLine = false;
			}
			if( !bClearThisLine )
				break;
			else
				offY++;
		}
		for(int i = 1; i <= rots[0].W; ++i){
			bool bClearThisLine = true;
			for(int j = 1; j <= rots[0].H; ++j){
				if( rots[0].m[j][i] == PZL )
					bClearThisLine = false;
			}
			if( !bClearThisLine )
				break;
			else
				offX++;
		}
		
		for(int i = 1; i <= rots[0].H; ++i){
			for(int j = 1; j <= rots[0].W; ++j){
				this->rots[0].m[i][j] = this->rots[0].m[i+offY][j+offX];
			}
		}
		rots[0].H -= offY;
		rots[0].W -= offX;

		offY = 0; offX = 0;

		for(int i = rots[0].H; i >= 1; --i){
			bool bClearThisLine = true;
			for(int j = rots[0].W; j >= 1; --j){
				if( rots[0].m[i][j] == PZL )
					bClearThisLine = false;
			}
			if( !bClearThisLine )
				break;
			else
				offY++;
		}
		for(int i = rots[0].W; i >= 1; --i){
			bool bClearThisLine = true;
			for(int j = rots[0].H; j >= 1; --j){
				if( rots[0].m[j][i] == PZL )
					bClearThisLine = false;
			}
			if( !bClearThisLine )
				break;
			else
				offX++;
		}
		this->rots[0].H -= offY;
		this->rots[0].W -= offX;
	}
	void CreateRotations(){
		rots[0].DetermineSiSj();
		for(int i = 1; i <= 3; ++i){
			bool bExist = false;
			piece next;

			TurnRight90( rots[rots.size()-1], next );
			next.H = rots[rots.size()-1].W;
			next.W = rots[rots.size()-1].H;
			next.DetermineSiSj();

			if( rots.end() == find( rots.begin(), rots.end(), next ) )
				rots.push_back( next );
		}
		//cout << rots.size() << endl;
	}
	int CountPuzzleCells() const {
		int ret = 0;
		for(int i = 1; i <= rots[0].H; ++i)
			for(int j = 1; j <= rots[0].W; ++j)
				if( rots[0].m[i][j] == PZL )
					++ret;
		return ret;
	}
	bool operator>(const CPiece &t) const {
		int area   = this->rots[0].H * this->rots[0].W;
		int area_t = t.rots[0].H     * t.rots[0].W;
		if( area == area_t )
			return this->CountPuzzleCells() > t.CountPuzzleCells();
		else
			return area > area_t;
	}
private:
	void TurnRight90( piece &from, piece &t ){
		double offsetX = (from.W+1) / 2.0;
		double offsetY = (from.H+1) / 2.0;

		for(double i = 1 - offsetY; i <= from.H - offsetY + 0.1; i += 1.0){
			for(double j = 1 - offsetX; j <= from.W - offsetX + 0.1; j += 1.0){
				double ti = j;
				double tj = -i;
				t.m[ int(ti + offsetX) ][ int(tj + offsetY) ] = from.m[ int(i + offsetY) ][ int(j + offsetX) ];
			}
		}
	}
};

class CPieces{
public:
	vector< CPiece > vPieces;
	bitset< MAX_PIECES > bUse;
	bitset< MAX_PIECES > bUsed;
};

class CPuzzle{
public:
	int H, W;
	short m[MAX][MAX];
	short chk[MAX][MAX];

	bool inRangeHeight(int i){ return 1 <= i && i <= H; }
	bool inRangeWidth(int j){ return 1 <= j && j <= W; }
	void Initialize(){
		for(int i = 0; i < MAX; ++i)
			for(int j = 0; j < MAX; ++j){
				m[ i ][ j ] = BURIED;
				chk[MAX][MAX] = 0;
			}
	}
	void Print(){
		for(int i = 1; i <= H; ++i){
			for(int j = 1; j <= W; ++j)
				cout << (m[i][j]==BURIED?'#':'.');
			cout << '\n';
		}
	}
	bool CheckAndPutPiece( int i, int j, unsigned int choose, int rot, CPieces &ps ){
		int tmpm[MAX][MAX];
		bool bOk = true;
		CPiece::piece &pce = ps.vPieces[choose].rots[rot];

		for(int ci = 0; ci < MAX; ++ci)
			for(int cj = 0; cj < MAX; ++cj)
				tmpm[ci][cj]=m[ci][cj];
		
		PutPiece( i, j, pce );

		for(int ci = 1; ci <= H; ++ci){
			for(int cj = 1; cj <= W; ++cj){
				if( m[ci][cj] == NONE ){
					bool bFound = false;
					for(unsigned int k = 0; k < ps.vPieces.size() && !bFound; ++k){
						if( k != choose && ps.bUse[k] && !ps.bUsed[k] ){
							for(unsigned int l = 0; l < ps.vPieces[k].rots.size() && !bFound; ++l){
								if( TryPutPiece(
									ci - ps.vPieces[k].rots[l].si,
									cj - ps.vPieces[k].rots[l].sj,
									ps.vPieces[k].rots[l] ) )
								{
									CheckPiece(
										ci - ps.vPieces[k].rots[l].si,
										cj - ps.vPieces[k].rots[l].sj,
										ps.vPieces[k].rots[l] );
								}
							}
						}
					}
				}
			}
		}

		for(int ci = 1; ci <= H && bOk; ++ci)
			for(int cj = 1; cj <= W && bOk; ++cj)
				if( m[ci][cj] == NONE && chk[ci][cj] == 0 )
					bOk = false;

		if( !bOk ){
			for(int ci = 0; ci < MAX; ++ci)
				for(int cj = 0; cj < MAX; ++cj)
					m[ci][cj] = tmpm[ci][cj];
			return false;
		}else
			return true;
	}
	void ResetChk(){
		for(int i = 0; i < MAX; ++i)
			for(int j = 0; j < MAX; ++j)
				chk[i][j] = 0;
	}
	bool TryPutPiece( int i, int j, CPiece::piece &p ){
		CPiece::piece &pce = p;

		if( !inRangeHeight(i) || !inRangeWidth(j) || !inRangeHeight(i+pce.H-1) || !inRangeWidth(j+pce.W-1) )
			return false;

		for(int ci = i; ci <= i + pce.H - 1; ++ci)
			for(int cj = j; cj <= j + pce.W - 1; ++cj)
				if( m[ci][cj] == BURIED && pce.m[ci-i+1][cj-j+1] == PZL )
					return false;
		return true;
	}

	bool Complete(){
		for(int i = 1; i <= H; ++i)
			for(int j = 1; j <= W; ++j)
				if( m[i][j] == NONE )
					return false;
		return true;
	}
	int CountEmptyCells(){
		int ret = 0;
		for(int i = 1; i <= H; ++i)
			for(int j = 1; j <= W; ++j)
				if( m[i][j] == NONE )
					++ret;
		return ret;
	}
private:
	void CheckPiece( int i, int j, CPiece::piece &p){
		CPiece::piece &pce = p;

		if( !inRangeHeight(i) || !inRangeWidth(j) || !inRangeHeight(i+pce.H-1) || !inRangeWidth(j+pce.W-1) )
			return ;

		for(int ci = i; ci <= i + pce.H - 1; ++ci)
			for(int cj = j; cj <= j + pce.W - 1; ++cj)
				if( m[ci][cj] == NONE && pce.m[ci-i+1][cj-j+1] == PZL )
					chk[ci][cj] = 1;
	}
	void PutPiece( int i, int j, CPiece::piece &p ){
		CPiece::piece &pce = p;

		for(int ci = i; ci <= i + pce.H - 1; ++ci)
			for(int cj = j; cj <= j + pce.W - 1; ++cj)
				if( m[ci][cj] == NONE && pce.m[ci-i+1][cj-j+1] == PZL )
					m[ci][cj] = BURIED;
	}
};


bool DFS( CPuzzle &p, CPieces &ps, bool &bAbort ){
	int choose = NIL;

	//p.Print();cout<<endl;

	for(unsigned int i = 0; i < ps.vPieces.size(); ++i){
		if( ps.bUse[i] && !ps.bUsed[i] ){
			choose = i;
			break;
		}
	}

	if( choose == NIL ){
		if( p.Complete() )
			return true;
		else
			return false;
	}else if( p.Complete() ){
		bAbort = true;
		return true;
	}

	for(unsigned int k = 0; k < ps.vPieces[choose].rots.size(); ++k){
		
		/*cout << "Considering : "<<ps.vPieces[choose].rots[k].si <<"," <<ps.vPieces[choose].rots[k].sj<<endl;
		ps.vPieces[choose].rots[k].Print();
		cout << endl;*/
		
		for(int i = 1; i <= p.H; ++i){
			for(int j = 1; j <= p.W; ++j){
				if( p.m[i][j] == NONE ){
					if( p.TryPutPiece(
						i - ps.vPieces[choose].rots[k].si,
						j - ps.vPieces[choose].rots[k].sj,
						ps.vPieces[choose].rots[k] ) )
					{
						CPuzzle pzl_tmp = p;
						bool bResult;

						/*cout << "Chosen: " << choose << " (i,j) = (" << i << "," << j << ")\n";
						cout << "Piece :\n";
						ps.vPieces[choose].rots[k].Print();
						cout << endl;*/

						pzl_tmp.ResetChk();
						if( pzl_tmp.CheckAndPutPiece(
							i - ps.vPieces[choose].rots[k].si,
							j - ps.vPieces[choose].rots[k].sj,
							choose,
							k,
							ps
							) )
						{
							ps.bUsed.set( choose );
							bResult = DFS( pzl_tmp, ps, bAbort );
							if( bResult )
								return true;
							ps.bUsed.reset( choose );
						}
					}
				}
			}
		}
	}
	return false;
}
int main(){
	while( true ){
		int n;
		int p, pnum;
		CPuzzle pzl;
		CPieces ps;

		pzl.Initialize();

		cin >> pzl.H >> pzl.W;

		if( pzl.H == 0 && pzl.W == 0 )
			break;

		for(int i = 1; i <= pzl.H; ++i){
			string s;
			cin >> s;
			for(int j = 1; j <= pzl.W; ++j){
				if( s[j - 1] == '#' ) 
					pzl.m[ i ][ j ] = BURIED;
				else
					pzl.m[ i ][ j ] = NONE;
			}
		}

		cin >> n;
		for(int i = 0; i < n; ++i){
			CPiece tmp;
			CPiece::piece t;
			
			cin >> t.H >> t.W;
			for(int j = 1; j <= t.H; ++j){
				string s;
				cin >> s;
				for(int k = 1; k <= t.W; ++k){
					if( s[k - 1] == '#' )
						t.m[ j ][ k ] = PZL;
					else
						t.m[ j ][ k ] = NONE;
				}	
			}
			tmp.rots.push_back( t );
			tmp.Minimize();
			tmp.CreateRotations();
			ps.vPieces.push_back( tmp );
		}

		cin >> p;
		for(int i = 0; i < p; ++i){
			cin >> pnum;
			bool bAbort = false;
			int cntPzl = 0;
			int cntPss = 0;
			CPuzzle pzl_tmp = pzl;
			CPieces ps_tmp;

			ps_tmp.bUse.reset();
			ps_tmp.bUsed.reset();
			for( int j = 0; j < pnum; ++j ){
				int t;
				cin >> t;
				ps_tmp.vPieces.push_back( ps.vPieces[t-1] );
				cntPss += ps.vPieces[t-1].CountPuzzleCells();
				ps_tmp.bUse.set( j );
			}
			cntPzl = pzl_tmp.CountEmptyCells();

			if( cntPzl != cntPss ){
				cout << "NO\n";
				continue;
			}

			/* ツパツズツδ仰づ個妥・ツつォツつ「ツ渉づ可青ョツ療ア */
			sort( ps_tmp.vPieces.begin(), ps_tmp.vPieces.end(), greater<CPiece>() );

			if( DFS( pzl_tmp, ps_tmp, bAbort ) )
				cout << (bAbort ? "NO\n" : "YES\n");
			else
				cout << "NO\n";
		}
	}
	return 0;
}
### Prompt

Create a solution in Cpp for the following problem:

Brain training puzzle games are popular from children to adults. We decided to make a puzzle game and play with everyone so that we could keep up.

We thought of a jigsaw puzzle game where you pick the pieces you need to fill in the unfinished parts. Figure 1 (a) is an example of a puzzle frame. The part where black is buried and the part where white is unfinished. Pieces that can be used to complete this puzzle are given as shown in Figure 1 (b). From this, select one or more black pieces that can fill the white part of the frame. For example, the combination shown in Selection Example 1 in Fig. 2 is correct. On the other hand, the combination like selection example 2 will not complete the puzzle, so it will be incorrect. It is also incorrect if the selected piece is left over. In this way, the player clears the game by selecting the appropriate piece.

Therefore, we decided to develop a judgment program to be used in this puzzle game. Create a program that inputs a combination of unfinished puzzles, piece candidates, and pieces selected by the player, and outputs YES if the player can select the appropriate piece, and NO otherwise. Please give me.

In this problem, the puzzle frame is represented by an array of H x W, and the unfinished part is given by. (Half-width period) and the completed part is given by # (half-width sharp). The maximum size of the puzzle frame is 20 x 20. In addition, each piece is represented by an array of h × w, and the parts that make up the piece are given by # and the parts that are not are given by. Each given piece can be rotated 90 degrees, 180 degrees, and 270 degrees from its original state. Also, the maximum size of each piece is 20 x 20, and the maximum number of pieces n given is 10.

<image>



Input

Given multiple datasets. Each dataset is given in the following format:


H W
g1,1 g1,2 ... g1, W
g2,1 g2,2 ... g2, W
::
gH, 1gH, 2 ... gH, W
n
h1 w1
c11,1 c11,2 ... c11, w1
c12,1 c12,2 ... c12, w1
::
c1h1,1c1h1,2 ... c1h1, w1
::
::
hn wn
cn1,1 cn1,2 ... cn1, wn
cn2,1 cn2,2 ... cn2, wn
::
cnhn, 1cnhn, 2 ... cnhn, wn
p
k1 t1 t2 ... tk1
k2 t1 t2 ... tk2
::
kp t1 t2 ... tkp


The first line gives the puzzle frame sizes H (vertical) and W (horizontal). The second line is given the H line, which consists of the letters gi, j (. Or #) and represents the board of the puzzle.

This is followed by information on the number of pieces n, n pieces. The information for each piece is given the size of the array of l-th pieces, hl (vertical) and wl (horizontal), and the array of l-th pieces. A one-line wl character string consisting of the characters cli, j (. Or #) is given as an array of l-th pieces on the hl line.

It is then given the number of players p, the number of selected pieces for the i-th player ki, and the number tj for the selected pieces.

Input ends with a line containing two 0s. The number of datasets does not exceed 10.

Output

For each dataset, print the correctness YES or NO of the piece selected by the i-th player on line i.

Examples

Input

14 20
####################
###.............####
####..........######
#######.....########
########.....#######
###..###......######
###..####......#####
#########......#####
###########.....####
############.....###
###.########......##
###.#######...###.##
##...###....#####.##
####################
10
12 15
#############..
.##########....
....#####......
.....#####.....
.....######....
......######...
......######...
........#####..
.........#####.
.........######
........###...#
.....####.....#
3 3
#..
###
#..
2 2
##
##
4 10
....#####.
....######
...###...#
####.....#
6 5
....#
..###
#####
##.##
#..##
#..#.
6 4
...#
.###
####
##.#
##.#
#...
2 6
######
.#####
2 7
..#####
#######
2 13
#############
.##########..
6 9
#####....
.######..
.######..
..######.
...#####.
....#####
8
3 1 2 3
4 1 2 3 4
7 2 3 4 5 6 7 8
5 2 3 10 7 8
6 2 3 9 5 6 4
8 2 3 4 6 9 5 4 10
4 4 5 6 9
5 10 2 3 4 9
0 0


Output

YES
NO
YES
NO
YES
NO
NO
YES


Input

14 20

.............####
..........######
.....########
.....#######
..###......######
..####......#####
......#####
.....####
.....###
.########......##
.#######...###.##
...###....#####.##

10
12 15
..
.##########....
....#####......
.....#####.....
.....######....
......######...
......######...
........#####..
.........#####.
.........######
........###...#
.....####.....#
3 3
..

..
2 2


4 10
....#####.
....######
...###...#
.....#
6 5
....#
..###

.##
..##
..#.
6 4
...#
.###

.#
.#
...
2 6

.#####
2 7
..#####

2 13

.##########..
6 9
....
.######..
.######..
..######.
...#####.
....#####
8
3 1 2 3
4 1 2 3 4
7 2 3 4 5 6 7 8
5 2 3 10 7 8
6 2 3 9 5 6 4
8 2 3 4 6 9 5 4 10
4 4 5 6 9
5 10 2 3 4 9
0 0


Output

YES
NO
YES
NO
YES
NO
NO
YES

### Response

```cpp
#include<iostream>
#include<vector>
#include<string>
#include<bitset>
#include<algorithm>
#include<functional>

#define NIL (-1)
#define MAX 22
#define MAX_PIECES 10
#define BURIED 1
#define NONE 0
#define PZL 1
using namespace std;

class CPiece{
public:
	class piece{
	public:
		int si, sj;
		int H, W;
		short m[MAX][MAX];
		piece(){
			for(int i = 0; i < MAX; ++i)
				for(int j = 0; j < MAX; ++j)
					m[ i ][ j ] = NONE;
		}
		void Print() const{
			for(int i = 1; i <= H; ++i){
				for(int j = 1; j <= W; ++j)
					cout << (m[i][j]==PZL?'#':'.');
				cout << '\n';
			}
		}
		void DetermineSiSj(){
			for(int i = 1; i <= H; ++i)for(int j = 1; j <= W; ++j)if(m[i][j]==PZL){si=i-1;sj=j-1;return ;} 
		}
		bool operator==(const CPiece::piece &t) const {
			if( H == t.H && W == t.W ){
				for(int i = 1; i <= H; ++i)
					for(int j = 1; j <= W; ++j)
						if( m[i][j] != t.m[i][j] )
							return false;
				return true;
			}else
				return false;
		}
	};
	vector<piece> rots;
	void Minimize(){
		int offX = 0, offY = 0;
		for(int i = 1; i <= rots[0].H; ++i){
			bool bClearThisLine = true;
			for(int j = 1; j <= rots[0].W; ++j){
				if( rots[0].m[i][j] == PZL )
					bClearThisLine = false;
			}
			if( !bClearThisLine )
				break;
			else
				offY++;
		}
		for(int i = 1; i <= rots[0].W; ++i){
			bool bClearThisLine = true;
			for(int j = 1; j <= rots[0].H; ++j){
				if( rots[0].m[j][i] == PZL )
					bClearThisLine = false;
			}
			if( !bClearThisLine )
				break;
			else
				offX++;
		}
		
		for(int i = 1; i <= rots[0].H; ++i){
			for(int j = 1; j <= rots[0].W; ++j){
				this->rots[0].m[i][j] = this->rots[0].m[i+offY][j+offX];
			}
		}
		rots[0].H -= offY;
		rots[0].W -= offX;

		offY = 0; offX = 0;

		for(int i = rots[0].H; i >= 1; --i){
			bool bClearThisLine = true;
			for(int j = rots[0].W; j >= 1; --j){
				if( rots[0].m[i][j] == PZL )
					bClearThisLine = false;
			}
			if( !bClearThisLine )
				break;
			else
				offY++;
		}
		for(int i = rots[0].W; i >= 1; --i){
			bool bClearThisLine = true;
			for(int j = rots[0].H; j >= 1; --j){
				if( rots[0].m[j][i] == PZL )
					bClearThisLine = false;
			}
			if( !bClearThisLine )
				break;
			else
				offX++;
		}
		this->rots[0].H -= offY;
		this->rots[0].W -= offX;
	}
	void CreateRotations(){
		rots[0].DetermineSiSj();
		for(int i = 1; i <= 3; ++i){
			bool bExist = false;
			piece next;

			TurnRight90( rots[rots.size()-1], next );
			next.H = rots[rots.size()-1].W;
			next.W = rots[rots.size()-1].H;
			next.DetermineSiSj();

			if( rots.end() == find( rots.begin(), rots.end(), next ) )
				rots.push_back( next );
		}
		//cout << rots.size() << endl;
	}
	int CountPuzzleCells() const {
		int ret = 0;
		for(int i = 1; i <= rots[0].H; ++i)
			for(int j = 1; j <= rots[0].W; ++j)
				if( rots[0].m[i][j] == PZL )
					++ret;
		return ret;
	}
	bool operator>(const CPiece &t) const {
		int area   = this->rots[0].H * this->rots[0].W;
		int area_t = t.rots[0].H     * t.rots[0].W;
		if( area == area_t )
			return this->CountPuzzleCells() > t.CountPuzzleCells();
		else
			return area > area_t;
	}
private:
	void TurnRight90( piece &from, piece &t ){
		double offsetX = (from.W+1) / 2.0;
		double offsetY = (from.H+1) / 2.0;

		for(double i = 1 - offsetY; i <= from.H - offsetY + 0.1; i += 1.0){
			for(double j = 1 - offsetX; j <= from.W - offsetX + 0.1; j += 1.0){
				double ti = j;
				double tj = -i;
				t.m[ int(ti + offsetX) ][ int(tj + offsetY) ] = from.m[ int(i + offsetY) ][ int(j + offsetX) ];
			}
		}
	}
};

class CPieces{
public:
	vector< CPiece > vPieces;
	bitset< MAX_PIECES > bUse;
	bitset< MAX_PIECES > bUsed;
};

class CPuzzle{
public:
	int H, W;
	short m[MAX][MAX];
	short chk[MAX][MAX];

	bool inRangeHeight(int i){ return 1 <= i && i <= H; }
	bool inRangeWidth(int j){ return 1 <= j && j <= W; }
	void Initialize(){
		for(int i = 0; i < MAX; ++i)
			for(int j = 0; j < MAX; ++j){
				m[ i ][ j ] = BURIED;
				chk[MAX][MAX] = 0;
			}
	}
	void Print(){
		for(int i = 1; i <= H; ++i){
			for(int j = 1; j <= W; ++j)
				cout << (m[i][j]==BURIED?'#':'.');
			cout << '\n';
		}
	}
	bool CheckAndPutPiece( int i, int j, unsigned int choose, int rot, CPieces &ps ){
		int tmpm[MAX][MAX];
		bool bOk = true;
		CPiece::piece &pce = ps.vPieces[choose].rots[rot];

		for(int ci = 0; ci < MAX; ++ci)
			for(int cj = 0; cj < MAX; ++cj)
				tmpm[ci][cj]=m[ci][cj];
		
		PutPiece( i, j, pce );

		for(int ci = 1; ci <= H; ++ci){
			for(int cj = 1; cj <= W; ++cj){
				if( m[ci][cj] == NONE ){
					bool bFound = false;
					for(unsigned int k = 0; k < ps.vPieces.size() && !bFound; ++k){
						if( k != choose && ps.bUse[k] && !ps.bUsed[k] ){
							for(unsigned int l = 0; l < ps.vPieces[k].rots.size() && !bFound; ++l){
								if( TryPutPiece(
									ci - ps.vPieces[k].rots[l].si,
									cj - ps.vPieces[k].rots[l].sj,
									ps.vPieces[k].rots[l] ) )
								{
									CheckPiece(
										ci - ps.vPieces[k].rots[l].si,
										cj - ps.vPieces[k].rots[l].sj,
										ps.vPieces[k].rots[l] );
								}
							}
						}
					}
				}
			}
		}

		for(int ci = 1; ci <= H && bOk; ++ci)
			for(int cj = 1; cj <= W && bOk; ++cj)
				if( m[ci][cj] == NONE && chk[ci][cj] == 0 )
					bOk = false;

		if( !bOk ){
			for(int ci = 0; ci < MAX; ++ci)
				for(int cj = 0; cj < MAX; ++cj)
					m[ci][cj] = tmpm[ci][cj];
			return false;
		}else
			return true;
	}
	void ResetChk(){
		for(int i = 0; i < MAX; ++i)
			for(int j = 0; j < MAX; ++j)
				chk[i][j] = 0;
	}
	bool TryPutPiece( int i, int j, CPiece::piece &p ){
		CPiece::piece &pce = p;

		if( !inRangeHeight(i) || !inRangeWidth(j) || !inRangeHeight(i+pce.H-1) || !inRangeWidth(j+pce.W-1) )
			return false;

		for(int ci = i; ci <= i + pce.H - 1; ++ci)
			for(int cj = j; cj <= j + pce.W - 1; ++cj)
				if( m[ci][cj] == BURIED && pce.m[ci-i+1][cj-j+1] == PZL )
					return false;
		return true;
	}

	bool Complete(){
		for(int i = 1; i <= H; ++i)
			for(int j = 1; j <= W; ++j)
				if( m[i][j] == NONE )
					return false;
		return true;
	}
	int CountEmptyCells(){
		int ret = 0;
		for(int i = 1; i <= H; ++i)
			for(int j = 1; j <= W; ++j)
				if( m[i][j] == NONE )
					++ret;
		return ret;
	}
private:
	void CheckPiece( int i, int j, CPiece::piece &p){
		CPiece::piece &pce = p;

		if( !inRangeHeight(i) || !inRangeWidth(j) || !inRangeHeight(i+pce.H-1) || !inRangeWidth(j+pce.W-1) )
			return ;

		for(int ci = i; ci <= i + pce.H - 1; ++ci)
			for(int cj = j; cj <= j + pce.W - 1; ++cj)
				if( m[ci][cj] == NONE && pce.m[ci-i+1][cj-j+1] == PZL )
					chk[ci][cj] = 1;
	}
	void PutPiece( int i, int j, CPiece::piece &p ){
		CPiece::piece &pce = p;

		for(int ci = i; ci <= i + pce.H - 1; ++ci)
			for(int cj = j; cj <= j + pce.W - 1; ++cj)
				if( m[ci][cj] == NONE && pce.m[ci-i+1][cj-j+1] == PZL )
					m[ci][cj] = BURIED;
	}
};


bool DFS( CPuzzle &p, CPieces &ps, bool &bAbort ){
	int choose = NIL;

	//p.Print();cout<<endl;

	for(unsigned int i = 0; i < ps.vPieces.size(); ++i){
		if( ps.bUse[i] && !ps.bUsed[i] ){
			choose = i;
			break;
		}
	}

	if( choose == NIL ){
		if( p.Complete() )
			return true;
		else
			return false;
	}else if( p.Complete() ){
		bAbort = true;
		return true;
	}

	for(unsigned int k = 0; k < ps.vPieces[choose].rots.size(); ++k){
		
		/*cout << "Considering : "<<ps.vPieces[choose].rots[k].si <<"," <<ps.vPieces[choose].rots[k].sj<<endl;
		ps.vPieces[choose].rots[k].Print();
		cout << endl;*/
		
		for(int i = 1; i <= p.H; ++i){
			for(int j = 1; j <= p.W; ++j){
				if( p.m[i][j] == NONE ){
					if( p.TryPutPiece(
						i - ps.vPieces[choose].rots[k].si,
						j - ps.vPieces[choose].rots[k].sj,
						ps.vPieces[choose].rots[k] ) )
					{
						CPuzzle pzl_tmp = p;
						bool bResult;

						/*cout << "Chosen: " << choose << " (i,j) = (" << i << "," << j << ")\n";
						cout << "Piece :\n";
						ps.vPieces[choose].rots[k].Print();
						cout << endl;*/

						pzl_tmp.ResetChk();
						if( pzl_tmp.CheckAndPutPiece(
							i - ps.vPieces[choose].rots[k].si,
							j - ps.vPieces[choose].rots[k].sj,
							choose,
							k,
							ps
							) )
						{
							ps.bUsed.set( choose );
							bResult = DFS( pzl_tmp, ps, bAbort );
							if( bResult )
								return true;
							ps.bUsed.reset( choose );
						}
					}
				}
			}
		}
	}
	return false;
}
int main(){
	while( true ){
		int n;
		int p, pnum;
		CPuzzle pzl;
		CPieces ps;

		pzl.Initialize();

		cin >> pzl.H >> pzl.W;

		if( pzl.H == 0 && pzl.W == 0 )
			break;

		for(int i = 1; i <= pzl.H; ++i){
			string s;
			cin >> s;
			for(int j = 1; j <= pzl.W; ++j){
				if( s[j - 1] == '#' ) 
					pzl.m[ i ][ j ] = BURIED;
				else
					pzl.m[ i ][ j ] = NONE;
			}
		}

		cin >> n;
		for(int i = 0; i < n; ++i){
			CPiece tmp;
			CPiece::piece t;
			
			cin >> t.H >> t.W;
			for(int j = 1; j <= t.H; ++j){
				string s;
				cin >> s;
				for(int k = 1; k <= t.W; ++k){
					if( s[k - 1] == '#' )
						t.m[ j ][ k ] = PZL;
					else
						t.m[ j ][ k ] = NONE;
				}	
			}
			tmp.rots.push_back( t );
			tmp.Minimize();
			tmp.CreateRotations();
			ps.vPieces.push_back( tmp );
		}

		cin >> p;
		for(int i = 0; i < p; ++i){
			cin >> pnum;
			bool bAbort = false;
			int cntPzl = 0;
			int cntPss = 0;
			CPuzzle pzl_tmp = pzl;
			CPieces ps_tmp;

			ps_tmp.bUse.reset();
			ps_tmp.bUsed.reset();
			for( int j = 0; j < pnum; ++j ){
				int t;
				cin >> t;
				ps_tmp.vPieces.push_back( ps.vPieces[t-1] );
				cntPss += ps.vPieces[t-1].CountPuzzleCells();
				ps_tmp.bUse.set( j );
			}
			cntPzl = pzl_tmp.CountEmptyCells();

			if( cntPzl != cntPss ){
				cout << "NO\n";
				continue;
			}

			/* ツパツズツδ仰づ個妥・ツつォツつ「ツ渉づ可青ョツ療ア */
			sort( ps_tmp.vPieces.begin(), ps_tmp.vPieces.end(), greater<CPiece>() );

			if( DFS( pzl_tmp, ps_tmp, bAbort ) )
				cout << (bAbort ? "NO\n" : "YES\n");
			else
				cout << "NO\n";
		}
	}
	return 0;
}
```