object Main {

  def main(args: Array[String]): Unit = {
    val sc = new java.util.Scanner(System.in)

    val N, _A, _B, _C, _D = sc.nextInt()
    val A = _A - 1
    val B = _B - 1
    val C = _C - 1
    val D = _D - 1
    sc.nextLine()
    val S: Array[Char] = sc.nextLine().toCharArray

    // 1マス右か,2マス右にジャンプさせるしかなく
    // 1マス右は,岩が無い時しか選択できず.
    // 2マス右は,岩が1つしか無い時にしか選択できない.
    // 岩が2つある時には必ず右に行くことができない.

    // A < B かつ, 右に行く操作しか許されていないので,
    // 達成可能な時, 必ずBから先に動かすことになる.
    // そのあと, Aから探索する. つまり, AとBは独立して探索可能である.

    // A -> C. B -> Dへの移動を独立して探索する

    // しかし, D < C の可能性がある(先に到着したほうが岩と同様の扱いをされる)
    // なので, D < C の場合において, どこかで A が B を追い越す必要性があり,
    // 追い越せるかどうかは何も無いマスがA < x <= D + 1 のマスにおいて
    // ...のように3以上つ重なっている場合のみであり、追い越せる場合にはその後独立した問題に帰着する
    // 追い越せない場合には必ず満たす

    def solve(): Boolean = {
      def recursive(i: Int, target: Int): Boolean =
        if (i == target) true
        else if ((i + 1) < N && S(i + 1) == '.') // 枠内かつ何もなければ右に移動
          recursive(i+1,target)
        else if ((i + 2) < N && S(i + 2) == '.') // 枠内かつ何もなければ右に移動
          recursive(i+2,target)
        else false // 枠からはみ出る(ありえない) || 一マス右,二マス右に何も無い場合false

      def countContinuous(S: List[Char], count: Int): Boolean =
        if (count >= 3) true
        else if (S.nonEmpty) {
          if (S.head == '.') countContinuous(S.tail, count + 1)
          else countContinuous(S.tail, 0)
        } else false

      if (D < C) {
        if (countContinuous(S.slice(A, D + 2).toList, 0))
          recursive(A, C) && recursive(B, D)
        else false
      } else recursive(A, C) && recursive(B, D)
    }

    if (solve()) println("Yes")
    else println("No")
  }

}
