#include #include const int MAX_DIMENSION = 60 + 5; const int MAX_CARROTS = 60 + 5; const int NUMBER_OF_FLAGS = 2; /* flag = 1 : we can't move j1 anymore flag = 0 : we can move j1 */ int test_cases; int n, m, c, d, modulo; bool has_carrot[MAX_DIMENSION][MAX_DIMENSION]; int dp[MAX_DIMENSION][MAX_DIMENSION][MAX_DIMENSION][MAX_CARROTS][NUMBER_OF_FLAGS]; inline void update (int &a, int b) { a += b; if (a >= modulo) a -= modulo; } int main(int argc, const char * argv[]) { std::ios_base::sync_with_stdio(false); std::cin >> test_cases; while (test_cases--) { std::cin >> n >> m >> c >> d >> modulo; for(size_t i = 1; i <= n; ++i) for(size_t j = 1; j <= m; ++j) has_carrot[i][j] = false; for(size_t i = 0; i <= n; ++i) for(size_t j = 0; j <= m; ++j) for(size_t k = 0; k <= m; ++k) for(size_t l = 0; l <= d; ++l) for(size_t fl = 0; fl < NUMBER_OF_FLAGS; fl++) dp[i][j][k][l][fl] = 0; for(size_t i = 0; i < c; ++i) { size_t x, y; std::cin >> x >> y; has_carrot[x][y] = true; } dp[1][1][1][0][1] = 1; for(size_t i = 1; i <= n; ++i) for(size_t j1 = 1; j1 <= m; ++j1) for(size_t j2 = j1; j2 <= m; ++j2) for(size_t l = 0; l <= d; ++l) for(size_t fl = 0; fl < NUMBER_OF_FLAGS; ++fl) { if (j1 < j2) update(dp[i + 1][j1][j2][l + has_carrot[i + 1][j1] + has_carrot[i + 1][j2]][0], dp[i][j1][j2][l][fl]); if (fl == 0 && (j1 + 1 < j2 || i == n)) update(dp[i][j1 + 1][j2][l + has_carrot[i][j1 + 1]][0], dp[i][j1][j2][l][fl]); update(dp[i][j1][j2 + 1][l + has_carrot[i][j2 + 1]][1], dp[i][j1][j2][l][fl]); } int answer = 0; for(int i = 0; i <= d; ++i) update(answer, dp[n][m][m][i][0]); std::cout << answer << std::endl; } return 0; }