Problem:
Problem L: The Tower
Your task is to write a program that reads some lines of command for the following game and simulates operations until the player reaches the game over. We call following 2-dimensional grid of
m
by
n
characters Tower. The objective of this game is to move blocks in the tower to climb to a goal block. In the following grid, the bottom line is the first row and the top one is the
n
-th row. The leftmost column is the first column and the rightmost one is the
m
-th column.
.................... (
n
=13 th row)
.....#.....G........
....##.....##.....##
...####...IIII...###
..####.....##.....##
...####B..####....##
....###....#33##..##
.....####...#33#3.##
.##CCCC#####2##.####
..#####..###.#...###
...###....###.....#1
....####..##.......#
S..###..#.####.....# (1st row)
Explanation of cell marks:
'#' : Normal block
Normal block.
'I' : Ice block
Block made of the ice.  This has different features from the normal one.
'G' : Goal block
If the player climbs to this, game is over and clear.
'C' : Fixed block
The player can not move this directly.
'B' : Different dimensional block
If the player climbs to this, game is over and lose.
'.' : Space
Empty place.
'3' : Fragile block(3)
A fragile block of count 3.
'2' : Fragile block(2)
A fragile block of count 2.
'1' : Fragile block(1)
A fragile block of count 1.  If the count is zero, this block will be broken and become a space.
'S' : Player
The player.
Explanation of relative positions:
123
4S5
678
In the following description, assume that left up is the position of 1, up(over S) is 2, right up is 3, left is 4, right is 5, left down is 6, down(under S) is 7, right down is 8 for S.
Movements of the player
The player must not go out of the tower.  The outside of the tower is considered as space cells.
Move
The player can move everywhere in the current row as long as some of the following conditions are satisfied.
The player is in the first row and the target cell is a space.
There are blocks under the route connecting the current cell and the target cell (horizontal segment) and the target cell is a space.  It is OK that some blocks in the horizontal segment.  And the case that some of blocks under the segment are different dimensional ones, it is also OK.
Climb
If the player at the row below the n-th row (from 1st to n-1 th row) and there is a block in the right(left) and both of a cell over the player (up cell) and a right up(left up) cell are space, the player can move to the right up(left up) cell.
Get down
If the player at the row above the 1st row (from 2nd to n-th row), he can get down to right(left) down.  If the direction for getting down is right(left) and if there is no blocks in the right down (left down) cell and the right (left) cell, the player can move to the right down (left down) cell.
Push
If there is a block or continuous blocks in the right or left of the player, he can push the blocks to the direction one cell.  Here, blocks are "continuous" if there are two or more block
...(truncated)

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
#define r(i,n) for(int i=0;i<n;i++)
#define int long long
using namespace std;
typedef pair<int,int>P;
#define F first
#define S second

void INPUT();
int s_to_i(string z);

string s[55],com[1000],DIR[1000];
int x,y,gx,gy,n,h,w,ppp=1;

void GO(int Y,int X){
	if(s[y-1][x]=='3')s[y-1][x]='2';
	else if(s[y-1][x]=='2')s[y-1][x]='1';
	else if(s[y-1][x]=='1')s[y-1][x]='.';
	y = Y;
	x = X;
}

void Moveto(int t){
	if(s[y][t]!='.'||x==t||y==h-1)return;

	int off=(x<t?1:-1);
	int nx=x;

	if(y==1){
		GO(y,t);
		return;
	}

	int f=0;

	while(0<=nx&&nx<w&&nx!=t){
		if(s[y-1][nx+off]=='.')return;
		nx+=off;
	}

	GO(y,nx);
	return;
}

void Climb(string z){
	int ty=1;
	int tx=(z=="LEFT"?-1:1);
	if(y>=h-2)return;
	if( y+ty<0 || h<=y+ty || x+tx<0 || w<=x+tx )return;
	if( s[y][x+tx] == '.' )return;
	if( s[y+1][x+tx] == '.' && s[y+1][x] == '.' ){
		GO(y+ty,x+tx);
	}
	return;
}

void Getdown(string z){
	int ty=-1;
	int tx=(z=="LEFT"?-1:1);
	if( y+ty<0 || h<=y+ty || x+tx<0 || w<=x+tx )return;
	if( s[y][x+tx] == '.' && s[y-1][x+tx] == '.' ){
		GO(y+ty,x+tx);
	}
	return;
}

void Pull(string z){
	int tx=(z=="LEFT"?1:-1);
	if( x+tx<0 || w<=x+tx )return;
	if( x-tx<0 || w<=x-tx )return;
	if( s[y][x+tx] == 'C' )return;
	if( s[y][x+tx] == '.' )return;
	if( s[y][x-tx] != '.' )return;
	s[y][x]=s[y][x+tx];
	s[y][x+tx]='.';
	GO(y,x-tx);
	return;
}

void Push(string z){
	int tx=(z=="LEFT"?-1:1);
	if( x+tx<0 || w<=x+tx )return;
	int nx=x+tx;
	while(0<=nx&&nx<w&&s[y][nx]!='.'){
		if(s[y][nx]=='C')return;
		nx+=tx;
	}
	//r(i,h)cout<<s[h-1-i]<<endl;
	nx-=tx;
	for(int i=nx;i!=x;i-=tx){
		int p=i;
		while(1){
			if(p+tx<0 || w<=p+tx){
				s[y][p]='.';
				break;
			}
			if(s[y][p+tx]!='.')break;
			s[y][p+tx]=s[y][p];
			s[y][p]='.';
			if(!((s[y][p+tx]=='I'&&s[y-1][p+tx]!='.')||(s[y-1][p+tx]=='I')))break;
			p+=tx;
		}
	}
	//r(i,h)cout<<s[h-1-i]<<endl;
}

int RAKKA(){
//if(ppp==1920){s[y][x]='S';r(i,h)cout<<s[h-1-i]<<endl;s[y][x]='.';}
//cout<<y<<' '<<x<<endl;
	L:;
	r(i,h-1)r(j,w){
	//	cout<<i<<' '<<j<<endl;
		if(s[i][j]=='B'){
	//		cout<<i<<' '<<j<<endl;
			if(i+1==y&&j==x)return 2;
			if(ppp>=1900&&s[i+1][j]=='G')continue;
			s[i+1][j]='.';
		}
	}
	int T=0;
	while(s[y-1][x]=='.')y--,T++;
	if(T)goto L;
	int XXX=0;
	//s[y][x]='S';r(i,h)cout<<s[h-1-i]<<endl;s[y][x]='.';
	r(i,h-1)r(j,w){
	//	cout<<i<<' '<<j<<endl;
		if(s[i][j]=='G'){
			if(i!=gy||j!=gx)return 4;
			if(i+1==y&&j==x)return 1;
			XXX++;
		}
	//  cout<<i<<' '<<j<<endl;
	}
	if(!XXX)return 4;
	//cout<<y<<' '<<x<<endl;
	LL:;
	for(int i=2;i<h;i++){
		for(int j=0;j<w;j++){
			if(s[i][j]=='.')continue;
			//if(s[i][j]=='C')continue;
			int count=0;
			while(1){
				int sum=0;
				r(k,3){
					if(j+k-1<0||w<=j+k-1)continue;
					if(s[i-1][j+k-1]!='.')sum++;
				}
				if(sum)break;
				count++;
				T++;
				s[i-1][j]=s[i][j];
				s[i][j]='.';
				i--;
				//break;
				//cout<<i<<j<<endl;
			}
			if(s[y][x]!='.'){
			//	cout<<s[y][x]<<endl;
				return 3;
			}
			if(count) goto LL;
		}
	};
	if(T)goto L;
	//cout<<y<<x<<endl;
	return 0;
}


signed main(){
	while( 1 ){

		INPUT();
		r(i,n){
			int f=0;

			if(s[y-1][x]=='G'){
				cout<<"Game Over : Cleared"<<endl;
				break;
			}
			if(s[y-1][x]=='B'){
				cout<<"Game Over : Death by Hole"<<endl;
				break;
			}

			//cout<<i<<endl;

			if( com[i] == "MOVETO"  )  Moveto(s_to_i(DIR[i])-1);
			if( com[i] == "CLIMB"   )  Climb(DIR[i]);
			if( com[i] == "GETDOWN" )  Getdown(DIR[i]);
			if( com[i] == "PUSH"    )  Push(DIR[i]);
			if( com[i] == "PULL"    )  Pull(DIR[i]);

			//cout<<i<<endl;

			f = RAKKA();
			if(f==1){
				cout<<"Game Over : Cleared"<<endl;
				break;
			}
			if(f==2){
				cout<<"Game Over : Death by Hole"<<endl;
				break;
			}
			if(f==3){
				cout<<"Game Over : Death by Block"<<endl;
				break;
			}
			//cout<<i<<endl;
			if(f==4){
				cout<<"Game Over : Death by Walking Goal"<<endl;
				//return 0;
				break;
			}
			//cout<<i<<endl;

			if(i==n-1){
				cout<<"Game Over : Gave Up"<<endl;
				break;
			}
		}
		ppp++;
	}
}

