#include <bits/stdc++.h>

#define INF 1000000010
#define INFLL ((1LL<<62)-5)
#define FO(i,a,b) for (int (i) = (a); (i) < (b); ++(i))
#define OF(i,a,b) for (int (i) = (a)-1; (i) >= (b); --(i))
#define SZ(v) int(v.size())

using namespace std;
//PAIRS:
#define mp make_pair
#define fi first
#define se second
#define pb push_back
typedef pair<int,int> pii;
typedef long long ll;

/*~~~~TEMPLATE END~~~~*/

//DEBUGS:
//#define DEBUG

#ifdef DEBUG
#define dprintf printf
#else
#define dprintf(...)
#endif

const long long MOD = 998244353;
const ll MAX_N = 100005;

ll inv[MAX_N*4+5];
ll fact[MAX_N*4+5];
ll invfact[MAX_N*4+5];

ll minv (ll c) {
    ll ret = 1;
    ll cP = c;
    FO (i,0,31) {
        if ((MOD-2) & (1<<i)) {
            ret = (ret*cP) % MOD;
        }
        cP = (cP*cP) % MOD;
    }
    return ret;
}

void precomp() {
    FO (i,1,400010) {
        inv[i] = minv(i);
    }
    fact[0] = 1;
    FO (i,1,400010) fact[i] = (fact[i-1]*i) % MOD;
    invfact[0] = 1;
    FO (i,1,400010) invfact[i] = (invfact[i-1]*inv[i]) % MOD;
}

ll chs(ll a, ll b) {
    return ((fact[a] * invfact[b])%MOD * invfact[a-b])%MOD;
}

struct solver {
    int N, M;
    vector<int> vAm;
    vector<int> lV;
    vector<int> rV;
    solver(int __N, int _M, vector<int> &_vAm, vector<int> &_lV, vector<int> &_rV) {
        N = __N;
       M = _M;
        vAm = _vAm;
        lV = _lV;
        rV = _rV;
    }
    ll solve() {
        // rAm contains right side vals, hori must occur.
        vector <ll> rAm;
        ll wAm = 0;
        for (int i : rV) wAm += i;
        ll hAm = 0;
        OF (i,M,0) {
            if (wAm == 0) {
                if (hAm > 0) rAm.pb(0);
                else rAm.pb(1);
            } else {
                rAm.pb(chs(wAm+hAm-1, wAm-1));
            }
            hAm += vAm[i];
        }
        reverse(rAm.begin(), rAm.end());
        FO (i,0,M) dprintf ("%lld ", rAm[i]);
        dprintf("\n");
        // lAm contains left side vals, hori need not occur.
        vector <ll> lAm;
        wAm = 0;
        for (int i : lV) wAm += i;
        hAm = 0;
        FO (i,0,M) {
            if (wAm == 0) {
                if (hAm > 0) lAm.pb(0);
                else lAm.pb(1);
            } else {
                lAm.pb(chs(wAm+hAm-1, wAm-1));
            }
            hAm += vAm[i];
        }
        FO (i,0,M) dprintf ("%lld ", lAm[i]);
        dprintf("\n");
        FO (i,0,M)
            if (!vAm[i]) lAm[i] = 0;
        FO (i,0,M) {
            if (i) lAm[i] += lAm[i-1];
            if (vAm[i] == 2) lAm[i] *= 2;
            lAm[i] %= MOD;
        }
        ll ans = 0;
        FO (i,0,M) {
            if (vAm[i]) {
                ans += (lAm[i] * rAm[i])%MOD;
                ans %= MOD;
            }
        }
        return ans;
    }
};

int N, M;
vector <int> a, b, c, d;

int main() {
    precomp();
    scanf ("%d %d", &N, &M);
    FO (i,0,N) {
        char t;
        scanf (" %c", &t);
        t = t - '0';
        a.pb(t);
    }
    FO (i,0,N) {
        char t;
        scanf (" %c", &t);
        t = t - '0';
        b.pb(t);
    }
    FO (i,0,M) {
        char t;
        scanf (" %c", &t);
        t = t - '0';
        c.pb(t);
    }
    FO (i,0,M) {
        char t;
        scanf (" %c", &t);
        t = t - '0';
        d.pb(t);
    }
    int s = 0;
    FO (i,0,N) s += a[i] + b[i];
    FO (i,0,M) s += c[i] + d[i];
    if (!s) {
        printf ("1\n");
        return 0;
    }
    ll ans = 0;
    FO (i,0,2) {
        vector <int> t;
        FO (i,0,M) {
            t.pb(c[i]+d[i]);
        }
        solver s(N,M,t,a,b);
        ans += s.solve();
        dprintf ("ans: %lld\n", ans);

        swap(N,M);
        swap(a,c);
        swap(b,d);
    }
    printf ("%lld\n", ans % MOD);
    return 0;
}


Measured memory_bytes: 15412