#include <bits/stdc++.h>
using namespace std;

template <typename Tp>
class segment_tree{
    Tp *tree;
    const size_t len;
    const Tp e;
    Tp (*f)(Tp, Tp);
public:
    segment_tree(size_t n, const Tp &id, Tp (*fn)(Tp, Tp), const Tp *values=nullptr): len(n), e(id), f(fn){
        tree = new Tp[n<<1];
        for(size_t i=0; i<n; ++i) tree[n+i] = values ? values[i] : id;
        for(size_t i=n-1; i>0; --i) tree[i] = fn(tree[i<<1 | 0], tree[i<<1 | 1]);
    }
    void set(size_t pos, const Tp &val){
        tree[pos += len] = val;
        for(pos>>=1; pos>0; pos>>=1) tree[pos] = f(tree[pos<<1 | 0], tree[pos<<1 | 1]);
    }
    void add(size_t pos, const int &val){
        auto v = tree[len+pos];
        v.first += val;
        set(pos, v);
    }
    Tp get(size_t left, size_t right){
        left += len; right += len;
        Tp lval = e, rval = e;
        while(left < right){
            if(left  & 1) lval = f(lval, tree[left ++]);
            if(right & 1) rval = f(tree[--right], rval);
            left >>= 1; right >>= 1;
        }
        return f(lval, rval);
    }
};

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    
    int n, m;
    string s;
    static vector<int> edges[200000];
    static pair<int64_t, int> val[2][200000];
    static bool removed[200000];

    cin >> n >> m;
    cin >> s;
    for(int i=0;i<n;++i) val[0][i] = val[1][i] = {0, i};
    for(int i=0;i<m;++i){
        int a, b;
        cin >> a >> b;
        --a; --b;
        edges[a].emplace_back(b);
        val[s[a] != 'A'][b].first += 1;
        if(a == b) continue;
        edges[b].emplace_back(a);
        val[s[b] != 'A'][a].first += 1;
    }
    for(int i=0;i<n;++i){
        if(val[0][i].first == 0 && val[1][i].first == 0){
            val[0][i].first = val[1][i].first = INT32_MAX;
            removed[i] = true;
        }
    }

    using Tp = pair<int64_t, int>;
    segment_tree<Tp> sta{n, {INT64_MAX, -1}, [](auto x, auto y)->Tp{ return min(x, y); }, val[0]};
    segment_tree<Tp> stb{n, {INT64_MAX, -1}, [](auto x, auto y)->Tp{ return min(x, y); }, val[1]};

    bool updated = true;
    while(updated){
        updated = false;
        auto ma = sta.get(0, n), mb = stb.get(0, n);
        if(ma.first == 0){
            updated = true;
            int pos = ma.second;
            removed[pos] = true;
            sta.set(pos, {INT32_MAX, pos});
            stb.set(pos, {INT32_MAX, pos});
            val[0][pos].first = val[1][pos].first = INT32_MAX;
            for(int to: edges[pos]){
                if(removed[to]) continue;
                --val[s[pos] != 'A'][to].first;
                (s[pos] == 'A' ? sta : stb).add(to, -1);
            }
            continue;
        }
        if(mb.first == 0){
            updated = true;
            int pos = mb.second;
            removed[pos] = true;
            sta.set(pos, {INT32_MAX, pos});
            stb.set(pos, {INT32_MAX, pos});
            val[0][pos].first = val[1][pos].first = INT32_MAX;
            for(int to: edges[pos]){
                if(removed[to]) continue;
                --val[s[pos] != 'A'][to].first;
                (s[pos] == 'A' ? sta : stb).add(to, -1);
            }
            continue;
        }        
    }

    for(int i=0;i<n;++i){
        if(removed[i]) continue;
        int stat = 0;
        queue<int> q;
        removed[i] = true;
        q.emplace(i);
        while(!q.empty()){
            int t = q.front();
            q.pop();
            stat |= (s[t] == 'A') ? 1 : 2;
            if(stat == 3){ cout << "Yes" << endl; return 0; }
            for(int to: edges[t]){
                if(removed[to]) continue;
                removed[to] = true;
                q.emplace(to);
            }
        }
    }
    cout << "No" << endl;
    return 0;
}

Measured memory_bytes: 28752