Problem:
ジグソーパズル

子供から大人まで脳トレ系パズルゲームが流行しています。我々も遅れを取らぬよう、パズルゲームを作ってみんなで遊ぶことにしました。

我々が考えたのはジグソーパズルのゲームで、未完成の部分を埋めるのに必要なピースを選ぶというものです。図 1 (a) はパズルの枠の例です。黒が埋まっている部分、白が未完成の部分です。このパズルを完成するのに使えるピースが図 1 (b) のように与えられます。この中から、枠の白い部分を埋めることができる黒いピースを 1 つ以上選択します。例えば、図 2 の選択例 1 のような組み合わせなら正解となります。一方、選択例 2 のような組み合わせではパズルは完成しないので不正解となります。また、選択したピースが余ってしまう場合も不正解です。このように、プレイヤーは適切なピースを選択することでゲームをクリアします。

そこでこのパズルゲームで用いる判定プログラムを開発することになりました。未完成のパズル、ピースの候補、そしてプレイヤーが選んだピースの組み合わせを入力とし、プレイヤーが適切なピースを選ぶことができていれば YES を、そうでなければ NO と出力するプログラムを作成してください。

この問題では、パズルの枠は H × W の配列で表し、未完成の部分を . (半角ピリオド)、完成している部分を # (半角シャープ)によって与えます。パズルの枠の大きさは最大 20 × 20 とします。また、各ピースは h × w の配列で表し、ピースを構成する部分を # 、そうでない部分を . によって与えます。与えられる各ピースは、元の状態から 90 度、180 度、270 度だけ回転することができます。また、各ピースの大きさは最大 20 × 20 とし、与えられるピースの数 n は最大 10 とします。

Input

複数のデータセットが与えられます。各データセットは以下の形式で与えられます。

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

1 行目に、パズルの枠の大きさ H(縦) と W(横) が与えられます。
2 行目に、文字 gi,j (. または #) からなりパズルの盤面を表す 1 行 W 文字の文字列が H 行与えられます。

続いてピースの数 n、n 個のピースの情報が与えられます。各ピースの情報として、l 番目のピースの配列のサイズ hl (縦) と wl (横)、l 番目のピースの配列が与えられます。l 番目のピースの配列として文字 cli,j (. または #) からなる 1 行 wl 文字の文字列が hl 行与えられます。

続いてプレイヤーの人数 p、i 番目のプレイヤーの選択したピースの数 ki と選択したピースの番号 tj が与えられます。

入力は２つの 0 を含む行で終了します。データセットの数は 10 を超えません。

Output

各データセットごとに、i 番目のプレイヤーが選択したピースの正否 YES または NO を i 行目に出力してください。

Sample 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 for the Sample Input

YES
NO
YES
NO
YES
NO
NO
YES

Solution in Ruby (judge verdict: Time Limit Exceeded)

### class definition

class Grid
  attr_accessor :w, :h, :vals, :size

  def initialize(h, w, strs = [])
    @h = h
    @w = w
    @size = 0

    if strs.empty?
      @vals = h.times.map{0}
    else
      @vals = []
      strs.each do |str|
        bits = str.strip.split("").map{|s| s == '#' ? "1" : "0"}.reverse
        @vals.push bits.join("").to_i(2)
        bits.each{|b| @size += 1 if b == '1'}
      end
    end
  end

  def ==(g0)
    g0.is_a?(Grid) ? (@h == g0.h && @w == g0.w && @vals == g0.vals) : false
  end

  def to_s
    "(#{@h} x #{@w})[#{@size}]\n" +
      @vals.map{|bits| sprintf("%0*b", @w, bits).reverse + "\n"}.join('')
  end

  def val(x, y)
    ((@val[y] >> x) & 1) != 0
  end
end

class Frame < Grid
  def dcopy
    f0 = Frame.new(@h, @w)
    f0.size = @size
    for y in (0...@h)
      f0.vals[y] = @vals[y]
    end
    f0
  end

  def fit?(x0, y0, pc)
    for y in (0...pc.h)
      pcb = (pc.vals[y] << x0)
      frb = @vals[y0 + y]
      return false if ((frb ^ pcb) & frb) != frb
    end
    true
  end

  def set(x0, y0, pc, bit)
    for y in (0...pc.h)
      pcb = (pc.vals[y] << x0)
      if bit
        @vals[y0 + y] |= pcb
      else
        @vals[y0 + y] &= ~pcb
      end
    end
    true
  end
end

### subroutines

class Piece < Grid
  def rotate
    p0 = Piece.new(@w, @h)
    p0.size = @size
    for y in (0...@h)
      for x in (0...@w)
        if (@vals[y] & (1 << x)) != 0
          p0.vals[@w - 1 - x] |= (1 << y)
        end
      end
    end
    p0
  end
end

def find_locs(pc, fr)
  max_h = fr.h - pc.h
  max_w = fr.w - pc.w

  locs = []
  for y in (0..max_h)
    for x in (0..max_w)
      if fr.fit?(x, y, pc)
        locs.push [x, y]
      end
    end
  end

  locs
end

def check_pieces(k, pcset, fr)
  #p "check_pieces(#{k})"
  return true if k >= pcset.length

  for pcl in pcset[k]
    pc, locs = pcl

    max_h = fr.h - pc.h
    max_w = fr.w - pc.w

    for xy in locs
      x, y = xy
      if fr.fit?(x, y, pc)
        fr.set(x, y, pc, true)
        return true if check_pieces(k + 1, pcset, fr)
        fr.set(x, y, pc, false)
      end
    end
  end

  return false
end

### main

while true
  h, w = gets.strip.split(" ").map{|s| s.to_i}
  break if h == 0 && w == 0

  frame = Frame.new(h, w, h.times.map{gets})
  framesize = h * w - frame.size
  #p frame

  n = gets.strip.to_i

  pcs = []
  n.times.each do
    ph, pw = gets.strip.split(" ").map{|s| s.to_i}

    pc0 = Piece.new(ph, pw, ph.times.map{gets})
    locs0 = find_locs(pc0, frame)
    pcls = [[pc0, locs0]]

    for i in (1..3)
      pc1 = pc0.rotate
      if ! pcls.map{|pcl| pcl[0]}.include?(pc1)
        locs1 = find_locs(pc1, frame)
        pcls.push [pc1, locs1] if ! locs1.empty?
      end
      pc0 = pc1
    end
    pcs.push pcls
    #p pcls
  end

  pi = gets.strip.to_i

  pi.times.each do
    choice = gets.strip.split(" ").map{|s| s.to_i - 1}
    np = choice.shift + 1

    ssize = choice.inject(0){|sum, i| sum + pcs[i][0][0].size}

    if ssize != framesize
      puts "NO"
      next
    end

    frame0 = frame.dcopy
    pcset = choice.map{|i| pcs[i]}.sort{|a, b| b[0][0].size <=> a[0][0].size}

    tf = check_pieces(0, pcset, frame0)
    puts tf ? "YES" : "NO"
  end
end