#include <iostream>
#include <string>
#include <vector>
#include <cctype>
#include <sstream>
using namespace std;
 
int dx[] = {-1, 0, 1, 0};
 
int cx[] = {-1,0,1};
int W,H,T;
int Gx,Gy;
 
string field[55];
 
void dump()
{
    for(int i=0; i<H; i++) cout << field[i] << endl;
}
 
bool isBlock(char c)
{
    return isalnum(c) || c == '#';
}
 
bool Up(int x, int y, int dir)
{
    int hx = x + dx[dir], hy = y;
    if(hx < 0 || hx >= W) return false;
    if(!isBlock(field[hy][hx])) return false;
 
    int mx = x, my = y - 1;
    if(my < 0) return false;
    if(field[my][mx] != '.' || field[my][hx] != '.') return false;
 
    return true;
}
 
bool Down(int x, int y, int dir)
{
    int hx = x + dx[dir], hy = y;
    if(hx < 0 || hx >= W) return false;
    if(field[hy][hx] != '.') return false;
 
    int mx = hx, my = hy + 1;
    if(my >= H) return false;
    if(field[my][mx] != '.') return false;
 
    return true;
}
 
bool canMove(int x, int y, int mx, int dir)
{
    if(mx < 0 || mx >= W) return false;
    if(field[y][mx] != '.') return false;
    if(y == H-1) return true;
 
    int tx = x;
    while(1) {
        if(!isBlock(field[y+1][tx])) return false;

        if(tx == mx) break;
        tx += dx[dir];
    }
 
    return true;
}
 
bool cPull(int x, int y, int dir)
{
    int tx = x + dx[dir], ty = y;
    int bx = x - dx[dir], by = y;
 
    if(bx < 0 || bx >= W) return false;
    if(!isBlock(field[by][bx])) return false;
    if(field[by][bx] == 'C') return false;
 
    if(tx < 0 || tx >= W) return false;
    if(field[ty][tx] != '.') return false;
 
    field[y][x] = field[by][bx];
    field[by][bx] = '.';
 
    return true;
}
 
bool canPush(int x, int y, int dir)
{
    int tx = x, ty = y;
    while(1) {
        tx += dx[dir];
 
        if(tx<0||tx>=W) break;
        if(!isBlock(field[ty][tx])) break;
        if(field[ty][tx]=='C') return false;
    }
 
    tx -= dx[dir];
 
    if(x == tx) return false;
 
    return true;
}
 
void moveBlock(int x, int y, int dir)
{
    char tmp = field[y][x];
    field[y][x] = '.';
    int tx = x + dx[dir], ty = y;
 
    while(1) {
        if(tx<0||tx>=W) return;
        if(isBlock(field[ty][tx])) {
            tx -= dx[dir];
            break;
        }
        if(tmp != 'I') {
            if(ty == H-1) break;
 
            if(field[ty+1][tx] != 'I') break;
        }
        else {
            if(ty != H-1) {
                if(field[ty+1][tx] == '.') break;
            }
        }
 
        tx += dx[dir];
         
    }
 
    field[ty][tx] = tmp;
}
 
void cPush(int x, int y, int dir)
{
    int tx = x, ty = y;
    while(1) {
        tx += dx[dir];
 
        if(tx < 0 || tx >= W) break;
        if(!isBlock(field[ty][tx])) break;
    }
 
    tx -= dx[dir];
 
    while(x != tx) {
        moveBlock(tx,ty,dir);
 
        tx -= dx[dir];
    }
}
 
bool countDown(int x, int y, int px, int py)
{
    if(x == px && y == py) return false;
    if(py == H-1) return false;
 
    if(!isdigit(field[py+1][px])) return false;
 
    int cnt = field[py+1][px]-'0' - 1;
    if(cnt == 0) field[py+1][px] = '.';
    else field[py+1][px] = cnt + '0';
 
    return true;
}
 
bool vanish()
{
    bool res = false;
    for(int i=1; i<H; i++)
    for(int j=0; j<W; j++) {
        if(field[i][j] == 'B') {
            if(field[i-1][j] != '.') {
                field[i-1][j] = '.';
                res = true;
            }
        }
    }
 
    return res;
}
 
bool fallPlayer(int x, int& y)
{
    int tx=x, ty=y;
    while(1) {
        if(ty == H-1) break;
        if(isBlock(field[ty+1][tx])) break;
 
        ty++;
    }
 
    if(ty==y) return false;
 
    y = ty;
 
    return true;
}
 
