#include <iostream>
#include <cstdio>
#include <cassert>

using namespace std;

struct Info {
  int d, s, e;
  Info(int d, int s, int e) : d(d), s(s), e(e) {}
  Info() {}
};

char field[22][22];
int dp[101][1 << 8][22][22];
int good[22][22];
Info info[10];
int X, Y, N, SX, SY, E;
int mp[10];

int dx[] = {1, 0, -1, 0, 0};
int dy[] = {0, 1, 0, -1, 0};

void init() {
  E = 0;
  for (int i = 0; i < 10; i++) {
    mp[i] = -1;
  }
  for (int i = 0; i < 22; i++) {
    for (int j = 0; j < 22; j++) {
      field[i][j] = '*';
    }
  }
  for (int i = 0; i < 22; i++) {
    for (int j = 0; j < 22; j++) {
      good[i][j] = 0;
    }
  }
  
  for (int i = 0; i < 101; i++) {
    for (int j = 0; j < (1 << 8); j++) {
      for (int k = 0; k < 22; k++) {
        for (int l = 0; l < 22; l++) {
          dp[i][j][k][l] = -1;
        }
      }
    }
  }
}

void solve() {
  {
    int t = 0;
    int s = 0;
    for (int g = 0; g < N; g++) {
      if ((good[SY][SX] & (1 << g)) &&
          info[g].s <= 0 &&
          0 < info[g].e ) {
        t += info[g].d;
        s |= (1 << g);
      }
    }
    dp[0][s][SY][SX] = t;
  }
  for (int time = 0; time < E; time++) {
    for (int y = 1; y <= Y; y++) {
      for (int x = 1; x <= X; x++) {
        for (int state = 0; state < (1 << N); state++) {
          int v = dp[time][state][y][x];
          if (v < 0) {
            continue;
          }
          for (int i = 0; i < 5; i++) {
            int nx = x + dx[i];
            int ny = y + dy[i];
            if (field[ny][nx] != '.') {continue;}
            dp[time + 1][state][ny][nx] =
              max(dp[time + 1][state][ny][nx], v);

            if (good[ny][nx] != 0) {
              int t = 0;
              int s = 0;
              for (int g = 0; g < N; g++) {
                if ((good[ny][nx] & (1 << g)) &&
                    !(state & (1 << g)) &&
                    info[g].s <= time + 1 &&
                    time + 1 < info[g].e) {
                  t += info[g].d;
                  s |= (1 << g);
                }
              }
              assert(!(state & s));
              if (t != 0) {
                dp[time + 1][state | s][ny][nx] =
                  max(dp[time + 1][state | s][ny][nx], v + t);
              }
            }
          }
        }
      }
    }
  }
  int mx = 0;
  for (int y = 1; y <= Y; y++) {
    for (int x = 1; x <= X; x++) {
      for (int s = 0; s < (1 << N); s++) {
        mx = max(mx, dp[E][s][y][x]);
      }
    }
  }
  cout << mx << endl;
}

void print() {
  for (int i = 1; i <= Y; i++) {
    for (int j = 1; j <= X; j++) {
      printf("%d ", good[i][j]);
    }
    printf("\n");
  }
  for (int i = 1; i <= Y; i++) {
    for (int j = 1; j <= X; j++) {
      printf("%c ", field[i][j]);
    }
    printf("\n");
  }
}

int main() {
  while (true) {
    cin >> X >> Y;
    if (X == 0 && Y == 0) {
      return 0;
    }
    init();
    int cur = 0;
    for (int i = 1; i <= Y; i++) {
      for (int j = 1; j <= X; j++) {
        cin >> field[i][j];
        if (field[i][j] == 'P') {
          SX = j;
          SY = i;
          field[i][j] = '.';
        }
        else if (field[i][j] != '.') {
          int num = field[i][j] - '0';
          if (mp[num] == -1) {
            mp[num] = cur++;
          }
          field[i][j] = mp[num] + '0';
          for (int k = 0; k < 4; k++) {
            int nx = dx[k] + j;
            int ny = dy[k] + i;
            good[ny][nx] |= (1 << (mp[num]));
          }
        }

      }
    }
    //print();
    cin >> N;
    for (int i = 0; i < N; i++) {
      int g, d, s, e;
      cin >> g >> d >> s >> e;
      info[mp[g]] = Info(d, s, e);
      E = max(e, E);
    }
    assert(N == cur);
    solve();
  }
}

Measured memory_bytes: 50048