import java.lang.Math.*
import java.util.*

fun main(args:Array<String>?): Unit {
    val (h, w, d, n) = readLine()!!.trim().split(' ').map(String::toInt)
    val state = Array(h){readLine()!!.trim()}
    val detected = Array(h){IntArray(w){0}}
    val radius = readLine()!!.trim().split(' ').map(String::toInt)
    repeat(n){
        val (x, y, s) = readLine()!!.trim().split(' ').map(String::toInt)
        if (s == 0){
            detected.addSquare(x - radius[0], y - radius[0], radius[0])
        }else if (s in 1 until d){
            detected.addSquare(x - radius[s], y - radius[s], radius[s])
            detected.removeSquare(x - radius[s - 1], y - radius[s - 1], radius[s - 1])
        }else {
            detected[0][0]++
            detected.removeSquare(x - radius[s - 1], y - radius[s - 1], radius[s - 1])
        }
    }
    for (i in 1 until h) for (j in 0 until w){
        detected[i][j] += detected[i - 1][j]
    }
    for (i in 0 until h) for (j in 1 until w){
        detected[i][j] += detected[i][j - 1]
    }
    val suspects = (0 until h).map{y -> (0 until w).map{x -> detected[y][x] == n && state[y][x] != '#'}.toBooleanArray()}.toTypedArray()
    val canReach = Array(h){BooleanArray(w){false}}
    if (suspects.all{it.none { it }}){
        println("Broken")
    }else {
        val start = (0 until h).mapNotNull { y -> (0 until w).find{ x -> state[y][x] == 'D'}?.let{Pair(it, y)} }.first()
        val queue: Queue<Pair<Int, Int>> = LinkedList()
        queue.add(start)
        canReach[start.second][start.first] = true
        while(queue.isNotEmpty()){
            val (x, y) = queue.poll()
            if (x + 1 in 0 until w && state[y][x + 1] == '.' && !canReach[y][x + 1]) {
                canReach[y][x + 1] = true
                queue.add(Pair(x + 1, y))
            }
            if (x - 1 in 0 until w && state[y][x - 1] == '.' && !canReach[y][x - 1]){
                canReach[y][x - 1] = true
                queue.add(Pair(x - 1, y))
            }
            if (y + 1 in 0 until h && state[y + 1][x] == '.' && !canReach[y + 1][x]){
                canReach[y + 1][x] = true
                queue.add(Pair(x, y + 1))
            }

            if (y - 1 in 0 until h && state[y - 1][x] == '.' && !canReach[y - 1][x]){
                canReach[y - 1][x] = true
                queue.add(Pair(x, y - 1))
            }
        }
        val reachable = (0 until h).flatMap{y -> (0 until w).filter{x -> suspects[y][x]}.map{x -> canReach[y][x]}}
        println(
                if (reachable.all{it}) "Yes" else if (reachable.none{it}) "No" else "Unknown"
        )
    }
}
fun Array<IntArray>.addSquare(left: Int, top: Int, size: Int): Unit {
    this[max(top, 0)][max(left, 0)]++
    if (top + size * 2 + 1 in this.indices) this[top + size * 2 + 1][max(left, 0)]--
    if (left + size * 2 + 1 in this[0].indices) this[max(top, 0)][left + size * 2 + 1]--
    if (top + size * 2 + 1 in this.indices && left + size * 2 + 1 in this[0].indices) this[top + size * 2 + 1][left + size * 2 + 1]++
}
fun Array<IntArray>.removeSquare(left: Int, top: Int, size: Int): Unit {
    this[max(top, 0)][max(left, 0)]--
    if (top + size * 2 + 1 in this.indices) this[top + size * 2 + 1][max(left, 0)]++
    if (left + size * 2 + 1 in this[0].indices) this[max(top, 0)][left + size * 2 + 1]++
    if (top + size * 2 + 1 in this.indices && left + size * 2 + 1 in this[0].indices) this[top + size * 2 + 1][left + size * 2 + 1]--
}


Measured memory_bytes: 32712