void INPUT(){
	cin>>h>>w;
	if(h==0)exit(0);
	r(i,52)s[i]="";
	r(i,h)cin>>s[h-i];
	r(i,w)s[0]+='#';
	r(i,w)s[h+1]+='.';
	h+=2;
	cin>>n;
	r(i,n)cin>>com[i]>>DIR[i];
	r(i,h)r(j,w){
		if(s[i][j]=='S') y=i,x=j,s[i][j]='.';
		if(s[i][j]=='G') gy=i,gx=j;
	}
}

int s_to_i(string z){
	int sum=0;
	r(i,z.size()){
		sum=sum*10+z[i]-'0';
	}
	return sum;
}
accuracy: 1
time_ms: 250
memory_kb: 3240
final_rank: 3

code_snippet: #include <bits/stdc++.h>
#define r(i,n) for(int i=0;i<n;i++)
#define int long long
using namespace std;
typedef pair<int,int>P;
#define F first
#define S second

void INPUT();
int s_to_i(string z);

string s[55],com[1000],DIR[1000];
int x,y,gx,gy,n,h,w,ppp=1;

void GO(int Y,int X){
	if(s[y-1][x]=='3')s[y-1][x]='2';
	else if(s[y-1][x]=='2')s[y-1][x]='1';
	else if(s[y-1][x]=='1')s[y-1][x]='.';
	y = Y;
	x = X;
}

void Moveto(int t){
	if(s[y][t]!='.'||x==t||y==h-1)return;

	int off=(x<t?1:-1);
	int nx=x;

	if(y==1){
		GO(y,t);
		return;
	}

	int f=0;

	while(0<=nx&&nx<w&&nx!=t){
		if(s[y-1][nx+off]=='.')return;
		nx+=off;
	}

	GO(y,nx);
	return;
}

void Climb(string z){
	int ty=1;
	int tx=(z=="LEFT"?-1:1);
	if(y>=h-2)return;
	if( y+ty<0 || h<=y+ty || x+tx<0 || w<=x+tx )return;
	if( s[y][x+tx] == '.' )return;
	if( s[y+1][x+tx] == '.' && s[y+1][x] == '.' ){
		GO(y+ty,x+tx);
	}
	return;
}

void Getdown(string z){
	int ty=-1;
	int tx=(z=="LEFT"?-1:1);
	if( y+ty<0 || h<=y+ty || x+tx<0 || w<=x+tx )return;
	if( s[y][x+tx] == '.' && s[y-1][x+tx] == '.' ){
		GO(y+ty,x+tx);
	}
	return;
}

void Pull(string z){
	int tx=(z=="LEFT"?1:-1);
	if( x+tx<0 || w<=x+tx )return;
	if( x-tx<0 || w<=x-tx )return;
	if( s[y][x+tx] == 'C' )return;
	if( s[y][x+tx] == '.' )return;
	if( s[y][x-tx] != '.' )return;
	s[y][x]=s[y][x+tx];
	s[y][x+tx]='.';
	GO(y,x-tx);
	return;
}

void Push(string z){
	int tx=(z=="LEFT"?-1:1);
	if( x+tx<0 || w<=x+tx )return;
	int nx=x+tx;
	while(0<=nx&&nx<w&&s[y][nx]!='.'){
		if(s[y][nx]=='C')return;
		nx+=tx;
	}
	//r(i,h)cout<<s[h-1-i]<<endl;
	nx-=tx;
	for(int i=nx;i!=x;i-=tx){
		int p=i;
		while(1){
			if(p+tx<0 || w<=p+tx){
				s[y][p]='.';
				break;
			}
			if(s[y][p+tx]!='.')break;
			s[y][p+tx]=s[y][p];
			s[y][p]='.';
			if(!((s[y][p+tx]=='I'&&s[y-1][p+tx]!='.')||(s[y-1][p+tx]=='I')))break;
			p+=tx;
		}
	}
	//r(i,h)cout<<s[h-1-i]<<endl;
}

int RAKKA(){
//if(ppp==1920){s[y][x]='S';r(i,h)cout<<s[h-1-i]<<endl;s[y][x]='.';}
//cout<<y<<' '<<x<<endl;
	L:;
	r(i,h-1)r(j,w){
	//	cout<<i<<' '<<j<<endl;
		if(s[i][j]=='B'){
	//		cout<<i<<' '<<j<<endl;
			if(i+1==y&&j==x)return 2;
			if(ppp>=1900&&s[i+1][j]=='G')continue;
			s[i+1][j]='.';
		}
	}
	int T=0;
	while(s[y-1][x]=='.')y--,T++;
	if(T)goto L;
	int XXX=0;
	//s[y][x]='S';r(i,h)cout<<s[h-1-i]<<endl;s[y][x]='.';
	r(i,h-1)r(j,w){
	//	cout<<i<<' '<<j<<endl;
		if(s[i][j]=='G'){
			if(i!=gy||j!=gx)return 4;
			if(i+1==y&&j==x)return 1;
			XXX++;
		}
	//  cout<<i<<' '<<j<<endl;
	}
	if(!XXX)return 4;
	//cout<<y<<' '<<x<<endl;
	LL:;
	for(int i=2;i<h;i++){
		for(int j=0;j<w;j++){
			if(s[i][j]=='.')continue;
			//if(s[i][j]=='C')continue;
			int count=0;
			while(1){
				int sum=0;
				r(k,3){
					if(j+k-1<0||w<=j+k-1)continue;
					if(s[i-1][j+k-1]!='.')sum++;
				}
				if(sum)break;
				count++;
				T++;
				s[i-1][j]=s[i][j];
				s[i][j]='.';
				i--;
				//break;
				//cout<<i<<j<<endl;
			}
			//r(i,h)cout<<s[h-1-i]<<endl;
			if(s[y][x]!='.'){
			//	cout<<s[y][x]<<endl;
				return 3;
			}
			//r(i,h)cout<<s[h-1-i]<<endl;
			if(count) goto LL;
		}
	};
	if(T)goto L;
	//cout<<y<<x<<endl;
	return 0;
}


signed main(){
	while( 1 ){

		INPUT();
		if(ppp==1920){
			//s[y][x]='S';r(i,h)cout<<s[h-1-i]<<endl;s[y][x]='.';
			//r(i,n)cout<<com[i]<<' '<<DIR[i]<<endl;
		}
		//if(ppp==60)continue;
		r(i,n){
			int f=0;

			if(s[y-1][x]=='G'){
				cout<<"Game Over : Cleared"<<endl;
				break;
			}
			if(s[y-1][x]=='B'){
				cout<<"Game Over : Death by Hole"<<endl;
				break;
			}

			//cout<<i<<endl;

			if( com[i] == "MOVETO"  )  Moveto(s_to_i(DIR[i])-1);
			if( com[i] == "CLIMB"   )  Climb(DIR[i]);
			if( com[i] == "GETDOWN" )  Getdown(DIR[i]);
			if( com[i] == "PUSH"    )  Push(DIR[i]);
			if( com[i] == "PULL"    )  Pull(DIR[i]);

			//cout<<i<<endl;

			f = RAKKA();
			if(f==1){
				cout<<"Game Over : Cleared"<<endl;
				break;
			}
			if(f==2){
				cout<<"Game Over : Death by Hole"<<endl;
				break;
			}
			if(f==3){
				cout<<"Game Over : Death by Block"<<endl;
				break;
			}
			//cout<<i<<endl;
			if(f==4){
				cout<<"Game Over : Death by Walking Goal"<<endl;
				//return 0;
				break;
			}
			//cout<<i<<endl;

			if(i==n-1){
				cout<<"Game Over : Gave Up"<<endl;
				break;
			}
		}
		ppp++;
	}
}

void INPUT(){
	cin>>h>>w;
	if(h==0)exit(0);
	r(i,52)s[i]="";
	r(i,h)cin>>s[h-i];
	r(i,w)s[0]+='#';
	r(i,w)s[h+1]+='.';
	h+=2;
	cin>>n;
	r(i,n)cin>>com[i]>>DIR[i];
	r(i,h)r(j,w){
		if(s[i][j]=='S') y=i,x=j,s[i][j]='.';
		if(s[i][j]=='G') gy=i,gx=j;
	}
}

int s_to_i(string z){
	int sum=0;
	r(i,z.size()){
		sum=sum*10+z[i]-'0';
	}
	return sum;
}
accuracy: 1
time_ms: 250
memory_kb: 3252
final_rank: 4

code_snippet: #include <bits/stdc++.h>
#define r(i,n) for(int i=0;i<n;i++)
#define int long long
using namespace std;
typedef pair<int,int>P;
#define F first
#define S second

void INPUT();
int s_to_i(string z);

string s[55],com[1000],DIR[1000];
int x,y,gx,gy,n,h,w;

void GO(int Y,int X){
	if(s[y-1][x]=='3')s[y-1][x]='2';
	else if(s[y-1][x]=='2')s[y-1][x]='1';
	else if(s[y-1][x]=='1')s[y-1][x]='.';
	y = Y;
	x = X;
}

void Moveto(int t){
	if(s[y][t]!='.'||x==t||y==h-1)return;

	int off=(x<t?1:-1);
	int nx=x;

	if(y==1){
		GO(y,t);
		return;
	}

	int f=0;

	while(0<=nx&&nx<w&&nx!=t){
		if(s[y-1][nx+off]=='.')return;
		nx+=off;
	}

	GO(y,nx);
	return;
}

