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
/*
  sample input
real    0m1.756s
user    0m1.652s
sys     0m0.012s
 */
#include<iostream>
#include<set>
#include<algorithm>
#include<vector>
#include<map>
using namespace std;
#define REP(i,b,n) for(int i=b;i<n;i++)
#define rep(i,n)   REP(i,0,n)
const int R =20,C=20;
class st{
public:
  int r,c;
  bool m[R][C];
  bool all[4][R][C];
  int rotreq;
  int cnt;
  int id;
  void rot(){
    bool tmp[R][C];
    rep(i,r)rep(j,c)tmp[i][j]=m[i][j];
    rep(i,c){
      rep(j,r){
	m[i][j]=tmp[j][c-1-i];
      }
    }
    swap(r,c);
  }
  void set(int i){
    id=i;
    cnt=0;
    rep(i,r)rep(j,c)if (m[i][j])cnt++;
    rotreq=0;
    rep(k,4){
      rot();
      rep(i,r)rep(j,c)all[k][i][j]=m[i][j];
    }
    rep(k,4){
      bool isok=true;
      rep(kk,k){
	if (r != c && k%2 != kk%2)continue;
	bool issame=true;
	rep(i,r)rep(j,c)if (all[k][i][j] != all[kk][i][j])issame=false;
	if (issame)isok=false;
      }
      if (isok)rotreq|=(1<<k);
    }
  }
  bool issame(const st & a)const{
    rep(k,4){
      int rr=k%2==1?r:c,cc=k%2==1?c:r;
      if (a.r != rr || a.c != cc)continue;
      bool issame=true;
      rep(i,rr){
	rep(j,cc){
	  if (a.m[i][j] != all[j][i][j])issame=false;
	}
      }
      if (issame)return true;
    }
    return false;
  }
  bool operator<(const st & a)const{
    if (!issame(a)){
      if (cnt != a.cnt)return cnt > a.cnt;
      else return r*c > a.r*a.c;
    }
    return false;
  }
};

void output(int r,int c,bool m[R][C]){
  rep(i,r){
    rep(j,c)cout << m[i][j];
    cout << endl;
  }
  cout << endl;
}

void getinp(int r,int c,bool a[R][C]){
  rep(i,r){
    rep(j,c){char t;cin>>t;a[i][j]=t=='#';}
  }
}

bool issame[10][10];
bool solve(int now,const vector<int> & num,const int r,const int c,bool ori[R][C],st *in,int last){
  //output(r,c,ori);
  if (now == num.size()){
    rep(i,r)rep(j,c)if (!ori[i][j])return false;
    return true;
  }
  bool covered[R][C]={};
  rep(i,r)rep(j,c)covered[i][j]=ori[i][j];
  int prev=now==0?-1:(issame[num[now]][num[now-1]]?last:-1);
  int p=num[now];
  REP(i,now,num.size()){
    int p=num[i];
    bool havecand=false;
    rep(k,4){
      in[p].rot();
      if ((in[p].rotreq&(1<<k)) == 0)continue;
      rep(i,r){
	if (i+in[p].r > r)break;
	rep(j,c){
	  if (j+in[p].c > c)break;

	  bool isok=true;	
	  rep(ii,in[p].r)rep(jj,in[p].c)
	    if (ori[i+ii][j+jj] && in[p].m[ii][jj]){isok=false;}
	  if (!isok)continue;
	  havecand=true;
	  rep(ii,in[p].r)rep(jj,in[p].c)covered[i+ii][j+jj]=true;
	}
      }
    }
    if (!havecand)return false;
  }

  //output(r,c,covered);

  rep(i,r)rep(j,c)if (!covered[i][j])return false;

  rep(k,4){
    in[p].rot();
    //swap(in[p].r,in[p].c);
    if ((in[p].rotreq&(1<<k)) == 0)continue;
    rep(i,r){
      if (i+in[p].r > r)break;
      rep(j,c){
	if (i*j+c <= prev)continue;
	/*
	if (j+in[p].c > c)break;
	bool isok=true;	
	rep(ii,in[p].r)rep(jj,in[p].c)
	  if (ori[i+ii][j+jj] && in[p].all[k][ii][jj]){isok=false;}
	if (!isok)continue;
	rep(ii,in[p].r)rep(jj,in[p].c)if (in[p].all[k][ii][jj])ori[i+ii][j+jj]=true;
	bool ret=solve(now+1,num,r,c,ori,in,i*c+j);
	rep(ii,in[p].r)rep(jj,in[p].c)if (in[p].all[k][ii][jj])ori[i+ii][j+jj]=false;
	if (ret)return true;
	*/

	if (j+in[p].c > c)break;
	bool isok=true;	
	rep(ii,in[p].r)rep(jj,in[p].c)
	  if (ori[i+ii][j+jj] && in[p].m[ii][jj]){isok=false;}
	if (!isok)continue;
	rep(ii,in[p].r)rep(jj,in[p].c)if (in[p].m[ii][jj])ori[i+ii][j+jj]=true;
	bool ret=solve(now+1,num,r,c,ori,in,i*c+j);
	rep(ii,in[p].r)rep(jj,in[p].c)if (in[p].m[ii][jj])ori[i+ii][j+jj]=false;
	if (ret)return true;

      }
    }
  }
  return false;
}

int main(){
  bool in[R][C]={};
  int r,c;
  while(cin>>r>>c && r){
    int total=0;
    getinp(r,c,in);
    rep(i,r)rep(j,c)if (!in[i][j])total++;

    int n;
    cin>>n;
    st inp[n];
    rep(i,n){
      cin>>inp[i].r>>inp[i].c;
      getinp(inp[i].r,inp[i].c,inp[i].m);
      inp[i].set(i);
    }
    sort(inp,inp+n);
    map<int,int> M;
    rep(i,n)M[inp[i].id]=i;
    rep(i,n){
      REP(j,i+1,n){
	if (inp[i].issame(inp[j]))issame[i][j]=issame[j][i]=true;
	else issame[i][j]=issame[j][i]=false;
      }
    }

    int q;
    cin>>q;
    rep(k,q){
      int num;cin>>num;
      vector<int> a(num);
      int sum=0;
      rep(i,num){
	cin>>a[i];
	a[i]--;
	a[i]=M[a[i]];
	sum+=inp[a[i]].cnt;
      }
      if (sum == total && solve(0,a,r,c,in,inp,-1))cout <<"YES" << endl;
      else cout <<"NO"<<endl;
    }
  }
  return false;
}