#include using namespace std; using ll = long long; using vl = vector; using mat = vector; const ll MOD = 1'000'000'007; struct problem { ll t; char g; int s, c, b; }; mat mul(const mat& a, const mat& b) { mat c(a.size(), vl(b[0].size(), 0)); for (int i = 0; i < a.size(); ++i) for (int j = 0; j < b[0].size(); ++j) for (int k = 0; k < b.size(); ++k) c[i][j] = (c[i][j] + a[i][k]*b[k][j])%MOD; return c; } mat powm(mat a, ll b) { mat x(a.size(), vl(a[0].size(), 0)); for (int i = 0; i < a.size(); ++i) x[i][i] = 1; while (b) { if (b&1) x = mul(x,a); b >>= 1; a = mul(a,a); } return x; } int main() { ll N; int S, P, C; vector probs; cin >> N >> P >> S >> C; probs.resize(P); for (auto& [t, g, s, c, b] : probs) cin >> t >> g >> s >> c >> b; probs.push_back({N, 'A', S, C, S+C}); // construct matrix step[i][j] = // number of ways to go from i in room A to j in room A in one step // if the number of that type we have in total is K auto construct = [&](int K) { mat step(K+1, vl(K+1,0)); for (int i = 0; i <= K; ++i) for (int j = 0; j <= K; ++j) if (i == j) step[i][j] = 1; else if (i-1 == j) step[i][j] = i; else if (i+1 == j) step[i][j] = K-i; return step; }; mat s_step = construct(S), c_step = construct(C); // transpose c_step for (int i = 1; i <= C; ++i) for (int j = 0; j < i; ++j) swap(c_step[i][j], c_step[j][i]); mat cur(S+1, vl(C+1, 0)); cur[S][C] = 1; // cur[i][j] will be the number of ways to reach i "solvers" in room A and j "coders" // in room A after some number of steps (initially 0) // to update for t steps, do (s_step)^t * cur * (c_step)^t // think: s_step acts on the columns of cur and c_step acts on the rows of cur ll pt = 1; for (int i = 0; i <= P; ++i) { auto [t, g, s, c, b] = probs[i]; // update cur[][] using t-pt steps (previous time to current time) mat sp = powm(s_step, t-pt), cp = powm(c_step, t-pt); cur = mul(mul(sp, cur), cp); // zero out entries of cur that do not correspond to a valid // count of solvers/coders in the room for problem i for (int ss = 0; ss <= S; ++ss) for (int cc = 0; cc <= C; ++cc) { int hs = (g == 'A' ? ss : S-ss), hc = (g == 'A' ? cc : C-cc); if (hs < s || hc < c || hs+hc < b) cur[ss][cc] = 0; } pt = t; } cout << cur[S][C] << endl; }