#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


struct Info{
	Info(int arg_row,int arg_col){
		row = arg_row;
		col = arg_col;
	}
	int row,col;
};

int H,W;
int diff_row[4] = {-1,0,0,1},diff_col[4] = {0,-1,1,0};

bool rangeCheck(int row,int col){
	if(row >= 0 && row <= H-1 && col >= 0 && col <= W-1)return true;
	else{
		return false;
	}
}

int main(){

	int D,N;

	scanf("%d %d %d %d",&H,&W,&D,&N);

	bool can_visit[H][W];
	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++)can_visit[row][col] = false;
	}

	char base_map[H][W+1];
	int start_row,start_col;

	for(int row = 0; row < H; row++){
		scanf("%s",base_map[row]);
		for(int col = 0; col < W; col++){
			if(base_map[row][col] == 'D'){
				start_row = row;
				start_col = col;
				base_map[row][col] = '.';
			}
		}
	}

	queue<Info> Q;
	can_visit[start_row][start_col] = true;

	Q.push(Info(start_row,start_col));
	int adj_row,adj_col;

	while(!Q.empty()){

		for(int i = 0; i < 4; i++){
			adj_row = Q.front().row+diff_row[i];
			adj_col = Q.front().col+diff_col[i];

			if(rangeCheck(adj_row,adj_col) == false || base_map[adj_row][adj_col] == '#')continue;

			if(can_visit[adj_row][adj_col] == false){
				can_visit[adj_row][adj_col] = true;
				Q.push(Info(adj_row,adj_col));
			}
		}
		Q.pop();
	}

	int table[H][W];
	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++)table[row][col] = 0;
	}

	int R[D+1];
	for(int i = 1; i <= D; i++)scanf("%d",&R[i]);

	int x,y,S;
	for(int loop = 0; loop < N; loop++){
		scanf("%d %d %d",&x,&y,&S);
		if(S == 0){
			for(int row = max(0,y-R[1]); row <= min(H-1,y+R[1]); row++){
				for(int col = max(0,x-R[1]); col <= min(W-1,x+R[1]); col++){
					table[row][col]++;
				}
			}
		}else if(S == D){
			for(int row = 0; row < H; row++){
				for(int col = 0; col < W; col++){
					if(row >= y-R[D] && row <= y+R[D] && col >= x-R[D] && col <= x+R[D])continue;
					table[row][col]++;
				}
			}
		}else{

			for(int row = max(0,y-R[S+1]); row <= min(H-1,y+R[S+1]); row++){
				for(int col = max(0,x-R[S+1]); col <= min(W-1,x+R[S+1]); col++){
					if(row >= y-R[S] && row <= y+R[S] && col>= x-R[S] && col <= x+R[S])continue;
					table[row][col]++;
				}
			}
		}
	}

	int work[H][W];
	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++)work[row][col] = table[row][col];
	}

	int count = 0;

	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){
			if(work[row][col] == N){
				count++;
				work[row][col] = -1;

				Q.push(Info(row,col));

				while(!Q.empty()){

					for(int i = 0; i < 4; i++){
						adj_row = Q.front().row + diff_row[i];
						adj_col = Q.front().col + diff_col[i];

						if(rangeCheck(adj_row,adj_col) == false)continue;

						if(work[adj_row][adj_col] == N){
							work[adj_row][adj_col] = -1;
							Q.push(Info(adj_row,adj_col));
						}
					}

					Q.pop();
				}
			}
		}
	}

	if(count == 0 || count >= 2){
		printf("Broken\n");
		return 0;
	}

	int can_num = 0,not_num = 0;

	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){
			if(table[row][col] == N){
				if(can_visit[row][col]){
					can_num++;
				}else{
					if(base_map[row][col] != '#'){
						not_num++;
					}
				}
			}
		}
	}


	if(can_num > 0 && not_num == 0){
		printf("Yes\n");
	}else if(can_num == 0 && not_num > 0){
		printf("No\n");
	}else{
		printf("Unknown\n");
	}

	return 0;
}

Measured memory_bytes: 3216