void Climb(string z){
	int ty=1;
	int tx=(z=="LEFT"?-1:1);
	if(y>=h-2)return;
	if( y+ty<0 || h<=y+ty || x+tx<0 || w<=x+tx )return;
	if( s[y][x+tx] == '.' )return;
	if( s[y+1][x+tx] == '.' && s[y+1][x] == '.' ){
		GO(y+ty,x+tx);
	}
	return;
}

void Getdown(string z){
	int ty=-1;
	int tx=(z=="LEFT"?-1:1);
	if( y+ty<0 || h<=y+ty || x+tx<0 || w<=x+tx )return;
	if( s[y][x+tx] == '.' && s[y-1][x+tx] == '.' ){
		GO(y+ty,x+tx);
	}
	return;
}

void Pull(string z){
	int tx=(z=="LEFT"?1:-1);
	if( x+tx<0 || w<=x+tx )return;
	if( x-tx<0 || w<=x-tx )return;
	if( s[y][x+tx] == 'C' )return;
	if( s[y][x+tx] == '.' )return;
	if( s[y][x-tx] != '.' )return;
	s[y][x]=s[y][x+tx];
	s[y][x+tx]='.';
	GO(y,x-tx);
	return;
}

void Push(string z){
	int tx=(z=="LEFT"?-1:1);
	if( x+tx<0 || w<=x+tx )return;
	int nx=x+tx;
	while(0<=nx&&nx<w&&s[y][nx]!='.'){
		if(s[y][nx]=='C')return;
		nx+=tx;
	}
	//r(i,h)cout<<s[h-1-i]<<endl;
	nx-=tx;
	for(int i=nx;i!=x;i-=tx){
		int p=i;
		while(1){
			if(p+tx<0 || w<=p+tx){
				s[y][p]='.';
				break;
			}
			if(s[y][p+tx]!='.')break;
			s[y][p+tx]=s[y][p];
			s[y][p]='.';
			if(!((s[y][p+tx]=='I'&&s[y-1][p+tx]!='.')||(s[y-1][p+tx]=='I')))break;
			p+=tx;
		}
	}
	//r(i,h)cout<<s[h-1-i]<<endl;
}
int ppp=1;
int RAKKA(){
//if(ppp==56){s[y][x]='S';r(i,h)cout<<s[h-1-i]<<endl;s[y][x]='.';}
//cout<<y<<' '<<x<<endl;
	L:;
	r(i,h-1)r(j,w){
	//	cout<<i<<' '<<j<<endl;
		if(s[i][j]=='B'){
	//		cout<<i<<' '<<j<<endl;
			if(i+1==y&&j==x)return 2;
			s[i+1][j]='.';
		}
	}
	int T=0;
	while(s[y-1][x]=='.')y--,T++;
	if(T)goto L;
	int XXX=0;
	//s[y][x]='S';r(i,h)cout<<s[h-1-i]<<endl;s[y][x]='.';
	r(i,h-1)r(j,w){
	//	cout<<i<<' '<<j<<endl;
		if(s[i][j]=='G'){
			if(i!=gy||j!=gx)return 4;
			if(i+1==y&&j==x)return 1;
			XXX++;
		}
	//  cout<<i<<' '<<j<<endl;
	}
	if(!XXX)return 4;
	//cout<<y<<' '<<x<<endl;
	LL:;
	for(int i=2;i<h;i++){
		for(int j=0;j<w;j++){
			if(s[i][j]=='.')continue;
			//if(s[i][j]=='C')continue;
			int count=0;
			while(1){
				int sum=0;
				r(k,3){
					if(j+k-1<0||w<=j+k-1)continue;
					if(s[i-1][j+k-1]!='.')sum++;
				}
				if(sum)break;
				count++;
				T++;
				s[i-1][j]=s[i][j];
				s[i][j]='.';
				i--;
				//break;
				//cout<<i<<j<<endl;
			}
			//r(i,h)cout<<s[h-1-i]<<endl;
			if(s[y][x]!='.'){
			//	cout<<s[y][x]<<endl;
				return 3;
			}
			//r(i,h)cout<<s[h-1-i]<<endl;
			if(count) goto LL;
		}
	};
	if(T)goto L;
	//cout<<y<<x<<endl;
	return 0;
}


signed main(){
	while( 1 ){

		INPUT();
		if(ppp==56){
			//s[y][x]='S';r(i,h)cout<<s[h-1-i]<<endl;s[y][x]='.';
			//r(i,n)cout<<com[i]<<' '<<DIR[i]<<endl;
		}
		//if(ppp==60)continue;
		r(i,n){
			int f=0;

			if(s[y-1][x]=='G'){
				cout<<"Game Over : Cleared"<<endl;
				break;
			}
			if(s[y-1][x]=='B'){
				cout<<"Game Over : Death by Hole"<<endl;
				break;
			}

			//cout<<i<<endl;

			if( com[i] == "MOVETO"  )  Moveto(s_to_i(DIR[i])-1);
			if( com[i] == "CLIMB"   )  Climb(DIR[i]);
			if( com[i] == "GETDOWN" )  Getdown(DIR[i]);
			if( com[i] == "PUSH"    )  Push(DIR[i]);
			if( com[i] == "PULL"    )  Pull(DIR[i]);

			//cout<<i<<endl;

			f = RAKKA();
			if(f==1){
				cout<<"Game Over : Cleared"<<endl;
				break;
			}
			if(f==2){
				cout<<"Game Over : Death by Hole"<<endl;
				break;
			}
			if(f==3){
				cout<<"Game Over : Death by Block"<<endl;
				break;
			}
			//cout<<i<<endl;
			if(f==4){
				cout<<"Game Over : Death by Walking Goal"<<endl;
				//return 0;
				break;
			}
			//cout<<i<<endl;

			if(i==n-1){
				cout<<"Game Over : Gave Up"<<endl;
				break;
			}
		}
		ppp++;
	}
}

void INPUT(){
	cin>>h>>w;
	if(h==0)exit(0);
	r(i,52)s[i]="";
	r(i,h)cin>>s[h-i];
	r(i,w)s[0]+='#';
	r(i,w)s[h+1]+='.';
	h+=2;
	cin>>n;
	r(i,n)cin>>com[i]>>DIR[i];
	r(i,h)r(j,w){
		if(s[i][j]=='S') y=i,x=j,s[i][j]='.';
		if(s[i][j]=='G') gy=i,gx=j;
	}
}

int s_to_i(string z){
	int sum=0;
	r(i,z.size()){
		sum=sum*10+z[i]-'0';
	}
	return sum;
}
accuracy: 0.75
time_ms: 250
memory_kb: 3276
final_rank: 15

code_snippet: #include <bits/stdc++.h>
#define r(i,n) for(int i=0;i<n;i++)
#define int long long
using namespace std;
typedef pair<int,int>P;
#define F first
#define S second

void INPUT();
int s_to_i(string z);

string s[55],com[1000],DIR[1000];
int x,y,gx,gy,n,h,w;

void GO(int Y,int X){
	if(s[y-1][x]=='3')s[y-1][x]='2';
	else if(s[y-1][x]=='2')s[y-1][x]='1';
	else if(s[y-1][x]=='1')s[y-1][x]='.';
	y = Y;
	x = X;
}

void Moveto(int t){
	if(s[y][t]!='.'||x==t)return;

	int off=(x<t?1:-1);
	int nx=x;

	if(y==1){
		GO(y,t);
		return;
	}

	int f=0;

	while(0<=nx&&nx<w&&nx!=t){
		if(s[y-1][nx+off]=='.')return;
		nx+=off;
	}

	GO(y,nx);
	return;
}

void Climb(string z){
	int ty=1;
	int tx=(z=="LEFT"?-1:1);
	if( y+ty<0 || h<=y+ty || x+tx<0 || w<=x+tx )return;
	if( s[y][x+tx] == '.' )return;
	if( s[y+1][x+tx] == '.' && s[y+1][x] == '.' ){
		GO(y+ty,x+tx);
	}
	return;
}

void Getdown(string z){
	int ty=-1;
	int tx=(z=="LEFT"?-1:1);
	if( y+ty<0 || h<=y+ty || x+tx<0 || w<=x+tx )return;
	if( s[y][x+tx] == '.' && s[y-1][x+tx] == '.' ){
		GO(y+ty,x+tx);
	}
	return;
}

void Pull(string z){
	int tx=(z=="LEFT"?1:-1);
	if( x+tx<0 || w<=x+tx )return;
	if( x-tx<0 || w<=x-tx )return;
	if( s[y][x+tx] == 'C' )return;
	if( s[y][x+tx] == '.' )return;
	if( s[y][x-tx] != '.' )return;
	s[y][x]=s[y][x+tx];
	s[y][x+tx]='.';
	GO(y,x-tx);
	return;
}

