#include <bits/stdc++.h>
using ll = long long;
using namespace std;
#define rep(i, n) for (int i = 0, i##_len = (int)(n); i < i##_len; i++)
#define reps(i, n) for (int i = 1, i##_len = (int)(n); i <= i##_len; i++)
#define rrep(i, n) for (int i = ((int)(n)-1); i >= 0; i--)
#define rreps(i, n) for (int i = ((int)(n)); i > 0; i--)
#define repi(i, x) \
	for (auto i = (x).begin(), i##_fin = (x).end(); i != i##_fin; i++)
#define all(x) (x).begin(), (x).end()
#define F first
#define S second
#define mp make_pair
#define mt make_tuple
#define pb push_back
#define eb emplace_back
string solve(bool a) { return ((a) ? "Yes" : "No"); }
typedef vector<int> Vi;
typedef vector<Vi> VVi;
typedef pair<int, int> Pi;
typedef vector<Pi> VPi;
typedef vector<long long> V;
typedef vector<V> VV;
typedef pair<long long, long long> P;
typedef vector<P> VP;
template <class T>
inline bool chmax(T& a, T b) {
	if (a < b) {
		a = b;
		return 1;
	}
	return 0;
}
template <class T>
inline bool chmin(T& a, T b) {
	if (a > b) {
		a = b;
		return 1;
	}
	return 0;
}
template <class T, class U>
ostream& operator<<(ostream& os, const pair<T, U>& p) {
	os << "(" << p.first << "," << p.second << ")";
	return os;
}
template <class T>
ostream& operator<<(ostream& os, const vector<T>& v) {
	os << "{";
	rep(i, v.size()) {
		if (i) os << ",";
		os << v[i];
	}
	os << "}";
	return os;
}
template <class T, class U>
istream& operator>>(istream& is, pair<T, U>& p) {
	is >> p.first >> p.second;
	return is;
}
template <class T>
istream& operator>>(istream& is, vector<T>& v) {
	rep(i, v.size()) { is >> v[i]; }
	return is;
}
const long long INFLL = 1LL << 60;
const int INF         = 1 << 30;
const double PI       = acos(-1);

int main() {
	int n;
	string s;
	ll ans = 0LL;
	cin >> n >> s;
	vector<string> dis1, dis2;
	string bef = "";
	for (int bit = 0; bit < (1 << n); bit++) {
		bef = "";
		for (int i = 0; i < n; i++) {
			if (bit & (1 << i)) {
				bef += s[i];
			}
		}
		bef += '0';
		for (int i = n - 1; i >= 0; i--) {
			if ((bit & (1 << i)) == 0) {
				bef += s[i];
			}
		}
		dis1.pb(bef);
		// clog << bef << endl;
		bef = "";
		//--------//

		for (int i = n - 1; i >= 0; i--) {
			if ((bit & (1 << i)) == 0) {
				bef += s[i + n];
			}
		}
		bef += '0';
		for (int i = 0; i < n; i++) {
			if (bit & (1 << i)) {
				bef += s[i + n];
			}
		}

		dis2.pb(bef);
		//	clog << bef << endl;
	}
	sort(all(dis1));
	sort(all(dis2));
	repi(i,dis1){
		ans +=
		    distance(lower_bound(all(dis2), *i), upper_bound(all(dis2), *i) );
	//	clog << ans << endl;
	}
	cout << ans << endl;
}
/*
半分全挙列
chose red; head last: blue
chose bule: head last: red

top!= head: rr- bb- -> 2n:: n
2^n * log(n^2)


cabaacba = caba \ acba
c  -> /  aba ->
aba   <-/ <- c
== c aba   /  c aba
ab  ->/ ac
ca <-/ ba
== ab ac / ab ac
*/
#include <bits/stdc++.h>
#define owo(i,a, b) for(int i=(a);i<(b); ++i)
#define uwu(i,a, b) for(int i=(a)-1; i>=(b); --i)
#define senpai push_back
#define ttgl pair<int, int>
#define ayaya cout<<"ayaya~"<<endl
 
using namespace std;
/*#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
gpu_hash_map<int, int> mp;*/
using ll = long long;
using ld = long double;
const ll MOD = 1000000007;
const ll root = 62;
int gcd(int a,int b){return b?gcd(b,a%b):a;}
ll binpow(ll a,ll b){ll res=1;while(b){if(b&1)res=(res*a)%MOD;a=(a*a)%MOD;b>>=1;}return res;}
ll modInv(ll a){return binpow(a, MOD-2);}
const double PI = acos(-1);
const double eps = -1e6;
const int INF = 0x3f3f3f3f;
const int NINF = 0xc0c0c0c0;
const ll INFLL = 0x3f3f3f3f3f3f3f3f;
const ll NINFLL = 0xc0c0c0c0c0c0c0c0;
const int mxN = 1001;
ll arr[mxN];
ll b[mxN];
int cnt[mxN*mxN];
ll n, m;
int main() {
    //freopen("file.in", "r", stdin);
    //freopen("file.out", "w", stdout);
    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
    cin.tie(0)->sync_with_stdio(0);
    cin>>n>>m;
    owo(i, 0, n) {
        cin>>arr[i];
        cnt[arr[i]]++;
        if(cnt[arr[i]]>1) {
            cout<<"0\n";
            exit(0);
        }
    }
    memset(cnt, 0, sizeof(cnt));
    owo(i, 0, m) {
        cin>>b[i];
        cnt[b[i]]++;
        if(cnt[b[i]]>1) {
            cout<<"0\n";
            exit(0);
        }
    }
    ll ans = 1;
    sort(arr, arr+n);
    sort(b, b+m);
    reverse(arr, arr+n);
    reverse(b, b+m);
    ll aidx = 0;
    ll bidx = 0;
    for(ll nxt=n*m; nxt>0; --nxt) {
        while(aidx<n&&arr[aidx]>=nxt)aidx++;
        while(bidx<m&&b[bidx]>=nxt)bidx++;
        if(arr[aidx-1]==nxt&&b[bidx-1]==nxt) {
            ans = (ans*1LL)%MOD;
        }else if(arr[aidx-1]==nxt) {
            ans = (ans * bidx)%MOD;
        }else if(b[bidx-1]==nxt) {
            ans = (ans * aidx)%MOD;
        }else {
            ans = (ans * max((aidx * bidx - n * m + nxt), 0LL))%MOD;
        }
    }
    cout<<ans<<"\n";
    return 0;
}