#include <bits/stdc++.h>
#define FOR(i, begin, end) for(int i=(begin);i<(end);i++)
#define REP(i, n) FOR(i,0,n)
#define IFOR(i, begin, end) for(int i=(end)-1;i>=(begin);i--)
#define IREP(i, n) IFOR(i,0,n)
#define SORT(a) sort(a.begin(), a.end())
#define REVERSE(a) reverse(a.begin(), a.end())
#define Lower_bound(v, x) distance(v.begin(), lower_bound(v.begin(), v.end(), x))
#define Upper_bound(v, x) distance(v.begin(), upper_bound(v.begin(), v.end(), x))
#define int long long
#define INF 1000000000000000000
using namespace std;

#define ANS(f) if(f) cout << "YES" << endl; else cout << "NO" << endl;

typedef vector<int> vec;
typedef vector<vec> mat;
typedef pair<int, int> Pii;

template<typename T>
void readv(vector<T> &a){ REP(i, a.size()) cin >> a[i]; }
void readi(vector<int> &a){ REP(i, a.size()){cin >> a[i]; a[i]--;} }
void debug(mat m){REP(i, m.size()){ REP(j, m[i].size()){ cout << m[i][j] << ","; } cout << endl; }}

int modpow(int x, int n, int m){
    int a = 1;
    IREP(i, 64){
        a = (a * a) % m;
        if(((n >> i) & 1) == 1) a = (a * x) % m;
    }
    return a;
}

class Combination
{
public:

    vec fact, invfact;
    int MAX_N, mod;

    Combination(int MAX_N, int mod): MAX_N(MAX_N), mod(mod) {
        initialize();
    }

    void initialize(){
        fact = vec(MAX_N + 1);
        invfact = vec(MAX_N + 1);
        fact[0] = 1;
        FOR(i, 1, MAX_N + 1){
            fact[i] = (fact[i - 1] * i) % mod;
        }
        invfact[MAX_N] = modpow(fact[MAX_N], mod - 2, mod);
        IREP(i, MAX_N){
            invfact[i] = (invfact[i + 1] * (i + 1)) % mod;
        }
    }

    int nCr(int n, int r){
        if(r > n || r < 0 || n < 0) return 0;
        if(n > MAX_N){
            MAX_N = n;
            initialize();
        }
        int a = fact[n];
        a = (a * invfact[r]) % mod;
        a = (a * invfact[n - r]) % mod;
        return a;
    }
};

signed main(){

    int N, M; cin >> N >> M;
    vec A(N), B(M);
    readv(A), readv(B);
    int n = 0, m = 0;
    
    SORT(A);
    SORT(B);
    REP(i, N - 1){
        if(A[i] == A[i + 1]){
            cout << 0;
            return 0;
        }
    }
    REP(i, M - 1){
        if(B[i] == B[i + 1]){
            cout << 0;
            return 0;
        }
    } 

    vector<Pii> p(N + M);
    REP(i, N) p[i] = Pii(A[i], 0);
    REP(i, M) p[i + N] = Pii(B[i], 1);
    SORT(p);

    int mod = 1000000007;
    Combination comb(N + M + 10, mod);

    int ans = 1;
    int u = 0;

    int i = 0;
    while(i < N + M){
        if(i != N * M - 1 && p[i].first == p[i + 1].first){
            int v = p[i].first;
            int tmp = N - n + M - m - 1;
            ans *= (comb.fact[tmp - 1] * comb.nCr(v - 1 - u, tmp - 1)) % mod;
            u += tmp;
            n++;
            m++;
            i += 2;
            //cout << "a:";
        }else{
            int v = p[i].first;
            int d = p[i].second;
            if(d == 0){
                ans *= (comb.fact[M - m] * comb.nCr(v - 1 - u, M - m - 1)) % mod;
                u += M - m;
                n++;
            }else{
                ans *= (comb.fact[N - n] * comb.nCr(v - 1 - u, N - n - 1)) % mod;
                u += N - n;
                m++;
            }
            i++;
            //cout << "b:";
        }
        ans %= mod;
        //cout << ans << endl;
    }
    cout << ans;

    return 0;
}

Measured memory_bytes: 23552