Problem:
Score : 900 points

Problem 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.

Constraints

2 \leq N \leq 2 \times 10^{5}

1 \leq M \leq 2 \times 10^{5}

|s| = N

s_i is A or B.

1 \leq a_i, b_i \leq N

The given graph may NOT be simple or connected.

Input

Input is given from Standard Input in the following format:

N M
s
a_1 b_1
:
a_{M} b_{M}

Output

If Nusook can make all strings consisting of A and B, print Yes; otherwise, print No.

Sample Input 1

2 3
AB
1 1
1 2
2 2

Sample Output 1

Yes

Since Nusook can visit Vertex 1 and Vertex 2 in any way he likes, he can make all strings consisting of A and B.

Sample Input 2

4 3
ABAB
1 2
2 3
3 1

Sample Output 2

No

For example, Nusook cannot make BB.

The given graph may not be connected.

Sample Input 3

13 23
ABAAAABBBBAAB
7 1
10 6
1 11
2 10
2 8
2 11
11 12
8 3
7 12
11 2
13 13
11 9
4 1
9 7
9 6
8 13
8 6
4 10
8 7
4 3
2 1
8 12
6 9

Sample Output 3

Yes

Sample Input 4

13 17
BBABBBAABABBA
7 1
7 9
11 12
3 9
11 9
2 1
11 5
12 11
10 8
1 11
1 8
7 7
9 10
8 8
8 12
6 2
13 11

Sample Output 4

No

Solution in C++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vi> vii;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

const int MAX_N = 4e5 + 10;

multiset<char> conn[MAX_N];
set<int> graph[MAX_N];
bool both[MAX_N];
int dist[MAX_N];
bool self[MAX_N];
vector<pair<int, int> > edges;
int degree[MAX_N];
vector<pii> deg;

int main()
{
	int n, m;
	cin >> n >> m;
	string S;
	cin >> S;
	S = S + S;
	memset(both, false, sizeof(both));
	memset(degree, 0, sizeof(degree));

	while(m--)
	{
		int x, y;
		cin >> x >> y;
		
		if(x == y)
		{
			y = x + n;
			self[x] = true;
			self[y] = true;
			graph[x].insert(y);
			graph[y].insert(x);
			conn[x].insert(S[x - 1]);
			conn[y].insert(S[y - 1]);
			degree[x] += 1;
			degree[y] += 1;
		}
		else
		{
			edges.push_back({x, y});
		}
	}
	for(auto &e : edges)
	{
		int x = e.first;
		int y = e.second;
		graph[x].insert(y);
		conn[x].insert(S[y - 1]);
		degree[x] += 1;
		if(self[x])
		{
			graph[x + n].insert(y);
			conn[x + n].insert(S[y - 1]);
			degree[x + n] += 1;
		}
		graph[y].insert(x);
		conn[y].insert(S[x - 1]);
		degree[y] += 1;
		if(self[y])
		{
			graph[y + n].insert(x);
			conn[y + n].insert(S[x - 1]);
			degree[y + n] += 1;
		}
		
		if(self[x] && self[y])
		{
			graph[x + n].insert(y + n);
			conn[x + n].insert(S[y + n - 1]);
			degree[x + n] += 1;
			graph[y + n].insert(x + n);
			conn[y + n].insert(S[x + n - 1]);
			degree[y + n] += 1;
		}
	}
	for(int i = 1; i <= 2 * n; i++)
	{
		deg.push_back({degree[i], i});
	}
	sort(deg.begin(), deg.end());
	for(int i = 1; i <= 2 * n; i++)
	{
		if((conn[i].size() > 0) && (*(conn[i].begin()) !=  *(conn[i].rbegin())))
			both[i] = true;
	}	
	for(auto &i : deg)
	{
		int u = i.second;
		if(both[u] == false)
		{
			for(auto &v : graph[u])
			{
				graph[v].erase(u);
				conn[v].erase(conn[v].find(S[u - 1]));
				if((conn[v].size() > 0) &&  (*(conn[v].begin()) !=  *(conn[v].rbegin())))
					both[v] = true;		
				else
					both[v] = false;
			}
		}
	}
	
	for(int i = 1; i <= 2 * n; i++)
	{
		if(both[i] == true)
		{
			queue<int> q;
			map<int, bool> visited;
			visited[i] = true;
			dist[i] = 0;
			q.push(i);
			while(!q.empty())
			{
				int u = q.front();
				q.pop();
				for(auto &v : graph[u])
				{
					if(both[v] == true)
					{
						if(visited.find(v) == visited.end())
						{
							dist[v] = dist[u] + 1;
							visited[v] = true;
							if(dist[v] < 2)
								q.push(v);
						}
						else if(dist[v] == 2)
						{
							// cout << "found cycle with parent " << u << " and child " << v << endl;
							cout << "Yes" << endl;
							return 0;
						}
					}
				}
			}
			visited.clear();
		}
	}
	cout << "No" << endl;
	return 0;
}