You are given an undirected graph with N vertices and M edges. Each vertex has a label, A or B. The phantom thief Nusook starts at a vertex and traverses edges to create a string of visited vertex labels. Determine if Nusook can create all possible strings of A and B. Constraints: 2 ≤ N ≤ 2 × 10^5, 1 ≤ M ≤ 2 × 10^5, |s| = N, s_i is A or B, 1 ≤ a_i, b_i ≤ N. The input format is N, M, followed by the vertex labels, and the edges. Output "Yes" if Nusook can create all strings, otherwise "No". Examples are provided.

# Buggy version:
import sys

input=sys.stdin.readline

def main():
    N,M=map(int,input().split())
    s=input()
    dic={"A":[0 for i in range(N)],"B":[0 for i in range(N)]}
    edge=[[] for i in range(N)]

    for i in range(M):
        a,b=map(int,input().split())
        a-=1;b-=1
        edge[a].append(b)
        edge[b].append(a)
        dic[s[a]][b]+=1
        dic[s[b]][a]+=1

    que=set([])
    check=0
    for i in range(N):
        if dic["A"][i]==0 or dic["B"][i]==0:
            que.add(i)
            dic["A"][v]=float("inf")
            dic["B"][v]=float("inf")

    while que:
        v=que.pop()
        check+=v+1
        for nv in edge[v]:
            dic[s[v]][nv]-=1
            if dic["A"][nv]==0 or dic["B"][nv]==0:
                dic["A"][v]=float("inf")
                dic["B"][v]=float("inf")
                que.add(nv)

    if check==N*(N+1)//2:
        print("No")
    else:
        print("Yes")

if __name__=="__main__":
    main()

# Fixed version:
import sys

input=sys.stdin.readline

def main():
    N,M=map(int,input().split())
    s=input()
    dic={"A":[0 for i in range(N)],"B":[0 for i in range(N)]}
    edge=[[] for i in range(N)]

    for i in range(M):
        a,b=map(int,input().split())
        a-=1;b-=1
        edge[a].append(b)
        edge[b].append(a)
        dic[s[a]][b]+=1
        dic[s[b]][a]+=1

    que=set([])
    check=0
    for i in range(N):
        if dic["A"][i]==0 or dic["B"][i]==0:
            que.add(i)


    while que:
        v=que.pop()
        check+=v+1
        dic["A"][v]=float("inf")
        dic["B"][v]=float("inf")
        for nv in edge[v]:
            dic[s[v]][nv]-=1
            if dic["A"][nv]==0 or dic["B"][nv]==0:
                que.add(nv)

    if check==N*(N+1)//2:
        print("No")
    else:
        print("Yes")

if __name__=="__main__":
    main()

# Buggy version:
def main():
    N, M = map(int, input().split())
    S = [i == "B" for i in input()]
    ab = [list(map(int, input().split())) for _ in [0]*M]
    graph = [set() for _ in [0]*N]
    [graph[a-1].add(b-1) for a, b in ab]
    [graph[b-1].add(a-1) for a, b in ab]

    status = [[0, 0] for _ in [0]*N]

    for i in range(N):
        for j in g[i]:
            status[i][S[j]] += 1

    que = []
    for i, (p, q) in enumerate(status):
        if (p == 0) ^ (q == 0):
            que.append(i)

    while que:
        i = que.pop()
        c = S[i]
        for j in graph[i]:
            if i != j:
                graph[j].remove(i)
            status[j][c] -= 1
            p, q = status[j]
            if (p == 0) ^ (q == 0):
                que.append(j)
        g[i] = set()

    for i in g:
        if i:
            print("Yes")
            return
    print("No")


main()


# Fixed version:
def main():
    N, M = map(int, input().split())
    S = [i == "B" for i in input()]
    ab = [list(map(int, input().split())) for _ in [0]*M]
    graph = [set() for _ in [0]*N]
    [graph[a-1].add(b-1) for a, b in ab]
    [graph[b-1].add(a-1) for a, b in ab]

    status = [[0, 0] for _ in [0]*N]

    for i in range(N):
        for j in graph[i]:
            status[i][S[j]] += 1

    que = []
    for i, (p, q) in enumerate(status):
        if (p == 0) ^ (q == 0):
            que.append(i)

    while que:
        i = que.pop()
        c = S[i]
        for j in graph[i]:
            if i != j:
                graph[j].remove(i)
            status[j][c] -= 1
            p, q = status[j]
            if (p == 0) ^ (q == 0):
                que.append(j)
        graph[i] = set()

    for i in graph:
        if i:
            print("Yes")
            return
    print("No")


