#include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
using ld =long double;
const ld eps = 1e-9;

bool check(const vector<vector<pair<int, int>>>&humans, int x, int y) {
	for (int i = 0; i < 4; ++i) {
		auto it=find(humans[i].begin(),humans[i].end(),make_pair(x,y));
		if(it!=humans[i].end())return false;
	}
	return true;
}
int dx[] = { -1,0,1,0,0 };
int dy[] = { 0,1,0,-1,0 };

template<typename T> struct Compress {
	map<T, int>mp;
	map<int, T>revmp;

	Compress(vector<T>vs) {
		setmp(vs);
	}

	Compress() :mp(), revmp() {

	}
	void setmp(vector<T>vs) {
		sort(vs.begin(), vs.end());
		vs.erase(unique(vs.begin(), vs.end()), vs.end());
		for (int i = 0; i < static_cast<int>(vs.size()); ++i) {
			mp[vs[i]] = i;
			revmp[i] = vs[i];
		}
	}

};
struct sale {
	int id;
	int d;
	int s;
	int e;
};

struct aa {
	int flag;
	int x;
	int y;
	int cost;
};


int main()
{
	while (true) {
		int W,H;cin>>W>>H;
		if(!W)break;
		vector<vector<int>>field(H,vector<int>(W,-1));
		vector<sale>aas;
		int sx,sy;
		{
			for (int i = 0; i < H; ++i) {
				for (int j = 0; j < W; ++j) {
					char ch;cin>>ch;
					if (ch == '.') {

					}
					else if (ch == 'P') {
						sx = j;
						sy = i;
					}
					else {
						assert(isdigit(ch));
						field[i][j] = ch - '0';
					}
				}
			}
			int N; cin >> N;
			Compress<int> comp;

			vector<int>v;

			for (int i = 0; i < N; ++i) {
				int g, d, s, e; cin >> g >> d >> s >> e;
				v.push_back(g);
				aas.push_back(sale{ g,d,s,e });
			}
			comp.setmp(v);
			for (auto & line : field) {
				for (auto&n : line) {
					if (n >= 0) {
						if (comp.mp.find(n) != comp.mp.end()) {
							n = comp.mp[n];
						}
						else {
							n=-3;
						}
					}
				}
			}

			vector<sale>real_aas(comp.mp.size(), sale{ -1,0,0,0 });
			for (auto aaa : aas) {
				real_aas[comp.mp[aaa.id]]=(sale{ aaa.id,aaa.d,aaa.s,aaa.e });
			}
			aas=real_aas;
		}
		vector<vector<vector<int>>>memo(H,vector<vector<int>>(W,vector<int>(1<<aas.size(),-1e9)));
		memo[sy][sx][0]=0;

		for (int time = 0; time < 110; ++time) {

			vector<vector<vector<int>>>next_memo(H, vector<vector<int>>(W, vector<int>(1 << aas.size(), -1e9)));
			for (int y = 0; y < H; ++y) {
				for (int x = 0; x < W; ++x) {
					for (int flag = 0; flag < (1 << aas.size()); ++flag) {

						for (int way = 0; way < 4; ++way) {
							const int next_y=y+dy[way];
							const int next_x=x+dx[way];
							if(next_x<0||W<=next_x||next_y<0||H<=next_y)continue;
							else {
								const int k=field[next_y][next_x];
								if (k >= 0&&(flag&(1<<k))==0) {
									
									sale asale(aas[k]);
									if (asale.s <= time&&time < asale.e) {
										memo[y][x][flag|(1<<k)]=max(memo[y][x][flag|(1<<k)],memo[y][x][flag]+asale.d);
									}
								}
							}
						}

						for (int way = 0; way < 5; ++way) {
							const int next_y = y + dy[way];
							const int next_x = x + dx[way];
							if (next_x<0 || W <= next_x || next_y<0 || H <= next_y)continue;
							else {
								const int k = field[next_y][next_x];
								if (k == -1) {
									next_memo[next_y][next_x][flag]=max(next_memo[next_y][next_x][flag],memo[y][x][flag]);
								}
							}
						}
					}
				}
			}
			memo=next_memo;
		}
		int ans=0;
		for (int y = 0; y < H; ++y) {
			for (int x = 0; x < W; ++x) {
				for (int flag = 0; flag < (1 << aas.size()); ++flag) {
					ans=max(ans,memo[y][x][flag]);
					
				}
			}
		}
		cout<<ans<<endl;
		
	}
	return 0;
}


Measured memory_bytes: 3784