#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
 
using namespace std;
using namespace __gnu_pbds;
 
#define fi first
#define se second
#define mp make_pair
#define pb push_back
 
typedef long long ll;
typedef pair<int,int> ii;
typedef vector<int> vi;
typedef long double ld; 
typedef tree<ii, null_type, less<ii>, rb_tree_tag, tree_order_statistics_node_update> pbds;
vector<int> fact;
vector<int> ifact;
vector<int> inv;
vector<int> pow2;
vector<int> ipow2;
const int MOD = 998244353;
int add(int a, int b)
{
	a+=b;
	while(a>=MOD) a-=MOD;
	return a;
}
int mult(int a, int b)
{
	return (a*1LL*b)%MOD;
}
int modpow(int a, int b)
{
	int r=1;
	while(b)
	{
		if(b&1) r=mult(r,a);
		a=mult(a,a);
		b>>=1;
	}
	return r;
}
int choose(int a, int b)
{
	if(b==0) return 1;
	if(a<b) return 0;
	if(a==b) return 1;
	return mult(fact[a],mult(ifact[b],ifact[a-b]));
}
int inverse(int a)
{
	return modpow(a,MOD-2);
}
void init(int _n)
{
	fact.clear(); ifact.clear(); inv.clear(); pow2.clear(); ipow2.clear();
	fact.resize(_n+1);
	ifact.resize(_n+1);
	inv.resize(_n+1);
	pow2.resize(_n+1);
	ipow2.resize(_n+1);
	pow2[0]=ipow2[0]=1;
	ifact[0]=1;
	fact[0]=1;
	for(int i=1;i<=_n;i++)
	{
		pow2[i]=add(pow2[i-1],pow2[i-1]);
		fact[i]=mult(fact[i-1],i);
		ipow2[i]=inverse(pow2[i]);
		//ifact[i]=mult(ifact[i-1],inv[i]);
	}
	ifact[_n] = inverse(fact[_n]);
	for(int i=_n-1;i>=1;i--)
	{
		ifact[i] = mult(ifact[i + 1], i + 1);
	}
	for(int i=1;i<=_n;i++)
	{
		inv[i] = mult(fact[i-1],ifact[i]);
	}
}

int l[111111];
int r[111111];
int u[111111];
int d[111111];
int prefL[111111];
int prefR[111111];
int prefU[111111];
int prefD[111111];
int prefUD[111111];

int sumL(int l, int r)
{
	if(l>r) return 0;
	if(l==0) return prefL[r];
	else return add(prefL[r],MOD-prefL[l-1]);
}

int sumR(int l, int r)
{
	if(l>r) return 0;
	if(l==0) return prefR[r];
	else return add(prefR[r],MOD-prefR[l-1]);
}

int sumU(int l, int r)
{
	if(l>r) return 0;
	if(l==0) return prefU[r];
	else return add(prefU[r],MOD-prefU[l-1]);
}

int sumD(int l, int r)
{
	if(l>r) return 0;
	if(l==0) return prefD[r];
	else return add(prefD[r],MOD-prefD[l-1]);
}

int sumUD(int l, int r)
{
	if(l>r) return 0;
	if(l==0) return prefUD[r];
	else return add(prefUD[r],MOD-prefUD[l-1]);
}

int solve(int r, int c)
{
	return choose(r+c-1,r);
}

void calcL(string s)
{
	for(int i=0;i<s.length();i++)
	{
		prefL[i]=(s[i]=='1');
		if(i>0) prefL[i]+=prefL[i-1];
	}
}

void calcR(string s)
{
	for(int i=0;i<s.length();i++)
	{
		prefR[i]=(s[i]=='1');
		if(i>0) prefR[i]+=prefR[i-1];
	}
}

void calcU(string s)
{
	for(int i=0;i<s.length();i++)
	{
		prefU[i]=(s[i]=='1');
		if(i>0) prefU[i]+=prefU[i-1];
	}
}

void calcD(string s)
{
	for(int i=0;i<s.length();i++)
	{
		prefD[i]=(s[i]=='1');
		if(i>0) prefD[i]+=prefD[i-1];
	}
}

void calcUD(string s)
{
	for(int i=0;i<s.length();i++)
	{
		prefUD[i]=(s[i]=='1');
		if(i>0) prefUD[i]+=prefUD[i-1];
	}
}

int dpl[222222];
int dpr[222222];

