#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <cctype>
using std::vector;

const int LIMIT_SIZE = 24;

struct State
{
	char	map[LIMIT_SIZE][LIMIT_SIZE];
};

#define ACTION_PUT		0
#define ACTION_STAR		1		
#define ACTION_BOMBER	2

struct PlayAction
{
	int		action;
	int		x, y;
};

class Replay
{
public:
	int				len;
	vector<PlayAction> 	list;
	
	void LoadReplay(const char* filename);
};

/////Variable Definitions
int			n, m;
int			star, bomber;
int			nop;
vector<int>	oplist;
State		init_map;

Replay		gameplay;
long long spj_a[12];

void ErrorAndExit(const char* msg, const char* details = NULL)
{
	fprintf(stderr, "[Error] %s\n", msg);
	if (details != NULL)
		fprintf(stderr, "	Info: %s\n", details);
	puts("0");
	exit ( 0 );
}

long long ReportScore(long long score)
{
	fprintf(stderr,"Correct! Your Score is %lld\n", score);
	long long ans=1;
	for(int i=2;i<=10;i++)
	{
		if(score>=spj_a[i]) ans=i;
	}
	return ans;
}

void LoadGame(const char* filename)
{
	FILE*	fin = fopen(filename, "r");
	if (fin == NULL)
		ErrorAndExit("Input File Do not Exist.");
		
	fscanf(fin, "%d%d", &n, &m);
	fscanf(fin, "%d%d", &star, &bomber);
	
	for (int i = 1; i <= n; i ++)
		fscanf(fin, "%s", init_map.map[i] + 1);
	fscanf(fin, "%d", &nop);
	oplist.clear();
	
	int x;
	for (int i = 0; i < nop; i ++)
	{
		fscanf(fin, "%d", &x);
		oplist.push_back(x);
	}
	
	fclose(fin);
}

void Replay::LoadReplay(const char* filename)
{
	len = 0;
	list.clear();
	
	FILE*	fin = fopen(filename, "r");
	char	buf[256];
	char  	cmd[256];
	char	msg[256];
	
	int		x, y;
	PlayAction	act;
	
	if (fin == NULL)
		ErrorAndExit("Output File Do Not Exist.");
	
	bool ended = 0;
	int	 line = 0;
	while (fgets(buf, 256, fin) > 0)
	{
		++ line;
		x = y = -1;
		sscanf(buf, "%s%d%d", cmd, &x, &y);
		sprintf(msg, "Wrong on line %d: %s", line, buf);
		
		if (strcmp(cmd, "END") == 0) 
		{
			ended = 1;
			break;
		}
		
		if (strcmp(cmd, "PUT") == 0)
		{
			act.action = ACTION_PUT;
		}
		else if (strcmp(cmd, "STAR") == 0)
		{
			act.action = ACTION_STAR;
		}
		else if (strcmp(cmd, "BOMBER") == 0)
		{	
			act.action = ACTION_BOMBER;
		}
		else {
			ErrorAndExit("Output Invalid!", msg);
		}
		
		if (x <= 0 || x > n || y <= 0 || y > m)
			ErrorAndExit("Output Invalid!", msg);
			
		act.x = x;
		act.y = y;
		list.push_back(act);
		len ++;
	}
	
	if (! ended)
	{
		ErrorAndExit("Output Invalid!", "Output do not end with instruction END");
	}
	
	fclose(fin);
}

const int SCORE[] = {
	0, 4, 20, 100, 500, 1500, 5000, 20000, 100000, 500000
};

long long 	total_score = 0;
State		curt;

int			qx	[LIMIT_SIZE * LIMIT_SIZE];
int			qy	[LIMIT_SIZE * LIMIT_SIZE];
int			head, tail;
bool		mark[LIMIT_SIZE][LIMIT_SIZE];

int			dx [] = {0, 0, 1, -1};
int			dy [] = {1, -1, 0, 0};

bool valid(int x, int y)
{
	return 1 <= x && x <= n && 1 <= y && y <= m;
}