bool checkFall(int x, int y)
{
    if(y==H-1) return false;
 
    for(int i=0; i<3; i++) {
        int nx = x + cx[i];
        int ny = y + 1;
        if(nx<0||ny<0||nx>=W||ny>=H) continue;
        if(isBlock(field[ny][nx])) return false;
    }
 
    return true;
}
 
bool fallBlock(int x, int y)
{
    if(y==H-1) return false;
    if(!isBlock(field[y][x])) return false;
 
    char tmp = field[y][x];
    int tx = x, ty = y;
 
    field[y][x] = '.';
 
    while(checkFall(tx,ty)) { ty++; }
 
    field[ty][tx] = tmp;
 
    return (x != tx || y != ty);
}
 
bool loopfallBlock()
{
    bool res = false;
    for(int i=H-2; i>=0; i--)
    for(int j=0; j<W; j++)
    {
        res |= fallBlock(j,i);
    }
 
    return res;
}
 
void execTurnEnd(int x, int& y, int px, int py)
{
    countDown(x,y,px,py);
     
    while(1) {
        bool moved = false;
 
        moved |= vanish();
        moved |= fallPlayer(x,y);
        moved |= loopfallBlock();
 
        if(!moved) break;
    }
}
 
int checkGameOver(int x, int y)
{
    if(y!=H-1) {
        if(field[y+1][x] == 'G') return 0;
        if(field[y+1][x] == 'B') return 1;
    }
 
    if(isBlock(field[y][x])) return 2;
    if(field[Gy][Gx] != 'G') return 3;
 
    return -1;
 
}
 
void output(int type)
{
    if(type==0) cout << "Game Over : Cleared" << endl;
    if(type==1) cout << "Game Over : Death by Hole" << endl;
    if(type==2) cout << "Game Over : Death by Block" << endl;
    if(type==3) cout << "Game Over : Death by Walking Goal" << endl;
    if(type==4) cout << "Game Over : Gave Up" << endl;
}
 
int parseInt(string a)
{
    stringstream ss(a);
 
    int res;
    ss >> res;
 
    return res;
}
 
void doCommand(int sx, int sy, vector<string>& commands)
{
    int x = sx, y = sy;
 
    for(int i = 0; i < commands.size(); i += 2) {
        int px = x, py = y;
 
        int res = checkGameOver(x,y);
        if(res != -1) {
            output(res);
            return;
        }
 
        if(commands[i] == "MOVETO") {
            int s = parseInt(commands[i + 1]) - 1;
            int d = (s < x ? 0 : 2);
            if(canMove(x, y, s, d)) {
                x = s;
            }
        }
 
        if(commands[i] == "PUSH") {
            int d = (commands[i + 1] == "LEFT" ? 0 : 2);
            if(canPush(x,y,d)) {
                cPush(x, y, d);
            }
        }
 
        if(commands[i] == "PULL") {
            int d = (commands[i + 1] == "LEFT" ? 0 : 2);
            if(cPull(x, y, d)) {
                x += dx[d];
            }
        }
 
        if(commands[i] == "GETDOWN") {
            int d = (commands[i + 1] == "LEFT" ? 0 : 2);
            if(Down(x, y, d)) { 
                x += dx[d];
                y += 1;
            }
        }
 
        if(commands[i] == "CLIMB") {
            int d = (commands[i + 1] == "LEFT" ? 0 : 2);
            if(Up(x, y, d)) { 
                x += dx[d];
                y -= 1;
            }
        }
 
        res = checkGameOver(x,y);
        if(res != -1) {
            output(res);
            return;
        }
 
        execTurnEnd(x, y, px, py);
 
    }
 
    int res = checkGameOver(x,y);
    if(res != -1) {
        output(res);
        return;
    }
    output(4);
}
 
int main()
{
 
    while(cin >> H >> W, (W||H)) {
        vector<string> command;
        for(int i=0; i<H; i++) cin >> field[i];
 
        int sx, sy;
        for(int i=0; i<H; i++)
        for(int j=0; j<W; j++) {
            if(field[i][j] == 'S') {
                sx = j;
                sy = i;
                field[i][j] = '.';
            }
            if(field[i][j] == 'G') {
                Gx = j;
                Gy = i;
            }
        }
 
        cin >> T;
        for(int i=0; i<T; i++) {
            string a,b;
            cin >> a >> b;
            command.push_back(a);
            command.push_back(b);
        }
 
        doCommand(sx, sy, command);
    }
}

Measured memory_bytes: 984