int main()
{
	ios_base::sync_with_stdio(0); cin.tie(0);
	init(533333);
	int n,m; cin>>n>>m;
	string L,R,U,D;
	cin>>L;
	cin>>R;
	cin>>U;
	cin>>D;
	string sud;
	for(int i=0;i<U.length();i++) sud+=char('0'+((U[i]-'0')&(D[i]-'0')));
	calcL(L); calcR(R); calcU(U); calcD(D); calcUD(sud);
	if(sumL(0,n-1)==0&&sumR(0,n-1)==0&&sumU(0,m-1)==0&&sumD(0,m-1)==0){cout<<1<<'\n'; return 0;}
	for(int l=0;l<m;l++)
	{
		int ltot=sumL(0,n-1);
		int c1=sumU(0,l-1);
		int c2=sumD(0,l-1);
		if(l==0) dpl[l]=1;
		else dpl[l]=choose(c1+c2-1+ltot,c1+c2);
	}
	for(int r=0;r<m;r++)
	{
		int ltot=sumR(0,n-1);
		int c1=sumU(r+1,m-1);
		int c2=sumD(r+1,m-1);
		if(r==m-1) dpr[r]=1;
		else dpr[r]=choose(c1+c2-1+ltot,c1+c2);
	}
	int ans=0;
	for(int l=0;l<m;l++)
	{
		int r=l;
		int coeff = mult(pow2[sumUD(l+1,r-1)],((U[l]=='1')+(D[l]=='1'))*(l==r?1:((U[r]=='1')+(D[r]=='1'))));
		if(coeff==0) continue;
		int res1=dpl[l];
		int res2=dpr[r];
		ans=add(ans,mult(coeff,mult(res1,res2)));
	}
	for(int l=0;l<m;l++)
	{
		dpl[l]=mult(dpl[l],ipow2[prefUD[l]]);
		dpl[l]=mult(dpl[l],(U[l]=='1')+(D[l]=='1'));
	}
	for(int r=0;r<m;r++)
	{
		dpr[r]=mult(dpr[r],pow2[(r>0?prefUD[r-1]:0)]);
		dpr[r]=mult(dpr[r],(U[r]=='1')+(D[r]=='1'));
	}
	int sum=0;
	for(int l=0;l+1<m;l++)
	{
		//solve for all r>l
		sum=add(sum,dpl[l]);
		ans=add(ans,mult(sum,dpr[l+1]));
	}
	swap(U,L); swap(R,D); swap(n,m);
	sud="";
	for(int i=0;i<U.length();i++) sud+=char('0'+((U[i]-'0')&(D[i]-'0')));
	calcL(L); calcR(R); calcU(U); calcD(D); calcUD(sud);
	for(int l=0;l<m;l++)
	{
		int ltot=sumL(0,n-1);
		int c1=sumU(0,l-1);
		int c2=sumD(0,l-1);
		if(l==0) dpl[l]=1;
		else dpl[l]=choose(c1+c2-1+ltot,c1+c2);
	}
	for(int r=0;r<m;r++)
	{
		int ltot=sumR(0,n-1);
		int c1=sumU(r+1,m-1);
		int c2=sumD(r+1,m-1);
		if(r==m-1) dpr[r]=1;
		else dpr[r]=choose(c1+c2-1+ltot,c1+c2);
	}
	for(int l=0;l<m;l++)
	{
		int r=l;
		int coeff = mult(pow2[sumUD(l+1,r-1)],((U[l]=='1')+(D[l]=='1'))*(l==r?1:((U[r]=='1')+(D[r]=='1'))));
		if(coeff==0) continue;
		int res1=dpl[l];
		int res2=dpr[r];
		ans=add(ans,mult(coeff,mult(res1,res2)));
	}
	for(int l=0;l<m;l++)
	{
		dpl[l]=mult(dpl[l],ipow2[prefUD[l]]);
		dpl[l]=mult(dpl[l],(U[l]=='1')+(D[l]=='1'));
	}
	for(int r=0;r<m;r++)
	{
		dpr[r]=mult(dpr[r],pow2[(r>0?prefUD[r-1]:0)]);
		dpr[r]=mult(dpr[r],(U[r]=='1')+(D[r]=='1'));
	}
	sum=0;
	for(int l=0;l+1<m;l++)
	{
		//solve for all r>l
		sum=add(sum,dpl[l]);
		ans=add(ans,mult(sum,dpr[l+1]));
	}
	cout<<ans<<'\n';
}


Measured memory_bytes: 14544