import scala.annotation.tailrec
import scala.collection.mutable
import scala.io.StdIn._
object Main extends App {
  loop
  @tailrec
  def loop: Unit = {
    val Array(n, m, s, t) = readLine.trim.split(' ').map(_.toInt)
    if (n == 0) return
    val factor = Array.tabulate(n){_ ⇒ Array.tabulate(n){_ ⇒ false}}
    val term = Array.tabulate(n){_ ⇒ Array.tabulate(n){_ ⇒ false}}
    val expression = Array.tabulate(n){_ ⇒ Array.tabulate(n){_ ⇒ false}}
    val factors = Array.tabulate(n){_ ⇒ Nil: List[Int]}
    val terms = Array.tabulate(n){_ ⇒ Nil: List[Int]}
    val expressions = Array.tabulate(n){_ ⇒ Nil: List[Int]}
    val factorsInv = Array.tabulate(n){_ ⇒ Nil: List[Int]}
    val termsInv = Array.tabulate(n){_ ⇒ Nil: List[Int]}
    val expressionsInv = Array.tabulate(n){_ ⇒ Nil: List[Int]}
    val openExclusive = Array.tabulate(n){_ ⇒ Nil: List[Int]}
    val openInclusive = Array.tabulate(n){_ ⇒ Nil: List[Int]}
    val closeExclusive = Array.tabulate(n){_ ⇒ Nil: List[Int]}
    val closeInclusive = Array.tabulate(n){_ ⇒ Nil: List[Int]}
    val plus = Array.tabulate(n){_ ⇒ Nil: List[Int]}
    val multiple = Array.tabulate(n){_ ⇒ Nil: List[Int]}
    val plusInv = Array.tabulate(n){_ ⇒ Nil: List[Int]}
    val multipleInv = Array.tabulate(n){_ ⇒ Nil: List[Int]}
    val bridges = Array.tabulate(m){_ ⇒
      val Array(a, b, c) = readLine.trim.split(' ')
      if (c == "(") openExclusive(b.toInt - 1) ::= a.toInt - 1
      if (c == "[") openInclusive(b.toInt - 1) ::= a.toInt - 1
      if (c == ")") closeExclusive(a.toInt - 1) ::= b.toInt - 1
      if (c == "]") closeInclusive(a.toInt - 1) ::= b.toInt - 1
      if (c == "+") {
        plus(a.toInt - 1) ::= b.toInt - 1
        plusInv(b.toInt - 1) ::= a.toInt - 1
      }
      if (c == "*") {
        multiple(a.toInt - 1) ::= b.toInt - 1
        multipleInv(b.toInt - 1) ::= a.toInt - 1
      }
      Bridge(a.toInt - 1, b.toInt - 1, c.head)
    }
    val queue = mutable.Queue[Stamps]()
    for (Bridge(f, t, c) ← bridges if c == 'a'){
      if (!factor(f)(t)) {
        factor(f)(t) = true
        factors(f) ::= t
        factorsInv(t) ::= f
      }
      queue.enqueue(Factor(f, t))
    }
    while(queue.nonEmpty && !expression(s - 1)(t - 1)){
      queue.dequeue() match {
        case Expression(a, b) ⇒
          plus(b).foreach{mid ⇒
            terms(mid).filterNot(to ⇒ expression(a)(to)).foreach{to ⇒
              expression(a)(to) = true
              expressions(a) ::= to
              expressionsInv(to) ::= a
              queue.enqueue(Expression(a, to))
            }
          }
          openExclusive(a).foreach{from ⇒
            closeExclusive(b).filterNot(to ⇒ factor(from)(to)).foreach{to ⇒
              factor(from)(to) = true
              factors(from) ::= to
              factorsInv(to) ::= from
              queue.enqueue(Factor(from, to))
            }
          }
          openInclusive(a).foreach{from ⇒
            closeInclusive(b).filterNot(to ⇒ factor(from)(to)).foreach{to ⇒
              factor(from)(to) = true
              factors(from) ::= to
              factorsInv(to) ::= from
              queue.enqueue(Factor(from, to))
            }
          }
        case Term(a, b) ⇒
          if (!expression(a)(b)) {
            expression(a)(b) = true
            expressions(a) ::= b
            expressionsInv(b) ::= a
            queue.enqueue(Expression(a, b))
          }
          multiple(b).foreach{mid ⇒
            factors(mid).filterNot(to ⇒ term(a)(to)).foreach{to ⇒
              term(a)(to) = true
              terms(a) ::= to
              termsInv(to) ::= a
              queue.enqueue(Term(a, to))
            }
          }
          plusInv(a).foreach{mid ⇒
            expressionsInv(mid).filterNot(from ⇒ expression(from)(b)).foreach{from ⇒
              expression(from)(b) = true
              expressions(from) ::= b
              expressionsInv(b) ::= from
              queue.enqueue(Expression(from, b))
            }
          }
        case Factor(a, b) ⇒
          if (!term(a)(b)){
            term(a)(b) = true
            terms(a) ::= b
            termsInv(b) ::= a
            queue.enqueue(Term(a, b))
          }
          multipleInv(a).foreach{mid ⇒
            termsInv(mid).filterNot(from ⇒ term(from)(b)).foreach{from ⇒
              term(from)(b) = true
              terms(from) ::=b
              termsInv(b) ::= from
              queue.enqueue(Term(from, b))
            }
          }
      }
    }
    println(
      if (expression(s - 1)(t - 1)) "Yes" else "No"
    )
    loop
  }
  case class Bridge(from: Int, to: Int, char: Char)
  sealed trait Stamps
  case class Expression(from: Int, to: Int) extends Stamps
  case class Term(from: Int, to: Int) extends Stamps
  case class Factor(from: Int, to: Int) extends Stamps
}


Measured memory_bytes: 488328