#include <iostream>
#include <cstdio>
#include <cstring>
#define MOD 998244353
using namespace std;
int T, n, m, c, f;
string* map;
long long** flag[4];
long long find_C();
long long find_F();
void find_C_and_F(long long&, long long&);
int main() {
scanf("%d %*d", &T);
for (; T; T--) {
scanf("%d %d %d %d", &n, &m, &c, &f);
map = new string[n]{};
for (int i = 0; i < n; i++) cin >> map[i];
if (c == 0 && f == 0) {
printf("0 0\n");
delete[] map;
continue;
}
flag[0] = new long long*[n]{};
flag[1] = new long long*[n]{};
flag[2] = new long long*[n]{};
flag[3] = new long long*[n]{};
for (int i = 0; i < n; i++) {
flag[0][i] = new long long[m]{};
flag[1][i] = new long long[m]{};
flag[2][i] = new long long[m]{};
flag[3][i] = new long long[m]{};
}
for (int i = n - 1; i >= 0; i--)
for (int j = m - 1; j >= 0; j--) {
if (j == m - 1)
if (map[i][j] == '1') flag[0][i][j] = flag[2][i][j] = -1;
else flag[0][i][j] = flag[2][i][j] = 0;
else
if (map[i][j] == '1') flag[0][i][j] = -1;
else flag[0][i][j] = (flag[0][i][j + 1] + 1) % MOD;
if (i == n - 1)
if (map[i][j] == '1') flag[1][i][j] = flag[3][i][j] = -1;
else {
flag[1][i][j] = flag[3][i][j] = 0;
flag[2][i][j] = flag[0][i][j] % MOD;
}
else
if (map[i][j] == '1') flag[1][i][j] = flag[2][i][j] = flag[3][i][j] = -1;
else {
flag[1][i][j] = (flag[1][i + 1][j] + 1) % MOD;
if (map[i + 1][j] == '1') {
flag[2][i][j] = flag[0][i][j] % MOD;
flag[3][i][j] = flag[0][i][j] * flag[1][i][j] % MOD;
}
else {
flag[2][i][j] = (flag[0][i][j] + flag[2][i + 1][j]) % MOD;
flag[3][i][j] = (flag[0][i][j] * flag[1][i][j] % MOD + flag[3][i + 1][j]) % MOD;
}
}
}
if (c == 1) {
if (f == 1) {
long long c_ans, f_ans;
find_C_and_F(c_ans, f_ans);
printf("%lld %lld\n", c_ans, f_ans);
}
else printf("%lld 0\n", find_C());
}
else printf("0 %lld\n", find_F());
delete[] map;
for (int i = 0; i < n; i++) delete[] flag[0][i], flag[1][i], flag[2][i], flag[3][i];
delete[] flag[0], flag[1], flag[2], flag[3];
}
return 0;
}
long long find_C() {
long long ans = 0;
for (int i = 0; i < n - 2; i++) {
for (int j = 0; j < m - 1; j++) {
if (map[i][j] == '1' || flag[0][i][j] || flag[1][i][j] < 2) continue;
ans = (ans + flag[0][i][j] * flag[2][i + 2][j] % MOD) % MOD;
}
}
return ans;
}
long long find_F() {
long long ans = 0;
for (int i = 0; i < n - 3; i++) {
for (int j = 0; j < m - 1; j++) {
if (map[i][j] == '1' || flag[0][i][j] == 0 || flag[1][i][j] < 3) continue;
ans = (ans + flag[0][i][j] * flag[3][i + 2][j] % MOD) % MOD;
}
}
return ans;
}
void find_C_and_F(long long &c_ans, long long &f_ans) {
c_ans = f_ans = 0;
for (int i = 0; i < n - 2; i++) {
for (int j = 0; j < m - 1; j++) {
if (map[i][j] == '1' || flag[0][i][j] == 0 || flag[1][i][j] < 2) continue;
c_ans = (c_ans + flag[0][i][j] * flag[2][i + 2][j] % MOD) % MOD;
if (flag[1][i][j] >= 3) f_ans = (f_ans + flag[0][i][j] * flag[3][i + 2][j] % MOD) % MOD;
}
}
return;
}