void Push(string z){
	int tx=(z=="LEFT"?-1:1);
	if( x+tx<0 || w<=x+tx )return;
	int nx=x+tx;
	while(0<=nx&&nx<w&&s[y][nx]!='.'){
		if(s[y][nx]=='C')return;
		nx+=tx;
	}
	//r(i,h)cout<<s[h-1-i]<<endl;
	nx-=tx;
	for(int i=nx;i!=x;i-=tx){
		int p=i;
		while(1){
			if(p+tx<0 || w<=p+tx){
				s[y][p]='.';
				break;
			}
			if(s[y][p+tx]!='.')break;
			s[y][p+tx]=s[y][p];
			s[y][p]='.';
			if(!((s[y][p+tx]=='I'&&s[y-1][p+tx]!='.')||(s[y-1][p+tx]=='I')))break;
			p+=tx;
		}
	}
	//r(i,h)cout<<s[h-1-i]<<endl;
}

int RAKKA(){
//s[y][x]='S';r(i,h)cout<<s[h-1-i]<<endl;s[y][x]='.';
//cout<<y<<' '<<x<<endl;
	L:;
	r(i,h-1)r(j,w){
	//	cout<<i<<' '<<j<<endl;
		if(s[i][j]=='B'){
	//		cout<<i<<' '<<j<<endl;
			if(i+1==y&&j==x)return 2;
			s[i+1][j]='.';
		}
	}
	int T=0;
	while(s[y-1][x]=='.')y--,T++;
	if(T)goto L;
	int XXX=0;
	//s[y][x]='S';r(i,h)cout<<s[h-1-i]<<endl;s[y][x]='.';
	r(i,h-1)r(j,w){
	//	cout<<i<<' '<<j<<endl;
		if(s[i][j]=='G'){
			if(i!=gy||j!=gx)return 4;
			if(i+1==y&&j==x)return 1;
			XXX++;
		}
	//  cout<<i<<' '<<j<<endl;
	}
	if(!XXX)return 4;
	//cout<<y<<' '<<x<<endl;
	LL:;
	for(int i=2;i<h;i++){
		for(int j=0;j<w;j++){
			if(s[i][j]=='.')continue;
			//if(s[i][j]=='C')continue;
			int count=0;
			while(1){
				int sum=0;
				r(k,3){
					if(j+k-1<0||w<=j+k-1)continue;
					if(s[i-1][j+k-1]!='.')sum++;
				}
				if(sum)break;
				count++;
				T++;
				s[i-1][j]=s[i][j];
				s[i][j]='.';
				i--;
				//break;
				//cout<<i<<j<<endl;
			}
			//r(i,h)cout<<s[h-1-i]<<endl;
			if(s[y][x]!='.'){
			//	cout<<s[y][x]<<endl;
				return 3;
			}
			//r(i,h)cout<<s[h-1-i]<<endl;
			if(count) goto LL;
		}
	};
	if(T)goto L;
	//cout<<y<<x<<endl;
	return 0;
}


signed main(){
	while( 1 ){
		INPUT();
		r(i,n){
			int f=0;

			if(s[y-1][x]=='G'){
				cout<<"Game Over : Cleared"<<endl;
				break;
			}
			if(s[y-1][x]=='B'){
				cout<<"Game Over : Death by Hole"<<endl;
				break;
			}

			//cout<<i<<endl;

			if( com[i] == "MOVETO"  )  Moveto(s_to_i(DIR[i])-1);
			if( com[i] == "CLIMB"   )  Climb(DIR[i]);
			if( com[i] == "GETDOWN" )  Getdown(DIR[i]);
			if( com[i] == "PUSH"    )  Push(DIR[i]);
			if( com[i] == "PULL"    )  Pull(DIR[i]);

			//cout<<i<<endl;

			f = RAKKA();
			if(f==1){
				cout<<"Game Over : Cleared"<<endl;
				break;
			}
			if(f==2){
				cout<<"Game Over : Death by Hole"<<endl;
				break;
			}
			if(f==3){
				cout<<"Game Over : Death by Block"<<endl;
				break;
			}
			//cout<<i<<endl;
			if(f==4){
				cout<<"Game Over : Death by Walking Goal"<<endl;
				//return 0;
				break;
			}
			//cout<<i<<endl;

			if(i==n-1){
				cout<<"Game Over : Gave Up"<<endl;
				break;
			}
		}
	}
}

void INPUT(){
	cin>>h>>w;
	if(h==0)exit(0);
	r(i,52)s[i]="";
	r(i,h)cin>>s[h-i];
	r(i,w)s[0]+='#';
	r(i,w)s[h+1]+='.';
	h+=2;
	cin>>n;
	r(i,n)cin>>com[i]>>DIR[i];
	r(i,h)r(j,w){
		if(s[i][j]=='S') y=i,x=j,s[i][j]='.';
		if(s[i][j]=='G') gy=i,gx=j;
	}
}

int s_to_i(string z){
	int sum=0;
	r(i,z.size()){
		sum=sum*10+z[i]-'0';
	}
	return sum;
}
accuracy: 0.75
time_ms: 250
memory_kb: 3276
final_rank: 15

code_snippet: #include <bits/stdc++.h>
#define r(i,n) for(int i=0;i<n;i++)
#define int long long
using namespace std;
typedef pair<int,int>P;
#define F first
#define S second

void INPUT();
int s_to_i(string z);

string s[55],com[1000],DIR[1000];
int x,y,gx,gy,n,h,w;

void GO(int Y,int X){
	if(s[y-1][x]=='3')s[y-1][x]='2';
	else if(s[y-1][x]=='2')s[y-1][x]='1';
	else if(s[y-1][x]=='1')s[y-1][x]='.';
	y = Y;
	x = X;
}

void Moveto(int t){
	if(s[y][t]!='.'||x==t)return;

	int off=(x<t?1:-1);
	int nx=x;

	if(y==1){
		GO(y,t);
		return;
	}

	int f=0;

	while(0<=nx&&nx<w&&nx!=t){
		if(s[y-1][nx+off]=='.')return;
		nx+=off;
	}

	GO(y,nx);
	return;
}

void Climb(string z){
	int ty=1;
	int tx=(z=="LEFT"?-1:1);
	if( y+ty<0 || h<=y+ty || x+tx<0 || w<=x+tx )return;
	if( s[y][x+tx] == '.' )return;
	if( s[y+1][x+tx] == '.' && s[y+1][x] == '.' ){
		GO(y+ty,x+tx);
	}
	return;
}

void Getdown(string z){
	int ty=-1;
	int tx=(z=="LEFT"?-1:1);
	if( y+ty<0 || h<=y+ty || x+tx<0 || w<=x+tx )return;
	if( s[y][x+tx] == '.' && s[y-1][x+tx] == '.' ){
		GO(y+ty,x+tx);
	}
	return;
}

void Pull(string z){
	int tx=(z=="LEFT"?1:-1);
	if( x+tx<0 || w<=x+tx )return;
	if( x-tx<0 || w<=x-tx )return;
	if( s[y][x+tx] == 'C' )return;
	if( s[y][x+tx] == '.' )return;
	if( s[y][x-tx] != '.' )return;
	s[y][x]=s[y][x+tx];
	s[y][x+tx]='.';
	GO(y,x-tx);
	return;
}

void Push(string z){
	int tx=(z=="LEFT"?-1:1);
	if( x+tx<0 || w<=x+tx )return;
	int nx=x+tx;
	while(0<=nx&&nx<w&&s[y][nx]!='.'){
		if(s[y][nx]=='C')return;
		nx+=tx;
	}
	//r(i,h)cout<<s[h-1-i]<<endl;
	nx-=tx;
	for(int i=nx;i!=x;i-=tx){
		int p=i;
		while(1){
			if(p+tx<0 || w<=p+tx){
				s[y][p]='.';
				break;
			}
			if(s[y][p+tx]!='.')break;
			s[y][p+tx]=s[y][p];
			s[y][p]='.';
			if(!((s[y][p+tx]=='I'&&s[y-1][p+tx]!='.')||(s[y-1][p+tx]=='I')))break;
			p+=tx;
		}
	}
	//r(i,h)cout<<s[h-1-i]<<endl;
}

int RAKKA(){
//s[y][x]='S';r(i,h)cout<<s[h-1-i]<<endl;s[y][x]='.';
//cout<<y<<' '<<x<<endl;
	L:;
	r(i,h-1)r(j,w){
	//	cout<<i<<' '<<j<<endl;
		if(s[i][j]=='B'){
	//		cout<<i<<' '<<j<<endl;
			if(i+1==y&&j==x)return 2;
			s[i+1][j]='.';
		}
	}
	int T=0;
	while(s[y-1][x]=='.')y--,T++;
	if(T)goto L;
	int XXX=0;
	r(i,h-1)r(j,w){
	//	cout<<i<<' '<<j<<endl;
		if(s[i][j]=='G'){
			if(i!=gy||j!=gx)return 4;
			if(i+1==y&&j==x)return 1;
			XXX++;
		}
	//  cout<<i<<' '<<j<<endl;
	}
	if(!XXX)return 4;
	//cout<<y<<' '<<x<<endl;
	LL:;
	for(int i=2;i<h;i++){
		for(int j=0;j<w;j++){
			if(s[i][j]=='.')continue;
			//if(s[i][j]=='C')continue;
			int count=0;
			while(1){
				int sum=0;
				r(k,3){
					if(j+k-1<0||w<=j+k-1)continue;
					if(s[i-1][j+k-1]!='.')sum++;
				}
				if(sum)break;
				count++;
				T++;
				s[i-1][j]=s[i][j];
				s[i][j]='.';
				i--;
				//break;
				//cout<<i<<j<<endl;
			}
			//r(i,h)cout<<s[h-1-i]<<endl;
			if(s[y][x]!='.'){
			//	cout<<s[y][x]<<endl;
				return 3;
			}
			//r(i,h)cout<<s[h-1-i]<<endl;
			if(count) goto LL;
		}
	};
	if(T)goto L;
	//cout<<y<<x<<endl;
	return 0;
}