main()

# Buggy version:
import sys
input = sys.stdin.readline
sys.setrecursionlimit(pow(10, 6))


def main():
    n, m = map(int, input().split())
    s = input().strip()
    ab = [tuple(map(int, input().split())) for _ in range(m)]
    edges = [[] for _ in range(n)]
    for a, b in ab:
        edges[a - 1].append(b - 1)
        edges[b - 1].append(a - 1)
    
    ab = [[0, 0] for i in range(n)]
    stack = []
    for i in range(n):
        for e in edges[i]:
            if s[e] == 'A':
                ab[i][0] += 1
            else:
                ab[i][1] += 1
        if ab[i][0] == 0 or ab[i][1] == 0:
            stack.append(i)
    
    deleted = [False for i in range(n)]
    while len(stack) > 0:
        q = stack.pop()
        if deleted[q]:
            continue
        deleted[q] = True
        for e in edges[q]:
            if not deleted[e]:
                if s[q] == 'A':
                    ab[e][0] -= 1
                    if ab[e][0] == 0:
                        stack.append(e)
                else:
                    ab[e][1] -= 1
                    if ab[e][1] == 0:
                        stack.append(e)
    
    for d in deleted:
        if not d:
            print("Yes")
            break
    else:
        print("no")


if __name__ == '__main__':
    main()


# Fixed version:
import sys
input = sys.stdin.readline
sys.setrecursionlimit(pow(10, 6))


def main():
    n, m = map(int, input().split())
    s = input().strip()
    ab = [tuple(map(int, input().split())) for _ in range(m)]
    edges = [[] for _ in range(n)]
    for a, b in ab:
        edges[a - 1].append(b - 1)
        edges[b - 1].append(a - 1)
    
    ab = [[0, 0] for i in range(n)]
    stack = []
    for i in range(n):
        for e in edges[i]:
            if s[e] == 'A':
                ab[i][0] += 1
            else:
                ab[i][1] += 1
        if ab[i][0] == 0 or ab[i][1] == 0:
            stack.append(i)
    
    deleted = [False for i in range(n)]
    while len(stack) > 0:
        q = stack.pop()
        if deleted[q]:
            continue
        deleted[q] = True
        for e in edges[q]:
            if not deleted[e]:
                if s[q] == 'A':
                    ab[e][0] -= 1
                    if ab[e][0] == 0:
                        stack.append(e)
                else:
                    ab[e][1] -= 1
                    if ab[e][1] == 0:
                        stack.append(e)
    
    for d in deleted:
        if not d:
            print("Yes")
            break
    else:
        print("No")


if __name__ == '__main__':
    main()

# Buggy version:
from collections import deque
N,M=map(int,input().split())
s=input()
H=[[] for i in range(N)]
G=[[] for i in range(2*N)]
for i in range(M):
    a,b=map(int,input().split())
    a-=1
    b-=1
    H[a].append(b)
    H[b].append(a)
    if s[a]=="A":
        if s[b]=="A":
            G[a].append(N+b)
            G[b].append(N+a)
        else:
            G[a+N].append(b+N)
            G[b].append(a)
    else:
        if s[b]=="A":
            G[a].append(b)
            G[N+b].append(N+a)
        else:
            G[N+a].append(b)
            G[N+b].append(a)
K=[0 for i in range(2*N)]
for i in range(2*N):
    for p in G[i]:
        K[p]+=1
q=deque(i for i in range(2*N) if K[i]==0)
res=[]
while q:
    v1=q.popleft()
    res.append(v1)
    for v2 in G[v1]:
        K[v2]-=1
        if K[v2]==0:
            q.append(v2)
if len(res)==2*N:
    print("Yes")
else:
    print("No")


# Fixed version:
from collections import deque
N,M=map(int,input().split())
s=input()
H=[[] for i in range(N)]
G=[[] for i in range(2*N)]
for i in range(M):
    a,b=map(int,input().split())
    a-=1
    b-=1
    H[a].append(b)
    H[b].append(a)
    if s[a]=="A":
        if s[b]=="A":
            G[a].append(N+b)
            G[b].append(N+a)
        else:
            G[a+N].append(b+N)
            G[b].append(a)
    else:
        if s[b]=="A":
            G[a].append(b)
            G[N+b].append(N+a)
        else:
            G[N+a].append(b)
            G[N+b].append(a)
