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)

/**
 * code generated by JHelper
 * More info: https://github.com/AlexeyDmitriev/JHelper
 * @author szawinis
 */

#include <iostream>
#include <fstream>

#include <bits/stdc++.h>
using namespace std;
#define long long long
const long MOD = 1e9+7, LINF = 1e18 + 1e16;
const int INF = 1e9+1;
const double EPS = 1e-10;
const int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
const int N = 2e5+1;

class TaskC {
	int n, m, dsu[N];
	string s;
	vector<int> g[N];
	bool valid[N];

	int root(int v) {
		return (dsu[v] < 0 ? v : dsu[v] = root(dsu[v]));
	}

	void merge(int u, int v) {
		if((u = root(u)) == (v = root(v))) return;
		dsu[u] += dsu[v];
		dsu[v] = u;
	}

public:
	void solve(istream& cin, ostream& cout) {
		cin >> n >> m >> s;
		for(int i = 0, u, v; i < m; i++) {
			cin >> u >> v;
			--u, --v;
			g[u].push_back(v);
			g[v].push_back(u);
		}
		for(int i = 0; i < n; i++) {
			bool hasA = false, hasB = false;
			for(int v: g[i]) {
				hasA |= s[v] == 'A';
				hasB |= s[v] == 'B';
			}
			valid[i] = hasA && hasB;
		}
		fill(dsu, dsu+N, -1);
		for(int u = 0; u < n; u++) if(valid[u]) for(int v: g[u]) if(valid[v]) merge(u, v);
		for(int u = 0; u < n; u++) if(valid[u]) {
			bool hasGoodA = false, hasGoodB = false;
			for(int v: g[u]) if(valid[v]) {
				hasGoodA |= s[v] == 'A';
				hasGoodB |= s[v] == 'B';
			}
			if(!hasGoodA || !hasGoodB) {
				cout << "No" << endl;
				return;
			}
		}
		cout << "Yes" << endl;
	}
};

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	TaskC solver;
	std::istream& in(std::cin);
	std::ostream& out(std::cout);
	solver.solve(in, out);
	return 0;
}