// Original C++ solution (slower):
#include <iostream>

#include <algorithm>

#include <cstring>

#include <string>

#include <vector>

#include <set>

#include <map>

#include <queue>

#include <cmath>

#include <stack>

#include <iomanip>

#include <functional>

#include <array>

#include <memory>

#include <bitset>

#include <unordered_set>

#include <unordered_map>

#include <numeric>

#undef NDEBUG

#include <assert.h>



using namespace std;

typedef long long ll;





int n, m;

set<int> adj[(int)2e5];

bool removed[(int)2e5];

string s;



bool valid(const int u) {

	bool ok[2] = { false, false };

	for (auto &&v : adj[u])

		if (!removed[v])

			ok[s[v] - 'A'] = true;

	return ok[0] && ok[1];

}



int main() {

	ios::sync_with_stdio(0);

	cin.tie(0), cout.tie(0);



	cin >> n >> m >> s;

	for (int i = 0; i < m; ++i) {

		int a, b;

		cin >> a >> b;

		--a, --b;

		adj[a].insert(b);

		adj[b].insert(a);

	}



	queue<int> q;

	for (int i = 0; i < n; ++i)

		if (!valid(i)) {

			removed[i] = true;

			q.push(i);

		}



	while (!q.empty()) {

		const int u = q.front();

		assert(removed[u]);

		q.pop();

		for (const int &v : adj[u]) {

			if (v != u) {

				// adj[v].erase(u);

				if (!removed[v] && !valid(v)) {

					removed[v] = true;

					q.push(v);

				}

			}

		}

	}



	const bool ans = any_of(removed, removed + n, [](const bool x) { return x == false;  });

	cout << (ans ? "Yes" : "No") << '\n';

	return 0;

}

// Optimized solution to the same problem (faster):
#include <iostream>

#include <algorithm>

#include <cstring>

#include <string>

#include <vector>

#include <set>

#include <map>

#include <queue>

#include <cmath>

#include <stack>

#include <iomanip>

#include <functional>

#include <array>

#include <memory>

#include <bitset>

#include <unordered_set>

#include <unordered_map>

#include <numeric>

#undef NDEBUG

#include <assert.h>



using namespace std;

typedef long long ll;





int n, m;

vector<int> adj[(int)2e5];

int cnt[(int)2e5][2];

string s;



int main() {

	ios::sync_with_stdio(0);

	cin.tie(0), cout.tie(0);



	cin >> n >> m >> s;

	/*

	n = (int)2e4;

	s = string(2, 'A') + string(n - 2, 'B');

	vector<pair<int, int>> edges = {

		{1, 2},

		{2, 3},

		{3, 3}

	};



	for (int i = 3; i <= n; ++i)

		edges.push_back({ 1, i });



	m = edges.size();

	*/



	for (int i = 0; i < m; ++i) {

		int a, b;

		// tie(a, b) = edges[i];

		cin >> a >> b;

		--a, --b;

		adj[a].push_back(b);

		adj[b].push_back(a);

	}



	queue<int> q;

	for (int i = 0; i < n; ++i) {

		for (char c = 'A'; c <= 'B'; ++c)

			cnt[i][c - 'A'] = count_if(adj[i].begin(), adj[i].end(), [&c](const int &x) { return s[x] == c; });

		if (any_of(cnt[i], cnt[i] + 2, [](const int &x) { return x == 0;  }))

			q.push(i);

	}



	auto removed = [](const int u) {

		assert(cnt[u][0] >= 0 && cnt[u][1] >= 0);

		return !cnt[u][0] || !cnt[u][1];

	};



	while (!q.empty()) {

		const int u = q.front();

		q.pop();

		assert(removed(u));

		for (const int &v : adj[u])

			if (!removed(v) && --cnt[v][s[u] - 'A'] == 0)

				q.push(v);

	}



	const bool ans = any_of(cnt, cnt + n, [](const int c[]) { return c[0] && c[1];  });

	cout << (ans ? "Yes" : "No") << '\n';

	return 0;

}

// Fastest known solution for this problem: