output_description: If Nusook can make all strings consisting of `A` and `B`, print `Yes`;
  otherwise, print `No`.
  
  * * *
input_description: Input is given from Standard Input in the following format:
  
      
      
      N M
      s
      a_1 b_1
      :
      a_{M} b_{M}
attempt: N, M = map(int, input().split())
  s = input()
  
  
  class Node:
      def __init__(self, node_id, label):
          self.node_id = node_id
          self.label = label
          self.from_links = set()
          self.to_links = set()
  
      def from_link(self, l):
          self.from_links.add(l)
  
      def to_link(self, l):
          self.to_links.add(l)
  
      def remove_from_link(self, l):
          self.from_links.remove(l)
  
      def remove_to_link(self, l):
          self.to_links.remove(l)
  
      def is_orphen(self):
          return not (self.to_links or self.from_links)
  
      def __repr__(self):
          return "Node<%d, %s>" % (self.node_id, label)
  
  
  class Link:
      def __init__(self, frm, to):
          self.frm = frm
          self.to = to
          self.to_node = None
          self.frm_node = None
  
      def __repr__(self):
          return "Link<%s, %s>" % (self.frm_node, self.to_node)
  
  
  class Graph:
      def __init__(self):
          self.nodes = dict()
          self.links = set()
  
      def add_node(self, node):
          self.nodes[node.node_id] = node
  
      def add_link(self, l):
          self.links.add(l)
          l.to_node = self.nodes[l.to]
          l.frm_node = self.nodes[l.frm]
          self.nodes[l.frm].from_link(l)
          self.nodes[l.to].to_link(l)
  
      def remove_link(self, l):
          self.links.remove(l)
  
          fn = self.nodes[l.frm]
          tn = self.nodes[l.to]
          fn.remove_from_link(l)
          tn.remove_to_link(l)
  
      def remove_node(self, n):
          del self.nodes[n.node_id]
  
  
  g = Graph()
  for i, label in enumerate(s, 1):
      g.add_node(Node(i, label))
  for _ in range(M):
      a, b = map(int, input().split())
      g.add_link(Link(a, b))
      g.add_link(Link(b, a))
  
  while True:
      flag = False
      touched = set()
      for n in g.nodes.values():
          if not n.to_links:
              continue
          lbl = set(m.to_node.label for m in n.from_links)
          if "A" not in lbl or "B" not in lbl:
              touched.add(n)
              for l in n.to_links.copy():
                  g.remove_link(l)
                  touched.add(l.frm_node)
                  touched.add(l.to_node)
      if touched:
          for n in touched:
              if n.is_orphen():
                  g.remove_node(n)
      else:
          break
  print("Yes" if g.nodes else "No")
  
problem_description: Statement
  
  You are given an undirected graph consisting of N vertices and M edges. The
  vertices are numbered 1 to N, and the edges are numbered 1 to M. In addition,
  each vertex has a label, `A` or `B`. The label of Vertex i is s_i. Edge i
  bidirectionally connects vertex a_i and b_i.
  
  The phantom thief Nusook likes to choose some vertex as the startpoint and
  traverse an edge zero or more times. Today, he will make a string after
  traveling as above, by placing the labels of the visited vertices in the order
  visited, beginning from the startpoint.
  
  For example, in a graph where Vertex 1 has the label `A` and Vertex 2 has the
  label `B`, if Nusook travels along the path 1 \rightarrow 2 \rightarrow 1
  \rightarrow 2 \rightarrow 2, the resulting string is `ABABB`.
  
  Determine if Nusook can make all strings consisting of `A` and `B`.
samples: [{"input": "2 3\n    AB\n    1 1\n    1 2\n    2 2", "output": "Yes\n    \n\n  * Since Nusook can visit Vertex 1 and Vertex 2 in any way he likes, he can make all strings consisting of `A` and `B`.\n\n![77e96cf8e213d606ddd8f3c3f8315d32.png](https://img.atcoder.jp/agc027/77e96cf8e213d606ddd8f3c3f8315d32.png)\n\n* * *"}, {"input": "4 3\n    ABAB\n    1 2\n    2 3\n    3 1", "output": "No\n    \n\n  * For example, Nusook cannot make `BB`.\n  * The given graph may not be connected.\n\n![1ab1411cb9d6ee023d14ca4e77c4b584.png](https://img.atcoder.jp/agc027/1ab1411cb9d6ee023d14ca4e77c4b584.png)\n\n* * *"}, {"input": "13 23\n    ABAAAABBBBAAB\n    7 1\n    10 6\n    1 11\n    2 10\n    2 8\n    2 11\n    11 12\n    8 3\n    7 12\n    11 2\n    13 13\n    11 9\n    4 1\n    9 7\n    9 6\n    8 13\n    8 6\n    4 10\n    8 7\n    4 3\n    2 1\n    8 12\n    6 9", "output": "Yes\n    \n\n* * *"}, {"input": "13 17\n    BBABBBAABABBA\n    7 1\n    7 9\n    11 12\n    3 9\n    11 9\n    2 1\n    11 5\n    12 11\n    10 8\n    1 11\n    1 8\n    7 7\n    9 10\n    8 8\n    8 12\n    6 2\n    13 11", "output": "No"}]