import std.stdio : write, writeln, writefln, stdin;
import std.array;
import std.range;
import std.typecons;
import std.algorithm : max, min;
import std.bigint;

int[21][21] map;
int[int] d_list;
int[int] s_list;
int[int] e_list;
int x, y;
int[2] P;
int n;

int INF = 1<<28;

int[][] ofs = [ [1, 0], [0, 1], [0, -1], [-1, 0] ];

int[int] memo;
int dfs(int bits, int value, int[2] p, int time){
	if( bits == (1<<n) -1 ){
		return value;
	}
	int b = bits&0xff;
	b |= (p[0]&0xff)<<8;
	b |= (p[1]&0xff)<<16;
	if(b in memo){
		if( time >= memo[ b ] ){
			return -1;
		}
	}
	
	int max_ = value;
	foreach(k, v; d_list){
		if( ((bits>>k)&0b1)==0b0 ){
			int[2][] req;
			int[] ped_list;
			bfs(p, k, req, ped_list);
			int length = cast(int)req.length;
			foreach(i; length.iota){
				int t = time + ped_list[i];
				if( s_list[k] <= t && t < e_list[k] ){
					int res = dfs( bits | (1<<k), value + v, req[i], t);
					max_ = max(max_, res);
				}else if( t < s_list[k] ){
					if( (s_list[k] - t)%2 == 0b0 ){
						int res = dfs( bits | (1<<k), value + v, req[i], s_list[k] );
						max_ = max(max_, res);
					}else{
						if( s_list[k] + 2 < e_list[k] ){
							int res = dfs( bits | (1<<k), value + v, req[i], s_list[k] + 2 );
							max_ = max(max_, res);
						}
					}
				}
			}
		}
	}
	
	memo[ b ] = time;
	return max_;
}

bool[21][21] done;
int[21][21] foot;
void bfs( int[2] p, int trg, ref int[2][] req, ref int[] ped_list){
	foot = foot.init;
	done = done.init;
	
	int[2][] res;
	
	int[2][] queue;
	done[p[1]][p[0]] = true;
	foot[p[1]][p[0]] = 0;
	queue ~= p;
	while(queue.length){
		int[2] e = queue.front;  queue.popFront;
		
		foreach(ite; ofs){
			int[2] buf = e;
			buf[] += ite[];
			if( 0<=buf[0] && buf[0]<x && 0<=buf[1] && buf[1]<y){
				int imf = map[buf[1]][buf[0]];
				if( imf == -1 ){
					if(!done[buf[1]][buf[0]]){
						done[buf[1]][buf[0]] = true;
						foot[buf[1]][buf[0]] = foot[e[1]][e[0]] + 1;
						queue ~= buf;
					}
				}
				if( imf == trg ){
					req ~= e;
					ped_list ~= foot[e[1]][e[0]];
				}
			}
		}
	}
}

void main(){
	while(true){
		x = next!int;
		y = next!int;
		if(!(x|y)) break;
		memo = memo.init;
		foreach(i; y.iota){
			foreach(j; x.iota){
				string s = next!string;
				if(s=="."){
					map[i][j] = -1;
				}else if(s=="P"){
					map[i][j] = -1;
					P[0] = j;
					P[1] = i;
				}else{
					map[i][j] = s.to!int;
				}
			}
		}
		
		n = next!int;
		foreach(i; n.iota){
			int g = next!int;
			int d = next!int;
			int s = next!int;
			int e = next!int;
			d_list[g] = d;
			s_list[g] = s;
			e_list[g] = e;
		}
		
		dfs(0, 0, P, 0).writeln;
	}
}


import std.stdio : readln;
import std.conv : to;
import std.string : split, chomp;
import std.traits;
string[] input;
string delim = " ";
T next(T)()
in
{
	assert(hasNext());
}
out
{
	input.popFront;
}
body
{
	return input.front.to!T;
}

bool hasNext(){
	if(input.length > 0){
		return true;
	}
	
	string str = readln;
	if(str.length > 0){
		input ~= str.chomp.split(delim);
		return true;
	}else{
		return false;
	}
}


void dbg(T...)(T vs)
{
	import std.stdio : stderr;
	foreach(v; vs)
		stderr.write(v.to!string ~ " ");
	stderr.write("\n");
}

T clone(T)(T v){
	T v_;
	static if(isInputRange!(T)){
		foreach(ite; v){
			v_ ~= ite.clone;
		}
	}else{
		v_ = v;
	}
	
	return v_;
}