#include<iostream>
#include<vector>
#include<algorithm>
#include<functional>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<unordered_map>
#include<climits>
#include<cstdlib>
#include<cmath>
#include<string>
#include<iomanip>
#include<bitset>

using namespace std;

#define ll long long int

ll const MOD = 1000000007;
ll const INF = (long long int)1 << 61;

#include<vector>

class Combination{
    long long int maxn;
    long long int mod;
    std::vector<long long int> factorial;
    std::vector<long long int> inverse;

    public:

    Combination(long long int n,long long int m):maxn(n),mod(m){
        factorial.push_back(1);
        inverse.push_back(1);

        for(long long int i = 1; i <= n; i++){
            factorial.push_back((factorial.back()*i)%mod);
            inverse.push_back([&](long long int x,long long int n) -> long long int{
                long long int ret = 1;
                while(n > 0){
                    if(n&1)ret = (ret*x)%mod;
                    x = (x*x)%mod;
                    n >>= 1;
                }
                return ret;
            }(factorial.back(),mod-2));
        }
    }

    long long int getFactorial(int idx){
        if(idx > maxn || idx < 0)return -1;
        return factorial[idx];
    }

    long long int getInverse(int idx){
        if(idx > maxn || idx < 0)return -1;
        return inverse[idx];
    }

    long long int comb(long long int n,long long int r){
        return (((factorial[n]*inverse[n-r])%mod)*inverse[r])%mod;
    }
};

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    
    ll n,m;
    cin >> n >> m;

    vector<ll> a(n);
    vector<ll> b(m);
    for(int i = 0; i < n; i++){
        cin >> a[i];
    }
    for(int i = 0; i < m; i++){
        cin >> b[i];
    }

    bool check = true;
    vector<ll> c = a;
    vector<ll> d = b;
    sort(c.begin(),c.end());
    sort(d.begin(),d.end());
    for(int i = 0; i < n-1; i++){
        if(c[i] == c[i+1]){
            check = false;
        }
    }
    for(int i = 0; i < m-1; i++){
        if(c[i] == c[i+1]){
            check = false;
        }
    }

    if(!check){
        cout << 0 << endl;
        return 0;
    }

    vector<bool> used(n*m+1,false);
    ll total = 0;
    vector<ll> row(n,m);
    vector<ll> colomn(m,n);
    vector<bool> h(n,false);
    vector<bool> w(m,false);

    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            if(a[i] == b[j]){
                used[a[i]] = true;
                total--;
                h[i] = w[j] = true;
            }
        }
    }

    ll ans = 1;

    Combination cb = Combination(n*m+1,MOD);

    for(int i = 0; i < n; i++){
        ll t = 0;
        if(h[i])continue;
        for(int j = 0; j < m; j++){
            if(a[i] < b[j]){
                t++;
            }
        }
        ans *= t;
        ans %= MOD;
        total--;
        used[a[i]] = true;
    }
    for(int i = 0; i < m; i++){
        ll t = 0;
        if(w[i])continue;
        for(int j = 0; j < n; j++){
            if(b[i] < a[j]){
                t++;
            }
        }
        ans *= t;
        ans %= MOD;
        total--;
        used[b[i]] = true;
    }

    vector<ll> y;
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            y.push_back(min(a[i],b[j]));
        }
    }

    sort(y.begin(),y.end());

    ll na = 0;

    for(int i = n*m; i > 0; i--){
        if(used[i]){
            na++;
            continue;
        }
        auto itr = lower_bound(y.begin(),y.end(),i);
        if(y.end() - itr -na < 0){
            cout << 0 << endl;
            return 0;
        }
        ans *= (ll)(y.end() - itr) - na;
        ans %= MOD;
        na++;
    }

    cout << ans << endl;
    
    return 0;
}

Measured memory_bytes: 30036