signed main(){
	while( 1 ){
		INPUT();
		r(i,n){
			int f=0;

			if(s[y-1][x]=='G'){
				cout<<"Game Over : Cleared"<<endl;
				break;
			}
			if(s[y-1][x]=='B'){
				cout<<"Game Over : Death by Hole"<<endl;
				break;
			}

			//cout<<i<<endl;

			if( com[i] == "MOVETO"  )  Moveto(s_to_i(DIR[i])-1);
			if( com[i] == "CLIMB"   )  Climb(DIR[i]);
			if( com[i] == "GETDOWN" )  Getdown(DIR[i]);
			if( com[i] == "PUSH"    )  Push(DIR[i]);
			if( com[i] == "PULL"    )  Pull(DIR[i]);

			//cout<<i<<endl;

			f = RAKKA();
			if(f==1){
				cout<<"Game Over : Cleared"<<endl;
				break;
			}
			if(f==2){
				cout<<"Game Over : Death by Hole"<<endl;
				break;
			}
			if(f==3){
				cout<<"Game Over : Death by Block"<<endl;
				break;
			}
			//cout<<i<<endl;
			if(f==4){
				cout<<"Game Over : Death by Walking Goal"<<endl;
				//return 0;
				break;
			}
			//cout<<i<<endl;

			if(i==n-1){
				cout<<"Game Over : Gave Up"<<endl;
				break;
			}
		}
	}
}

void INPUT(){
	cin>>h>>w;
	if(h==0)exit(0);
	r(i,52)s[i]="";
	r(i,h)cin>>s[h-i];
	r(i,w)s[0]+='#';
	h++;
	cin>>n;
	r(i,n)cin>>com[i]>>DIR[i];
	r(i,h)r(j,w){
		if(s[i][j]=='S') y=i,x=j,s[i][j]='.';
		if(s[i][j]=='G') gy=i,gx=j;
	}
}

int s_to_i(string z){
	int sum=0;
	r(i,z.size()){
		sum=sum*10+z[i]-'0';
	}
	return sum;
}
accuracy: 0.75
time_ms: 240
memory_kb: 3172
final_rank: 14

code_snippet: #include <iostream>
#include <vector>
#include <string>

using namespace std;

#define MAX_N 50
#define MAX_M 50
int n, m, T;
string F[MAX_N+1];
int GOAL_Y, GOAL_X;

struct Command {
    string name;
    int index; // for MOVETO
    string dir; // otherwise
};

vector<Command> cmds;

void find_player(int &y, int &x) {
    for (int i = 1; i <= n; i++) 
        for (int j = 0; j < m; j++) 
            if (F[i][j] == 'S') {
                y = i, x = j;
                return;
            }
    // player is not in the tower
    y = -1, x = -1;
}

void find_goal(int &y, int &x) {
    for (int i = 1; i <= n; i++) 
        for (int j = 0; j < m; j++) 
            if (F[i][j] == 'G') {
                y = i, x = j;
                return;
            }
    y = -1, x = -1;
}

bool valid_range(int y, int x) {
    return 0 <= y && y <= n && 0 <= x && x < m;
}

bool is_block(int y, int x) {
    if (!valid_range(y, x)) return false;
    return (F[y][x] != '.' && F[y][x] != 'S');
}

bool can_move_to(int y, int x) {
    if (!valid_range(y, x)) return false;
    return F[y][x] == '.';
}

void process_moveto(int index) {
    int y, x; find_player(y, x);
    if (!valid_range(y, x)) return;
    if (!can_move_to(y, index)) return;
    for (int i = min(x, index); i <= max(x, index); i++) 
        if (!is_block(y-1, i)) 
            return;
    F[y][index] = F[y][x];
    F[y][x] = '.';
}

void process_climb(string dir) {
    int y, x; find_player(y, x);
    if (!valid_range(y, x)) return;
    if (is_block(y+1, x)) return;
    if (dir == "RIGHT") {
        if (!can_move_to(y+1, x+1)) return;
        if (!is_block(y, x+1)) return;
        F[y][x] = '.';
        F[y+1][x+1] = 'S';
    } else {
        if (!can_move_to(y+1, x-1)) return;
        if (!is_block(y, x-1)) return;
        F[y][x] = '.';
        F[y+1][x-1] = 'S';
    }
}

void process_getdown(string dir) {
    int y, x; find_player(y, x);
    if (!valid_range(y, x)) return;
    if (dir == "RIGHT") {
        if (!can_move_to(y-1, x+1) || !can_move_to(y, x+1)) return;
        F[y][x] = '.';
        F[y-1][x+1] = 'S';
    } else {
        if (!can_move_to(y-1, x-1) || !can_move_to(y, x-1)) return;
        F[y][x] = '.';
        F[y-1][x-1] = 'S';
    }
}

void move_block(int y, int x, int d) {
    if (F[y][x] == 'I') {
        if (can_move_to(y, x+d)) {
            F[y][x+d] = F[y][x];
            F[y][x] = '.';
            if (valid_range(y-1, x+d) && F[y-1][x+d] != '.') {
                move_block(y, x+d, d);
            }
        } else {
            if (!valid_range(y, x+d)) F[y][x] = '.';
        }
    } else {
        if (can_move_to(y, x+d)) {
            F[y][x+d] = F[y][x];
            F[y][x] = '.';
            if (valid_range(y-1, x+d) && F[y-1][x+d] == 'I') {
                move_block(y, x+d, d);
            }
        } else {
            if (!valid_range(y, x+d)) F[y][x] = '.';
        }
    }
}

void process_push(string dir) {
    int y, x; find_player(y, x);
    if (!valid_range(y, x)) return;
    int dx = (dir == "RIGHT" ? 1 : -1);
    int to;
    for (to = x+dx; is_block(y, to); to += dx) 
        if (F[y][to] == 'C') return;
    for (int i = to; i != x; i -= dx) 
        move_block(y, i, dx);
}

void process_pull(string dir) {
    int y, x; find_player(y, x);
    if (!valid_range(y, x)) return;
    int dx = (dir == "RIGHT" ? 1 : -1);
    if (is_block(y, x-dx) && F[y][x-dx] != 'C' && can_move_to(y, x+dx)) {
        F[y][x+dx] = 'S';
        F[y][x] = F[y][x-dx];
        F[y][x-dx] = '.';
    }
}

void process(Command cmd) {
    if (cmd.name == "MOVETO") {
        process_moveto(cmd.index);
    } else if (cmd.name == "CLIMB") {
        process_climb(cmd.dir);
    } else if (cmd.name == "GETDOWN") {
        process_getdown(cmd.dir);
    } else if (cmd.name == "PUSH") {
        process_push(cmd.dir);
    } else if (cmd.name == "PULL") {
        process_pull(cmd.dir);
    }
}

bool over(string &res) {
    int y, x; find_player(y, x);
    if (is_block(y-1, x) && F[y-1][x] == 'G') {
        res = "Cleared";
        return true;
    }
    if (is_block(y-1, x) && F[y-1][x] == 'B') {
        res = "Death by Hole";
        return true;
    }
    if (!valid_range(y, x)) { // C
        res = "Death by Block";
        return true;
    }
    int gy, gx; find_goal(gy, gx);
    if (GOAL_Y != gy || GOAL_X != gx) {
        res = "Death by Walking Goal";
        return true;
    }
    return false;
}

void debug() {
    for (int i = n; i >= 0; i--) {
        cout << F[i] << endl;
    }
    cout << endl;
}

void post_process(int prev_y, int prev_x) {
    // fragile block
    if (is_block(prev_y-1, prev_x) && isdigit(F[prev_y-1][prev_x]) && F[prev_y][prev_x] != 'S') {
        F[prev_y-1][prev_x]--;
        if (F[prev_y-1][prev_x] == '0') 
            F[prev_y-1][prev_x] = '.';
    }
    bool updated = true;
    while (updated) {
        updated = false;
        for (int i = n; i > 0; i--) 
            for (int j = 0; j < m; j++) 
                if (is_block(i, j) && is_block(i-1, j) && F[i-1][j] == 'B') {
                    F[i][j] = '.';
                    updated = true;
                }
        int y, x; find_player(y, x);
        while (can_move_to(y-1, x)) {
            F[y][x] = '.';
            F[y-1][x] = 'S';
            y--;
            updated = true;
        }
        for (int i = 1; i <= n; i++) {
            for (int j = 0; j < m; j++) {
                if (is_block(i, j) && !is_block(i-1, j-1) && !is_block(i-1, j) && !is_block(i-1, j+1)) {
                    F[i-1][j] = F[i][j];
                    F[i][j] = '.'; 
                    updated = true;
                }
            }
        }
    }
}

