#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
#define rep(i, l, r) for (int i = l; i <= r; ++i)
#define dep(i, l, r) for (int i = r; i >= l; --i)
const int N = 1e3 + 5;
const int P = 998244353;
int n, m, Sb, Sw, res, cnt;
int b[5], a[5][5], pr[5][5], z[N][5], p[N][N], q[N][N], sp[N][N], sq[N][N];
namespace io {
const int SIZE = 1 << 22 | 1;
char iBuf[SIZE], *iS, *iT, c;
char oBuf[SIZE], *oS = oBuf, *oT = oBuf + SIZE;
#define gc() (iS == iT ? iT = iBuf + fread(iS = iBuf, 1, SIZE, stdin), (iS == iT ? EOF : *iS++) : *iS++)
template<class I> void read(I &x) {
int f = 1;
for(c = gc(); c < '0' || c > '9'; c = gc())
if(c == '-') f = -1;
for(x = 0; c >= '0' && c <= '9'; c = gc())
x = (x << 3) + (x << 1) + (c & 15);
x *= f;
}
inline void flush () {
fwrite(oBuf, 1, oS - oBuf, stdout);
oS = oBuf;
}
inline void putc(char x) {
*oS++ = x;
if(oS == oT) flush();
}
template<class I> void print(I x) {
if(x < 0) putc('-'), x = -x;
static char qu[55];
char *tmp = qu;
do *tmp++ = (x % 10) ^ '0'; while(x /= 10);
while(tmp-- != qu) putc(*tmp);
putc(' ');
}
struct flusher{ ~flusher() { flush(); } }_;
}
using io :: read;
using io :: print;
int inc (int a, int b) { return (a += b) >= P ? a - P : a; }
int dec (int a, int b) { return (a -= b) < 0 ? a + P : a; }
int mul (int a, int b) { return 1ll * a * b % P; }
int fpow (int a, int b) { int ans = 1; for ( ; b; a = mul(a, a), b >>= 1) if(b & 1) ans = mul(ans, a); return ans; }
void dfs (int u) {
if(u > 3) {
memset(a, 0, sizeof(a));
rep(x, 1, 2) rep(y, 1, b[x - 1]) a[x][y] = 1;
rep(y, 1, 2) rep(x, 1, b[y + 2 - 1]) a[x][y] = 1;
rep(x, 1, 2) rep(y, 1, 2) if(!a[x][y]) return ;
// rep(i, 0, 3) cout << b[i] << ' '; cout << '\n';
++cnt;
rep(i, 0, 3) z[cnt][i] = b[i];
return ;
}
b[u] = 0, dfs(u + 1);
b[u] = 1, dfs(u + 1);
b[u] = 2, dfs(u + 1);
}
int main () {
ios :: sync_with_stdio(0), cin.tie(0), cout.tie(0);
read(n), read(m);
rep(i, 1, n) rep(j, 1, m)
read(p[i][j]), sp[i][j] = inc(sp[i][j - 1], p[i][j]);
rep(i, 1, n) rep(j, 1, m)
read(q[i][j]), sq[i][j] = inc(sq[i - 1][j], q[i][j]);
rep(i, 1, n) rep(j, 1, m)
Sb = inc(Sb, dec(1, mul(sp[i][j - 1], sq[i - 1][j])));
// cout << Sb << '\n';
rep(i, 1, n) rep(j, 1, m - 1) {
int pr = dec(1, sp[i][j]);
pr = inc(pr, mul(p[i][j], dec(1, sq[i - 1][j + 1])));
pr = inc(pr, mul(sp[i][j - 1], mul(dec(1, sq[i - 1][j]), dec(1, sq[i - 1][j + 1]))));
Sb = dec(Sb, pr);
}
// cout << Sb << '\n';
rep(i, 1, n - 1) rep(j, 1, m) {
int pr = dec(1, sq[i][j]);
pr = inc(pr, mul(q[i][j], dec(1, sp[i + 1][j - 1])));
pr = inc(pr, mul(sq[i - 1][j], mul(dec(1, sp[i][j - 1]), dec(1, sp[i + 1][j - 1]))));
Sb = dec(Sb, pr);
}
// cout << Sb << '\n';
dfs(0);
rep(i, 1, n - 1) rep(j, 1, m - 1) {
pr[0][0] = sp[i][j - 1], pr[0][1] = p[i][j], pr[0][2] = dec(1, sp[i][j]);
pr[1][0] = sp[i + 1][j - 1], pr[1][1] = p[i + 1][j], pr[1][2] = dec(1, sp[i + 1][j]);
pr[2][0] = sq[i - 1][j], pr[2][1] = q[i][j], pr[2][2] = dec(1, sq[i][j]);
pr[3][0] = sq[i - 1][j + 1], pr[3][1] = q[i][j + 1], pr[3][2] = dec(1, sq[i][j + 1]);
rep(k, 1, cnt) {
res = 1;
rep(j, 0, 3) res = mul(res, pr[j][z[k][j]]);
// if(res) cout << i << ' ' << j << ' ' << k << ' ' << res << '\n';
Sb = inc(Sb, res);
}
}
rep(i, 1, n) rep(j, 1, m)
Sw = inc(Sw, mul(sp[i][j - 1], sq[i - 1][j]));
rep(i, 1, n) rep(j, 1, m - 1) {
int pr = mul(sq[i - 1][j], sq[i - 1][j + 1]);
Sw = dec(Sw, mul(pr, sp[i][j - 1]));
}
rep(i, 1, n - 1) rep(j, 1, m) {
int pr = mul(sp[i][j - 1], sp[i + 1][j - 1]);
Sw = dec(Sw, mul(pr, sq[i - 1][j]));
}
rep(i, 1, n - 1) rep(j, 1, m - 1) {
int pr = mul(sp[i][j - 1], sp[i + 1][j - 1]);
pr = mul(pr, mul(sq[i - 1][j], sq[i - 1][j + 1]));
Sw = inc(Sw, pr);
}
// cout << Sb << ' ' << Sw << '\n';
cout << inc(Sb, inc(mul(Sw, 2), 1)) << '\n';
return 0;
}