bool CheckUpgrade(int x, int y)
{
	int	L = curt.map[x][y];
	if (L == '9') return 0;
	
	memset(mark, 0, sizeof(mark));
	mark[x][y] = 1;
	qx[0] = x; qy[0] = y; head = 0; tail = 1;
	
	while (head < tail)
	{
		x = qx[ head ];
		y = qy[ head ];
		head ++;
		for (int d = 0; d < 4; d ++)
			if (valid(x + dx[d], y + dy[d]) && curt.map[ x + dx[d] ][ y + dy[d] ] == L && ! mark[ x + dx[d] ][ y + dy[d] ])
			{
				mark[ x + dx[d] ][ y + dy[d] ] = 1;
				qx[tail] = x + dx[d];
				qy[tail] = y + dy[d];
				tail ++;
			}
	}
	
	return tail >= 3;
}

void DoUpgrade()
{
	for (int i = 1; i < tail; i ++)
		curt.map[ qx[i] ][ qy[i] ] = '.';
	curt.map[ qx[0] ][ qy[0] ] ++;
	
	total_score += SCORE[ curt.map[ qx[0] ][ qy[0] ] - '0' ];
}

void BuildOnPos(int x, int y)
{
	total_score += SCORE[ curt.map[x][y] - '0' ];
	while (CheckUpgrade(x, y))
		DoUpgrade();
}

void ShowMap()
{
	return;
	
	printf("======== Score=%lld [Star=%d, Bomber=%d]\n", total_score, star, bomber);
	for (int i = 1; i <= n; i ++)
		printf("%s\n", curt.map[i] + 1);
	printf("\n");
}

long long Simulate()
{
	total_score = 0;
	
	curt = init_map;
	char	msg	[256];
	
	int		opnow = 0;
	int		L;
	
	for (int p = 0; p < gameplay.len; p ++)
	{
		PlayAction act = gameplay.list[p];
		int x = act.x;
		int y = act.y;
		
		if (act.action == ACTION_BOMBER)
		{
			if (bomber <= 0)
			{
				sprintf(msg, "[Line %d] No bombers left", p + 1);
				ErrorAndExit("Output Invaild!", msg);
			}
			
			if (curt.map[x][y] == '.')
			{
				sprintf(msg, "[Line %d] Can't place bomber on (%d, %d). It's empty.", p + 1, x, y);
				ErrorAndExit("Output Invaild!", msg);
			}
			
			total_score -= SCORE[ curt.map[x][y] - '0' ] / 2;
			curt.map[x][y] = '.';
			bomber --;
		}
		else if (act.action == ACTION_PUT)
		{
			if (opnow >= nop)
			{
				sprintf(msg, "[Line %d] Too many PUT operations.", p + 1);
				ErrorAndExit("Output Invaild!", msg);
			}
			
			if (curt.map[x][y] != '.')
			{
				sprintf(msg, "[Line %d] Can't place L%d on (%d, %d). It's not empty.", p + 1, L, x, y);
				ErrorAndExit("Output Invaild!", msg);
			}
			
			curt.map[x][y] = oplist[ opnow ++ ] + '0';
			
			BuildOnPos(x, y);
			
		}
		else if (act.action == ACTION_STAR)
		{
			if (star <= 0)
			{
				sprintf(msg, "[Line %d] No stars left", p + 1);
				ErrorAndExit("Output Invaild!", msg);
			}
			
			if (curt.map[x][y] != '.')
			{
				sprintf(msg, "[Line %d] Can't place STAR on (%d, %d). It's not empty.", p + 1, x, y);
				ErrorAndExit("Output Invaild!", msg);
			}
			
			for (char c = '9'; c >= '1'; c --)
			{
				curt.map[x][y] = c;
				if (CheckUpgrade(x, y))
					break;
			}
			
			BuildOnPos(x, y);
				
			star --;
		}
		
		ShowMap();
	}
	
	return ReportScore(total_score);
}

int main(int argc, char* argv[])
{
	freopen("answer", "r", stdin);
	for(int i=10;i>=2;i--) scanf("%lld",&spj_a[i]);
	fclose(stdin);
	
	LoadGame("input");
	gameplay.LoadReplay("user_out");

	printf("%lld\n", Simulate()*10);
	return 0;
}
