#include "bits/stdc++.h"
using namespace std;

// fundamental
using ll = long long;
#define REP(i,n) for (ll i = 0; i < (n); ++i)
#define FOR(i,s,n) for (ll i = (s); i < (n); ++i)
#define ALL(c) (c).begin(), (c).end()
#define TEN(x) ((ll)1e##x)
#define MAXC(c,x) (c = max(c, x))
#define MINC(c,x) (c = min(c, x))
const ll mod = TEN(9) + 7;

// vector
using vl = vector<ll>; using vvl = vector<vl>; using vvvl = vector<vvl>;
template<class T, size_t N, class A = size_t> auto mdv(A size = 0) -> typename enable_if<N==1, vector<T>>::type { return vector<T>(size); }
template<class T, size_t N, class A = size_t> auto mdv(A size = 0) -> vector<decltype(mdv<T, N - 1>())> { return vector<decltype(mdv<T, N - 1>())>(size); }
template<class T, size_t N, class A, class... B> auto mdv(A size, B... rest) -> typename enable_if<N!=1, vector<decltype(mdv<T, N - 1>(rest...))>>::type { return vector<decltype(mdv<T, N - 1>(rest...))>(size, mdv<T, N - 1>(rest...)); }
template<class T, class... A> auto mdv(A... size) -> decltype(mdv<T, sizeof...(size), A...>(size...)) { return mdv<T, sizeof...(size), A...>(size...); }
// template<size_t N, class A, class... B> auto mdvl(A size, B... rest) -> decltype(mdv<N, ll, A, B...>(size, rest...)) { return mdv<N, ll, A, B...>(size, rest...); }

// template<class T, class A> auto mdv(A size) -> vector<T> { return vector<T>(size); }
// template<class T, class A, class... B> auto mdv(A size, B... rest) -> vector<decltype(mdv<T>(rest...))> { return vector<decltype(mdv<T>(rest...))>(size, mdv<T>(rest...)); }

// io
template<class T> istream& operator >>(istream& is, vector<T>& vec){ for(T& x: vec) is >> x; return is; }
template<class T, class U> istream& operator >>(istream& is, pair<T, U>& p){ is >> p.first >> p.second; return is; }
template<class T> void input(T& t) { cin >> t; assert(cin); } template<class T, class... Ts> void input(T& t, Ts&... ts) { cin >> t; input(ts...); }
template<class T> void print(T&& t) { cout << t; } template<class T, class... Ts> void print(T&& t, Ts&&... ts) { cout << t; print(ts...); }
template<class T> void println(T&& t) { cout << t << endl; } template<class T, class... Ts> void println(T&& t, Ts&&... ts) { cout << t; println(ts...); }
template<class T> string join(const vector<T>& v, const string & sep) { stringstream ss; REP(i, v.size()) ss << (i != 0 ? sep : "") << v[i]; return ss.str(); }

template<int64_t mod> struct GF {
	typedef int64_t T;
	T v;
	GF() = default;
	GF(T v) : v((v % mod + mod) % mod) {}
	GF & operator+=(GF x) { v = (v + x.v) % mod; return *this; }
	GF & operator*=(GF x) { v = (v * x.v) % mod; return *this; }
	GF & operator-=(GF x) { v = (v - x.v + mod) % mod; return *this; }
	GF & operator/=(GF x) { return (*this) *= x.inverse(); }
	GF operator+(GF rhs) const { GF lhs = *this; return lhs += rhs; }
	GF operator*(GF rhs) const { GF lhs = *this; return lhs *= rhs; }
	GF operator-(GF rhs) const { GF lhs = *this; return lhs -= rhs; }
	GF operator/(GF rhs) const { GF lhs = *this; return lhs /= rhs; }
	GF inverse() const { // http://topcoder.g.hatena.ne.jp/iwiwi/20130105/1357363348
		T a = v, b = mod, x = 1, y = 0;
		while (b) {
			T t = a / b;
			swap(a -= t * b, b);
			swap(x -= t * y, y);
		}
		return x;
	}
	GF pow(T n) const {
		GF r; r.v = 1;
		for (T x = v; n > 0; n >>= 1) {
			if (n & 1) (r.v *= x) %= mod;
			(x *= x) %= mod;
		}
		return r;
	}
	typedef size_t U;
	static GF fact(U n) {
		static vector<GF> data;
		U m = data.size();
		if (m <= n) {
			data.resize(n + 1);
			if (m == 0) { data[0].v = 1; m++; }
			for (U i = m; i < n + 1; ++i) data[i] = data[i - 1] * i;
		}
		return data[n];
	}
	static GF nCr(U n, U r) { return fact(n) / fact(r) / fact(n - r); }
	static GF nPr(U n, U r) { return fact(n) / fact(r); }
};

int main() {
    cin.tie(0);
    ios_base::sync_with_stdio(false);
    cout << fixed << setprecision(50);
    
    ll n, m; cin >> n>> m;
    vl a(n), b(m);
    REP(i, n) cin >> a[i];
    REP(i, m) cin >> b[i];
    sort(ALL(a));
    sort(ALL(b));
    REP(i, n - 1) if (a[i] == a[i + 1]) {
        cout << 0 << endl;
        return 0;
    }
    REP(i, m - 1) if (b[i] == b[i + 1]) {
        cout << 0 << endl;
        return 0;
    }

    GF<mod> ans = 1;
    ll cnt = 0;
    ll i = 0, j = 0;
    while (cnt < n * m) {
        if (a[i] == b[j]) {
            if (a[i] - 1 - cnt < (n - i - 1) + (m - j - 1)) {
                cout << 0 << endl;
                return 0;
            }
            ans *= GF<mod>::nCr(a[i] - 1 - cnt, (n - i - 1) + (m - j - 1));
            ans *= GF<mod>::fact((n - i - 1) + (m - j - 1));
            cnt += (n - i - 1) + (m - j - 1) + 1;
            i++;
            j++;
        } else if (a[i] < b[j]) {
            if (a[i] - 1 - cnt < m - j - 1) {
                cout << 0 << endl;
                return 0;
            }
            ans *= GF<mod>::nCr(a[i] - 1 - cnt, m - j - 1);
            ans *= GF<mod>::fact(m - j);
            cnt += m - j;
            i++;
        } else {
            if (b[j] - 1 - cnt < n - i - 1) {
                cout << 0 << endl;
                return 0;
            }
            ans *= GF<mod>::nCr(b[j] - 1 - cnt, n - i - 1);
            ans *= GF<mod>::fact(n - i);
            cnt += n - i;
            j++;
        }
    }

    cout << ans.v << endl;
}


Measured memory_bytes: 17664