#include using namespace std; #if defined(_WIN32) || defined(_WIN64) #define getchar_unlocked _getchar_nolock #define putchar_unlocked _putchar_nolock #elif defined(__GNUC__) #else #define getchar_unlocked getchar #define putchar_unlocked putchar #endif namespace { #define isvisiblechar(c) (0x21<=(c)&&(c)<=0x7E) class MaiScanner { public: template void input_integer(T& var) noexcept { var = 0; T sign = 1; int cc = getchar_unlocked(); for (; cc<'0' || '9'>(int& var) noexcept { input_integer(var); return *this; } inline MaiScanner& operator>>(long long& var) noexcept { input_integer(var); return *this; } inline MaiScanner& operator>>(string& var) { int cc = getchar_unlocked(); for (; !isvisiblechar(cc); cc = getchar_unlocked()); for (; isvisiblechar(cc); cc = getchar_unlocked()) var.push_back(cc); return *this; } template inline void in(IT begin, IT end) { for (auto it = begin; it != end; ++it) *this >> *it; } }; class MaiPrinter { public: template void output_integer(T var) noexcept { if (var == 0) { putchar_unlocked('0'); return; } if (var < 0) putchar_unlocked('-'), var = -var; char stack[32]; int stack_p = 0; while (var) stack[stack_p++] = '0' + (var % 10), var /= 10; while (stack_p) putchar_unlocked(stack[--stack_p]); } inline MaiPrinter& operator<<(char c) noexcept { putchar_unlocked(c); return *this; } inline MaiPrinter& operator<<(int var) noexcept { output_integer(var); return *this; } inline MaiPrinter& operator<<(long long var) noexcept { output_integer(var); return *this; } inline MaiPrinter& operator<<(char* str_p) noexcept { while (*str_p) putchar_unlocked(*(str_p++)); return *this; } inline MaiPrinter& operator<<(const string& str) { const char* p = str.c_str(); const char* l = p + str.size(); while (p < l) putchar_unlocked(*p++); return *this; } template void join(IT begin, IT end, char sep = ' ') { for (bool b = 0; begin != end; ++begin, b = 1) b ? *this << sep << *begin : *this <<* begin; } }; } MaiScanner scanner; MaiPrinter printer; // ============================================================================= using ll = long long; const ll MD = 1e9+7; int N, M; string label; int dp[100010]; vector > edge_pd, edge_dc, edge_ca; int main() { scanner >> N >> M >> label; edge_pd.reserve(M); edge_dc.reserve(M); edge_ca.reserve(M); for (int _ = M-1; 0 <= _; --_) { int a, b; char ca, cb; scanner >> a >> b; --a; --b; if (label[a] < label[b]) swap(a, b); // note: [A,C,D,P]を降順に並べるとPDCA ca = label[a]; cb = label[b]; if (ca == 'P' && cb == 'D') { edge_pd.emplace_back(a, b); dp[a] = 1; } else if (ca == 'D' && cb == 'C') { edge_dc.emplace_back(a, b); } else if (ca == 'C' && cb == 'A') { edge_ca.emplace_back(a, b); } } for (auto edge : edge_pd) { dp[edge.second] = (dp[edge.second] + dp[edge.first]) % MD; } for (auto edge : edge_dc) { dp[edge.second] = (dp[edge.second] + dp[edge.first]) % MD; } int answer = 0; for (auto edge : edge_ca) { answer = (answer + dp[edge.first]) % MD; } cout << answer << endl; return 0; }