import std.stdio;
import std.typecons;
import std.string;
import std.conv;
import std.algorithm;
import std.range;


int[] dx = [0, 0, 0, +1, -1];
int[] dy = [0, +1, -1, 0, 0];

alias Tuple!(int, "value", int, "start", int, "end") Type;

int H, W, N;
Type[] types;
int[int] table;
char[][] board;
int[][][][] memo;

void main()
{
  for(string[] inputs; (inputs = readln.split)[0] != "0";){
	W = inputs[0].to!int;
	H = inputs[1].to!int;
	
	writeln( solve() );
  }
}

int solve()
{
  board = new char[][](W, H);
  memo = new int[][][][](20, 20, 101, 1 << 8);

  foreach(x; 0..20) foreach(y; 0..20) foreach(t; 0..101) memo[x][y][t][] = -1;
  
  int X, Y;
  
  foreach(y; 0..H){
	auto inputs = readln.split;
	
	foreach(x; 0..W){
	  board[x][y] = inputs[x].to!char;

	  if(board[x][y] == 'P'){
		X = x;
		Y = y;
	  }
	}
  }

  N = readln.chomp.to!int;
  types = new Type[](N);

  foreach(i; 0..N){
	auto inputs = readln.split.map!"a.to!int";

	types[i].value = inputs[1];
	types[i].start = inputs[2];
	types[i].end = inputs[3];

	table[inputs[0]] = i;
  }

  return rec(X, Y, 0, 0);
}

int rec(int x, int y, int t, int used)
{
  if(t == 101) return 0;
  if(used + 1 == 1 << N) return 0;
  if(memo[x][y][t][used] != -1) return memo[x][y][t][used];

  int res = 0;
  
  foreach(i; 0..5){
	int nx = x + dx[i], ny = y + dy[i];

	if(0 <= nx && nx < W && 0 <= ny && ny < H){
	  char data = board[nx][ny];
	  
	  if('0' <= data && data <= '9'){
		int idx = table[data - '0'];
		int s = types[idx].start;
		int e = types[idx].end;

		if(s <= t && t < e && (used & 1 << idx) == 0){
		  res = max(res, rec(x, y, t, used | 1 << idx) + types[idx].value);
		}
	  }else{
		res = max(res, rec(nx, ny, t + 1, used));
	  }
	}
  }

  return memo[x][y][t][used] = res;  
}