K=[0 for i in range(2*N)]
for i in range(2*N):
    for p in G[i]:
        K[p]+=1
q=deque(i for i in range(2*N) if K[i]==0)
res=[]
while q:
    v1=q.popleft()
    res.append(v1)
    for v2 in G[v1]:
        K[v2]-=1
        if K[v2]==0:
            q.append(v2)
if len(res)==2*N:
    print("No")
else:
    print("Yes")

# Buggy version:
import collections

n,m = map(int,input().split())
s = list(str(input()))
key = collection.deque()
lis = [[] for i in range(n)]
li = [{"A":0,"B":0} for i in range(n)]

for i in range(m):
  a,b = map(int,input().split())
  lis[a-1].append(b-1)
  lis[b-1].append(a-1)
  li[a-1][s[b-1]] += 1
  li[b-1][s[a-1]] += 1
  
ans = [0 for i in range(n)]

for i in range(n):
  if li[i]["A"] == 0 or li[i]["B"] == 0:
    key.append(i)
    ans[i] = 1
    
while len(key) > 0:
  num = key.popleft()
  for nu in lis[num]:
    li[j][s[num]] -= 1
    if li[j]["A"] == 0 or li[j]["B"] == 0:
      if ans[j] == 0:
        key.append(j)
        ans[j] = 1

if sum(ans) == n:print("No")
else:print("Yes")

# Fixed version:
import collections

n,m = map(int,input().split())
s = list(str(input()))
key = collections.deque()
lis = [[] for i in range(n)]
li = [{"A":0,"B":0} for i in range(n)]

for i in range(m):
  a,b = map(int,input().split())
  lis[a-1].append(b-1)
  lis[b-1].append(a-1)
  li[a-1][s[b-1]] += 1
  li[b-1][s[a-1]] += 1
  
ans = [0 for i in range(n)]

for i in range(n):
  if li[i]["A"] == 0 or li[i]["B"] == 0:
    key.append(i)
    ans[i] = 1
    
while len(key) > 0:
  num = key.popleft()
  for nu in lis[num]:
    li[nu][s[num]] -= 1
    if li[nu]["A"] == 0 or li[nu]["B"] == 0:
      if ans[nu] == 0:
        key.append(nu)
        ans[nu] = 1

if sum(ans) == n:print("No")
else:print("Yes")

# Buggy version:
import sys,time
sys.setrecursionlimit(10**7)

start_time = time.time()
N,M = map(int,input().split())
S = input()
src = [tuple(map(lambda x:int(x)-1,input().split())) for i in range(M)]

outdeg = [set() for i in range(2*N)]
for x,y in src:
    if S[x] == S[y]:
        #A0->A1, B0->B1
        outdeg[x].add(y+N)
        outdeg[y].add(x+N)
    else:
        #A1->B0, B1->A0
        outdeg[x+N].add(y)
        outdeg[y+N].add(x)

mem = [0] * (2*N)
def visit(v):
    # gori~~~
    if time.time() - start_time > 1.8:
        break
    if mem[v] == 1:
        print('Yes')
        exit()
    if mem[v] == 0:
        mem[v] = 1
        for to in outdeg[v]:
            visit(to)
        mem[v] = 2

for i in range(2*N):
    visit(i)

print('No')

# Fixed version:
import sys,time
sys.setrecursionlimit(10**7)

start_time = time.time()
N,M = map(int,input().split())
S = input()
src = [tuple(map(lambda x:int(x)-1,sys.stdin.readline().split())) for i in range(M)]

outdeg = [set() for i in range(2*N)]
for x,y in src:
    if S[x] == S[y]:
        #A0->A1, B0->B1
        outdeg[x].add(y+N)
        outdeg[y].add(x+N)
    else:
        #A1->B0, B1->A0
        outdeg[x+N].add(y)
        outdeg[y+N].add(x)

mem = [0] * (2*N)
def visit(v):
    if time.time() - start_time > 1.8:
        # gori~~~
        print('No')
        exit()
    if mem[v] == 1:
        print('Yes')
        exit()
    if mem[v] == 0:
        mem[v] = 1
        for to in outdeg[v]:
            visit(to)
        mem[v] = 2

for i in range(2*N):
    visit(i)

print('No')