#include <iostream>
#include <fstream>
#include <iomanip>
#include <climits>
#include <limits>
#include <algorithm>
#include <array>
#include <vector>
#include <deque>
#include <queue>
#include <list>
#include <stack>
#include <string>
#include <functional>
#include <numeric>
#include <map>
#include <set>
#include <cstdlib>
#include <bitset>
#include <unordered_map>
#include <random>
#include <cmath>
#include <complex>
// #include "utiltime.hpp"

using namespace std;

typedef long long int ll;
typedef vector<int> vi;
typedef vector<vector<int>> vvi;
typedef pair<int, int> P;
typedef pair<ll, ll> Pll;
typedef vector<ll> vll;
typedef vector<vector<ll>> vvll;

const int INFL = (int)1e9;
const ll INFLL = (ll)1e18;
const double INFD = numeric_limits<double>::infinity();
const double PI = 3.14159265358979323846;
#define Loop(i, n) for(int i = 0; i < (int)n; i++)
#define Loopll(i, n) for(ll i = 0; i < (ll)n; i++)
#define Loop1(i, n) for(int i = 1; i <= (int)n; i++)
#define Loopll1(i, n) for(ll i = 1; i <= (ll)n; i++)
#define Loopr(i, n) for(int i = (int)n - 1; i >= 0; i--)
#define Looprll(i, n) for(ll i = (ll)n - 1; i >= 0; i--)
#define Loopr1(i, n) for(int i = (int)n; i >= 1; i--)
#define Looprll1(i, n) for(ll i = (ll)n; i >= 1; i--)
#define Loopitr(itr, container) for(auto itr = container.begin(); itr != container.end(); itr++)
#define printv(vector) Loop(i, vector.size()) { cout << vector[i] << " "; } cout << endl;
#define printmx(matrix) Loop(i, matrix.size()) { Loop(j, matrix[i].size()) { cout << matrix[i][j] << " "; } cout << endl; }
#define quickio() ios::sync_with_stdio(false); cin.tie(0);
#define bitmanip(m,val) static_cast<bitset<(int)m>>(val)
ll rndf(double x) { return (ll)(x + (x >= 0 ? 0.5 : -0.5)); }
ll floorsqrt(double x) { ll m = (ll)sqrt(x); return m + (m * m <= (ll)(x) ? 0 : -1); }
ll ceilsqrt(double x) { ll m = (ll)sqrt(x); return m + ((ll)x <= m * m ? 0 : 1); }
ll rnddiv(ll a, ll b) { return (a / b + (a % b * 2 >= b ? 1 : 0)); }
ll ceildiv(ll a, ll b) { return (a / b + (a % b == 0 ? 0 : 1)); }

/*******************************************************/

typedef ll val_t;

struct graph_t {
	int n;           // |V|, index begins with 0
	int m;           // |E|
	vector<P> edges; // E
	vector<val_t> vals; // V
	vector<ll> cost; // cost or distance
	vector<ll> cap;  // capacity
};

class Graph {
private:
	struct node {
		int id; val_t val; bool done; vi to_eid; vi to;
	};
	vector<node> nodes;
	int n;
public:
	Graph(graph_t G) {
		n = G.n;
		nodes.resize(n);
		Loop(i, n) nodes[i] = { i,G.vals[i],false,{},{} };
		Loop(i, G.edges.size()) {
			nodes[G.edges[i].first].to_eid.push_back(i);
			nodes[G.edges[i].first].to.push_back(G.edges[i].second);
		}
		return;
	}
	bool solve() {
		queue<int> que;
		vi cnt_a(n, 0), cnt_b(n, 0);
		Loop(i, n) {
			for(int j : nodes[i].to) {
				if (nodes[j].val == 0) cnt_a[i]++;
				else cnt_b[i]++;
			}
			if (cnt_a[i] == 0 || cnt_b[i] == 0) que.push(i);
		}
		vector<bool> valids(n, true);
		while (que.size()) {
			int a = que.front(); que.pop();
			if (!valids[a]) continue;
			valids[a] = false;
			for (int b : nodes[a].to) {
				if (nodes[a].val == 0) cnt_a[b]--;
				else cnt_b[b]--;
				if (cnt_a[b] == 0 || cnt_b[b] == 0) que.push(b);
			}
		}
		Loop(i, n) {
			if (valids[i]) return true;
		}
		return false;
	}
};

int main() {
	graph_t G;
	cin >> G.n >> G.m;
	string s; cin >> s;
	Loop(i, G.n) G.vals.push_back(s[i] - 'A');
	Loop(i, G.m) {
		int s, t; cin >> s >> t;
		s--; t--;
		G.edges.push_back({ s,t });
		G.edges.push_back({ t,s });
	}
	Graph graph(G);
	bool ans = graph.solve();
	if (ans) cout << "Yes" << endl;
	else cout << "No" << endl;
}

Measured memory_bytes: 34288