int main() {
    while (cin >> n >> m, n || m) {
        cin.ignore();
        F[0] = string(m, '#');
        for (int i = n; i > 0; i--) getline(cin, F[i]);
        cin >> T; cin.ignore();
        cmds.clear(); cmds.resize(T);

        for (int i = 0; i < T; i++) {
            Command cmd;
            cin >> cmd.name;
            if (cmd.name == "MOVETO") {
                cin >> cmd.index;
                cmd.index--;
            } else {
                cin >> cmd.dir;
            }
            cmds[i] = cmd;
        }

        find_goal(GOAL_Y, GOAL_X);

        string res = "";
        for (int i = 0; i < T; i++) {
            if (over(res)) break;
            int prev_y, prev_x; find_player(prev_y, prev_x);
            process(cmds[i]);
            //cout << cmds[i].name << endl;
            //debug();
            if (over(res)) break;
            post_process(prev_y, prev_x);
            //cout << "post process" << endl;
            //debug();
            if (over(res)) break;
        }
        if (res == "") res = "Gave Up";
        cout << "Game Over : " << res << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 750
memory_kb: 1320
final_rank: 2

code_snippet: #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);
    }
}
accuracy: 1
time_ms: 1110
memory_kb: 984
final_rank: 5

code_snippet: #include <iostream>
#include <string>
#include <vector>
#include <cstdlib>

using namespace std;

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

int main(){
	while(true){
		int n, m;
		cin >> n >> m;
		if(n == 0 && m == 0){ break; }
		vector<string> field(n);
		int x, y, gx = -1, gy = -1;
		for(int i = 0; i < n; ++i){
			cin >> field[i];
			size_t st = field[i].find('S');
			if(st != string::npos){
				field[i][st] = '.';
				x = st;
				y = i;
			}
			size_t goal = field[i].find('G');
			if(goal != string::npos){
				gx = goal;
				gy = i;
			}
		}
		int T, status = -1;
		cin >> T;
		if(y < n - 1 && field[y + 1][x] == 'G'){
			status = 0;
		}else if(y < n - 1 && field[y + 1][x] == 'B'){
			status = 1;
		}
		while(status < 0 && T--){
			string c1, c2;
			cin >> c1 >> c2;
			int px = x, py = y;
			if(c1 == "MOVETO"){
				int s = atoi(c2.c_str()) - 1;
				if(s < 0 || s >= m){ continue; }
				if(y == n - 1){
					if(field[y][s] == '.'){
						swap(field[y][x], field[y][s]);
						x = s;
					}else{
						continue;
					}
				}else{
					int delta = (s < x ? -1 : 1);
					bool accept = true;
					for(int i = x; i != s + delta; i += delta){
						if(field[y + 1][i] == '.'){
							accept = false;
							break;
						}
					}
					if(accept && field[y][s] == '.'){
						swap(field[y][x], field[y][s]);
						x = s;
					}else{
						continue;
					}
				}
			}else if(c1 == "PUSH"){
				int delta = (c2 == "LEFT" ? -1 : 1), last;
				bool accept = true;
				if(field[y][x + delta] == '.'){ continue; }
				for(last = x + delta; last >= 0 && last < m; last += delta){
					if(field[y][last] == 'C'){
						accept = false;
						break;
					}else if(field[y][last] == '.'){
						last -= delta;
						break;
					}
				}
				if(!accept){ continue; }
				for(int i = last; i != x; i -= delta){
					for(int j = i; j >= 0 && j < m; j += delta){
						int next = j + delta;
						if(next < 0 || next >= m){
							field[y][j] = '.';
							break;
						}
						if(field[y][next] != '.'){ break; }
						swap(field[y][next], field[y][j]);
						bool ice = (field[y][next] == 'I');
						if(y < n - 1 && field[y + 1][next] == 'I'){ ice = true; }
						if((y < n - 1 && field[y + 1][next] == '.') || !ice){
							break;
						}
					}
				}
			}else if(c1 == "PULL"){
				int delta = (c2 == "LEFT" ? 1 : -1);
				int next = x + delta, back = x - delta;
				if(next < 0 || next >= m || back < 0 || back >= m){ continue; }
				if(field[y][next] == '.' || field[y][next] == 'C'){ continue; }
				if(field[y][back] != '.'){ continue; }
				swap(field[y][x], field[y][back]);
				swap(field[y][next], field[y][x]);
				x = back;
			}else if(c1 == "GETDOWN"){
				int delta = (c2 == "LEFT" ? -1 : 1);
				if(y == n - 1){ continue; }
				int next = x + delta;
				if(field[y][next] != '.' || field[y + 1][next] != '.'){ continue; }
				swap(field[y + 1][next], field[y][x]);
				y = y + 1;
				x = next;
			}else if(c1 == "CLIMB"){
				int delta = (c2 == "LEFT" ? -1 : 1);
				if(y == 0){ continue; }
				int next = x + delta;
				if(field[y][next] == '.'){ continue; }
				if(field[y - 1][next] != '.' || field[y - 1][x] != '.'){ continue; }
				swap(field[y - 1][next], field[y][x]);
				y = y - 1;
				x = next;
			}
			if(y < n - 1){
				if(field[y + 1][x] == 'G'){
					status = 0;
					break;
				}else if(field[y + 1][x] == 'B'){
					status = 1;
					break;
				}
			}
			int cgx = -1, cgy = -1;
			for(int i = 0; i < n; ++i){
				size_t p = field[i].find('G');
				if(p != string::npos){
					cgx = p;
					cgy = i;
					break;
				}
			}
			if(cgx != gx || cgy != gy){
				status = 3;
				break;
			}
			if((y != py || x != px) && py < n - 1){
				if(isdigit(field[py + 1][px]) && --field[py + 1][px] == '0'){
					field[py + 1][px] = '.';
				}
			}
			while(true){
				bool modified = false;
				for(int i = 0; i < n - 1; ++i){
					for(int j = 0; j < m; ++j){
						if(field[i][j] == '.'){ continue; }
						if(field[i + 1][j] == 'B'){
							field[i][j] = '.';
							modified = true;
						}
					}
				}
				for(; y < n - 1; ++y){
					if(field[y + 1][x] == '.'){
						swap(field[y][x], field[y + 1][x]);
						modified = true;
					}else{
						break;
					}
				}
				for(int i = n - 2; i >= 0; --i){
					for(int j = 0; j < m; ++j){
						for(int k = i; k < n - 1; ++k){
							if(field[k][j] == '.'){ break; }
							if(j > 0 && field[k + 1][j - 1] != '.'){ break; }
							if(field[k + 1][j] != '.'){ break; }
							if(j < m - 1 && field[k + 1][j + 1] != '.'){ break; }
							swap(field[k + 1][j], field[k][j]);
							modified = true;
						}
					}
				}
				if(modified){ continue; }
				break;
			}
			cgx = -1, cgy = -1;
			for(int i = 0; i < n; ++i){
				size_t p = field[i].find('G');
				if(p != string::npos){
					cgx = p;
					cgy = i;
					break;
				}
			}
			if(cgx != gx || cgy != gy){ status = 3; }
			if(field[y][x] != '.'){ status = 2; }
			if(y < n - 1){
				if(field[y + 1][x] == 'B'){ status = 1; }
				if(field[y + 1][x] == 'G'){ status = 0; }
			}
		}
		if(T < 0){ status = 4; }
		while(T-- > 0){
			string c1, c2;
			cin >> c1 >> c2;
		}
		switch(status){
			case 0: cout << "Game Over : Cleared"; break;
			case 1: cout << "Game Over : Death by Hole"; break;
			case 2: cout << "Game Over : Death by Block"; break;
			case 3: cout << "Game Over : Death by Walking Goal"; break;
			case 4: cout << "Game Over : Gave Up"; break;
		}
		cout << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 300
memory_kb: 936
final_rank: 1

code_snippet: #include <iostream>
#include <string>
#include <vector>
#include <cstdlib>

using namespace std;

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

int main(){
	while(true){
		int n, m;
		cin >> n >> m;
		if(n == 0 && m == 0){ break; }
		vector<string> field(n);
		int x, y, gx = -1, gy = -1;
		for(int i = 0; i < n; ++i){
			cin >> field[i];
			size_t st = field[i].find('S');
			if(st != string::npos){
				field[i][st] = '.';
				x = st;
				y = i;
			}
			size_t goal = field[i].find('G');
			if(goal != string::npos){
				gx = goal;
				gy = i;
			}
		}
		int T, status = -1;
		cin >> T;
		if(y < n - 1 && field[y + 1][x] == 'G'){
			status = 0;
		}else if(y < n - 1 && field[y + 1][x] == 'B'){
			status = 1;
		}
		while(status < 0 && T--){
			string c1, c2;
			cin >> c1 >> c2;
			int px = x, py = y;
			if(c1 == "MOVETO"){
				int s = atoi(c2.c_str()) - 1;
				if(s < 0 || s >= m){ continue; }
				if(y == n - 1){
					if(field[y][s] == '.'){
						swap(field[y][x], field[y][s]);
						x = s;
					}else{
						continue;
					}
				}else if(s != x){
					int delta = (s < x ? -1 : 1);
					bool accept = true;
					for(int i = x + delta; i != s; i += delta){
						if(field[y + 1][i] == '.'){
							accept = false;
							break;
						}
					}
					if(accept && field[y][s] == '.'){
						swap(field[y][x], field[y][s]);
						x = s;
					}else{
						continue;
					}
				}
			}else if(c1 == "PUSH"){
				int delta = (c2 == "LEFT" ? -1 : 1), last;
				bool accept = true;
				if(field[y][x + delta] == '.'){ continue; }
				for(last = x + delta; last >= 0 && last < m; last += delta){
					if(field[y][last] == 'C'){
						accept = false;
						break;
					}else if(field[y][last] == '.'){
						last -= delta;
						break;
					}
				}
				if(!accept){ continue; }
				for(int i = last; i != x; i -= delta){
					for(int j = i; j >= 0 && j < m; j += delta){
						int next = j + delta;
						if(next < 0 || next >= m){
							field[y][j] = '.';
							break;
						}
						if(field[y][next] != '.'){ break; }
						swap(field[y][next], field[y][j]);
						bool ice = (field[y][next] == 'I');
						if(y < n - 1 && field[y + 1][next] == 'I'){ ice = true; }
						if((y < n - 1 && field[y + 1][next] == '.') || !ice){
							break;
						}
					}
				}
			}else if(c1 == "PULL"){
				int delta = (c2 == "LEFT" ? 1 : -1);
				int next = x + delta, back = x - delta;
				if(next < 0 || next >= m || back < 0 || back >= m){ continue; }
				if(field[y][next] == '.' || field[y][next] == 'C'){ continue; }
				if(field[y][back] != '.'){ continue; }
				swap(field[y][x], field[y][back]);
				swap(field[y][next], field[y][x]);
				x = back;
			}else if(c1 == "GETDOWN"){
				int delta = (c2 == "LEFT" ? -1 : 1);
				if(y == n - 1){ continue; }
				int next = x + delta;
				if(field[y][next] != '.' || field[y + 1][next] != '.'){ continue; }
				swap(field[y + 1][next], field[y][x]);
				y = y + 1;
				x = next;
			}else if(c1 == "CLIMB"){
				int delta = (c2 == "LEFT" ? -1 : 1);
				if(y == 0){ continue; }
				int next = x + delta;
				if(field[y][next] == '.' || field[y - 1][next] != '.'){ continue; }
				swap(field[y - 1][next], field[y][x]);
				y = y - 1;
				x = next;
			}
			if(y < n - 1){
				if(field[y + 1][x] == 'G'){
					status = 0;
					break;
				}else if(field[y + 1][x] == 'B'){
					status = 1;
					break;
				}
			}
			int cgx = -1, cgy = -1;
			for(int i = 0; i < n; ++i){
				size_t p = field[i].find('G');
				if(p != string::npos){
					cgx = p;
					cgy = i;
					break;
				}
			}
			if(cgx != gx || cgy != gy){
				status = 3;
				break;
			}
			if((y != py || x != px) && py < n - 1){
				if(isdigit(field[py + 1][px]) && --field[py + 1][px] == '0'){
					field[py + 1][px] = '.';
				}
			}
			while(true){
				bool modified = false;
				for(int i = 0; i < n - 1; ++i){
					for(int j = 0; j < m; ++j){
						if(field[i][j] == '.'){ continue; }
						if(field[i + 1][j] == 'B'){
							field[i][j] = '.';
							modified = true;
						}
					}
				}
				for(; y < n - 1; ++y){
					if(field[y + 1][x] == '.'){
						swap(field[y][x], field[y + 1][x]);
						modified = true;
					}else{
						break;
					}
				}
				for(int i = n - 2; i >= 0; --i){
					for(int j = 0; j < m; ++j){
						for(int k = i; k < n - 1; ++k){
							if(field[k][j] == '.'){ break; }
							if(j > 0 && field[k + 1][j - 1] != '.'){ break; }
							if(field[k + 1][j] != '.'){ break; }
							if(j < m - 1 && field[k + 1][j + 1] != '.'){ break; }
							swap(field[k + 1][j], field[k][j]);
							modified = true;
						}
					}
				}
				if(modified){ continue; }
				break;
			}
			cgx = -1, cgy = -1;
			for(int i = 0; i < n; ++i){
				size_t p = field[i].find('G');
				if(p != string::npos){
					cgx = p;
					cgy = i;
					break;
				}
			}
			if(cgx != gx || cgy != gy){ status = 3; }
			if(field[y][x] != '.'){ status = 2; }
			if(y < n - 1){
				if(field[y + 1][x] == 'B'){ status = 1; }
				if(field[y + 1][x] == 'G'){ status = 0; }
			}
		}
		if(T < 0){ status = 4; }
		while(T-- > 0){
			string c1, c2;
			cin >> c1 >> c2;
		}
		switch(status){
			case 0: cout << "Game Over : Cleared"; break;
			case 1: cout << "Game Over : Death by Hole"; break;
			case 2: cout << "Game Over : Death by Block"; break;
			case 3: cout << "Game Over : Death by Walking Goal"; break;
			case 4: cout << "Game Over : Gave Up"; break;
		}
		cout << endl;
	}
	return 0;
}
accuracy: 0.75
time_ms: 350
memory_kb: 936
final_rank: 7

code_snippet: #include <iostream>
#include <string>
#include <vector>
#include <cstdlib>

using namespace std;

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

int main(){
	while(true){
		int n, m;
		cin >> n >> m;
		if(n == 0 && m == 0){ break; }
		vector<string> field(n);
		int x, y, gx = -1, gy = -1;
		for(int i = 0; i < n; ++i){
			cin >> field[i];
			size_t st = field[i].find('S');
			if(st != string::npos){
				field[i][st] = '.';
				x = st;
				y = i;
			}
			size_t goal = field[i].find('G');
			if(goal != string::npos){
				gx = goal;
				gy = i;
			}
		}
		int T, status = -1;
		cin >> T;
		if(y < n - 1 && field[y + 1][x] == 'G'){
			status = 0;
		}else if(y < n - 1 && field[y + 1][x] == 'B'){
			status = 1;
		}
		while(status < 0 && T--){
			string c1, c2;
			cin >> c1 >> c2;
			int px = x, py = y;
			if(c1 == "MOVETO"){
				int s = atoi(c2.c_str()) - 1;
				if(s < 0 || s >= m){ continue; }
				if(y == n - 1){
					if(field[y][s] == '.'){
						swap(field[y][x], field[y][s]);
						x = s;
					}else{
						continue;
					}
				}else{
					int delta = (s < x ? -1 : 1);
					bool accept = true;
					for(int i = x; i != s + delta; i += delta){
						if(field[y + 1][i] == '.'){
							accept = false;
							break;
						}
					}
					if(accept && field[y][s] == '.'){
						swap(field[y][x], field[y][s]);
						x = s;
					}else{
						continue;
					}
				}
			}else if(c1 == "PUSH"){
				int delta = (c2 == "LEFT" ? -1 : 1), last;
				bool accept = true;
				if(field[y][x + delta] == '.'){ continue; }
				for(last = x + delta; last >= 0 && last < m; last += delta){
					if(field[y][last] == 'C'){
						accept = false;
						break;
					}else if(field[y][last] == '.'){
						last -= delta;
						break;
					}
				}
				if(!accept){ continue; }
				for(int i = last; i != x; i -= delta){
					for(int j = i; j >= 0 && j < m; j += delta){
						int next = j + delta;
						if(next < 0 || next >= m){
							field[y][j] = '.';
							break;
						}
						if(field[y][next] != '.'){ break; }
						swap(field[y][next], field[y][j]);
						bool ice = (field[y][next] == 'I');
						if(y < n - 1 && field[y + 1][next] == 'I'){ ice = true; }
						if((y < n - 1 && field[y + 1][next] == '.') || !ice){
							break;
						}
					}
				}
			}else if(c1 == "PULL"){
				int delta = (c2 == "LEFT" ? 1 : -1);
				int next = x + delta, back = x - delta;
				if(next < 0 || next >= m || back < 0 || back >= m){ continue; }
				if(field[y][next] == '.' || field[y][next] == 'C'){ continue; }
				if(field[y][back] != '.'){ continue; }
				swap(field[y][x], field[y][back]);
				swap(field[y][next], field[y][x]);
				x = back;
			}else if(c1 == "GETDOWN"){
				int delta = (c2 == "LEFT" ? -1 : 1);
				if(y == n - 1){ continue; }
				int next = x + delta;
				if(field[y][next] != '.' || field[y + 1][next] != '.'){ continue; }
				swap(field[y + 1][next], field[y][x]);
				y = y + 1;
				x = next;
			}else if(c1 == "CLIMB"){
				int delta = (c2 == "LEFT" ? -1 : 1);
				if(y == 0){ continue; }
				int next = x + delta;
				if(field[y][next] == '.' || field[y - 1][next] != '.'){ continue; }
				swap(field[y - 1][next], field[y][x]);
				y = y - 1;
				x = next;
			}
			if(y != py || x != px){
				if(y < n - 1){
					if(field[y + 1][x] == 'G'){
						status = 0;
						break;
					}else if(field[y + 1][x] == 'B'){
						status = 1;
						break;
					}	
				}
			}
			int cgx = -1, cgy = -1;
			for(int i = 0; i < n; ++i){
				size_t p = field[i].find('G');
				if(p != string::npos){
					cgx = p;
					cgy = i;
					break;
				}
			}
			if(cgx != gx || cgy != gy){
				status = 3;
				break;
			}
			if((y != py || x != px) && py < n - 1){
				if(isdigit(field[py + 1][px]) && --field[py + 1][px] == '0'){
					field[py + 1][px] = '.';
				}
			}
			while(true){
				bool modified = false;
				for(int i = 0; i < n - 1; ++i){
					for(int j = 0; j < m; ++j){
						if(field[i][j] == '.'){ continue; }
						if(field[i + 1][j] == 'B'){
							field[i][j] = '.';
							modified = true;
						}
					}
				}
				for(; y < n - 1; ++y){
					if(field[y + 1][x] == '.'){
						swap(field[y][x], field[y + 1][x]);
						modified = true;
					}else{
						break;
					}
				}
				for(int i = n - 2; i >= 0; --i){
					for(int j = 0; j < m; ++j){
						for(int k = i; k < n - 1; ++k){
							if(field[k][j] == '.'){ break; }
							if(j > 0 && field[k + 1][j - 1] != '.'){ break; }
							if(field[k + 1][j] != '.'){ break; }
							if(j < m - 1 && field[k + 1][j + 1] != '.'){ break; }
							swap(field[k + 1][j], field[k][j]);
							modified = true;
						}
					}
				}
				if(modified){ continue; }
				break;
			}
			cgx = -1, cgy = -1;
			for(int i = 0; i < n; ++i){
				size_t p = field[i].find('G');
				if(p != string::npos){
					cgx = p;
					cgy = i;
					break;
				}
			}
			if(cgx != gx || cgy != gy){ status = 3; }
			if(field[y][x] != '.'){ status = 2; }
			if(y < n - 1){
				if(field[y + 1][x] == 'B'){ status = 1; }
				if(field[y + 1][x] == 'G'){ status = 0; }
			}
		}
		if(T < 0){ status = 4; }
		while(T-- > 0){
			string c1, c2;
			cin >> c1 >> c2;
		}
		switch(status){
			case 0: cout << "Game Over : Cleared"; break;
			case 1: cout << "Game Over : Death by Hole"; break;
			case 2: cout << "Game Over : Death by Block"; break;
			case 3: cout << "Game Over : Death by Walking Goal"; break;
			case 4: cout << "Game Over : Gave Up"; break;
		}
		cout << endl;
	}
	return 0;
}
accuracy: 0.75
time_ms: 310
memory_kb: 936
final_rank: 6

code_snippet: #include <iostream>
#include <string>
#include <vector>
#include <cctype>
#include <sstream>
using namespace std;
 
int dx[] = {-1, 0, 1, 0};
int dy[] = {0, -1, 0, 1};
 
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] != '.') return false;
 
    mx += dx[dir];
    if(field[my][mx] != '.') 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;
	if(x == mx) return true;
 
    int tx = x + dx[dir];
    while(1) {
        if(tx == mx) break;
        if(!isBlock(field[y+1][tx])) return false;
         
        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);
    }
}
accuracy: 0.75
time_ms: 1010
memory_kb: 984
final_rank: 12

code_snippet: #include <iostream>
#include <string>
#include <vector>
#include <cctype>
#include <sstream>
using namespace std;
 
int dx[] = {-1, 0, 1, 0};
int dy[] = {0, -1, 0, 1};
 
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] != '.') return false;
 
    mx += dx[dir];
    if(field[my][mx] != '.') 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(tx == mx) break;
        if(!isBlock(field[y+1][tx])) return false;
         
        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);
    }
}
accuracy: 0.75
time_ms: 1040
memory_kb: 988
final_rank: 13

code_snippet: #include <iostream>
#include <string>
#include <vector>
#include <cctype>
#include <sstream>
using namespace std;

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

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] != '.') return false;

	mx += dx[dir];
	if(field[my][mx] != '.') 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(tx == mx) break;
		if(!isBlock(field[y+1][x])) return false;
		
		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 extinct()
{
	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 |= extinct();
		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);
	}
}
accuracy: 0.75
time_ms: 590
memory_kb: 984
final_rank: 10

code_snippet: #include <iostream>
#include <string>
#include <vector>
#include <cctype>
#include <sstream>
using namespace std;

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

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] != '.') return false;

	mx += dx[dir];
	if(field[my][mx] != '.') 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(tx == mx) break;
		if(!isBlock(field[y+1][x])) return false;
		
		tx += dx[dir];
	}

	return true;
}

bool cPull(int x, int y, int dir)
{
	int tx = x + dx[dir], ty = y + dy[dir];
	int bx = x - dx[dir], by = y - dy[dir];

	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) {
				if(field[ty+1][tx] != 'I') break;
			}
			else break;
		}

		if(ty != H-1) {
			if(field[ty+1][tx] == '.') break;
		}

		tx += dx[dir];
		
	}

	field[ty][tx] = tmp;
}

void Push(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(1) {
		if(x == tx) break;
		moveBlock(tx,ty,dir);

		tx -= dx[dir];
	}
}

bool cPush(int x, int y, int dir)
{
	if(!canPush(x,y,dir)) return false;

	Push(x,y,dir);

	return true;
}

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 extinct()
{
	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] = '.';
				return true;
			}
		}
	}

	return false;
}

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 |= extinct();
		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);
			cPush(x, y, d);
		}

		if(commands[i] == "PULL") {
			int d = (commands[i + 1] == "LEFT" ? 0 : 2);
			if(cPull(x, y, d)) {
				x += dx[d];
				y += dy[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);
	}
}

/*
10 2
B.
B#
B.
B.
B.
B.
B.
BS
B#
BG
1
PUSH LEFT
*/

/*
2 4
.IIS
G..#
1
PUSH LEFT
*/
accuracy: 0.75
time_ms: 600
memory_kb: 988
final_rank: 11

code_snippet: #include <iostream>
#include <string>
#include <vector>
#include <cctype>
using namespace std;

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

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] != '.') return false;

	mx += dx[dir];
	if(field[my][mx] != '.') 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(field[y][mx] != '.') return false;
	if(y == H-1) return true;

	int tx = x;
	while(1) {
		if(tx == mx) break;
		if(!isBlock(field[y+1][x])) return false;
		
		tx += dx[dir];
	}

	return true;
}

bool cPull(int x, int y, int dir)
{
	int tx = x + dx[dir], ty = y + dy[dir];
	int bx = x - dx[dir], by = y - dy[dir];

	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) {
				if(field[ty+1][tx] != 'I') break;
			}
			else break;
		}

		if(ty != H-1) {
			if(tx!=x && field[ty+1][tx] == '.') break;
		}

		tx += dx[dir];
		
	}

	field[ty][tx] = tmp;
}

void Push(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(1) {
		if(x == tx) break;
		moveBlock(tx,ty,dir);

		tx -= dx[dir];
	}
}

bool cPush(int x, int y, int dir)
{
	if(!canPush(x,y,dir)) return false;

	Push(x,y,dir);

	return true;
}

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 extinct()
{
	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] = '.';
				return true;
			}
		}
	}

	return false;
}

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-1; 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 |= extinct();
		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)
{
	int res = 0;
	for(int i = 0; i < a.size(); i++) {
		res *= 10;
		res += a[i] - '0';
	}

	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);
			cPush(x, y, d);
		}

		if(commands[i] == "PULL") {
			int d = (commands[i + 1] == "LEFT" ? 0 : 2);
			if(cPull(x, y, d)) {
				x += dx[d];
				y += dy[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);
	}
}
accuracy: 0.75
time_ms: 580
memory_kb: 976
final_rank: 8

code_snippet: #include <iostream>
#include <string>
#include <vector>
#include <cctype>
using namespace std;

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

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] != '.') return false;

	mx += dx[dir];
	if(field[my][mx] != '.') 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(field[y][mx] != '.') return false;
	if(y == H-1) return true;

	int tx = x;
	while(1) {
		if(!isBlock(field[y+1][x])) 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 + dy[dir];
	int bx = x - dx[dir], by = y - dy[dir];

	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) {
				if(field[ty+1][tx] != 'I') break;
			}
			else break;
		}

		if(ty != H-1) {
			if(tx!=x && field[ty+1][tx] == '.') break;
		}

		tx += dx[dir];
		
	}

	field[ty][tx] = tmp;
}

void Push(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(1) {
		if(x == tx) break;
		moveBlock(tx,ty,dir);

		tx -= dx[dir];
	}
}

bool cPush(int x, int y, int dir)
{
	if(!canPush(x,y,dir)) return false;

	Push(x,y,dir);

	return true;
}

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 extinct()
{
	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] = '.';
				return true;
			}
		}
	}

	return false;
}

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-1; 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 |= extinct();
		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)
{
	int res = 0;
	for(int i = 0; i < a.size(); i++) {
		res *= 10;
		res += a[i] - '0';
	}

	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);
			cPush(x, y, d);
		}

		if(commands[i] == "PULL") {
			int d = (commands[i + 1] == "LEFT" ? 0 : 2);
			if(cPull(x, y, d)) {
				x += dx[d];
				y += dy[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);
	}
}
accuracy: 0.75
time_ms: 580
memory_kb: 980
final_rank: 9