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

#define rep(i, n) for(int (i) = 0; (i) < (n); (i)++)
#define repn(i, n) for(int (i) = 1; (i) <= (n); (i)++)
#define repr(i, n) for(int (i) = (n-1); (i) >= 0; (i)--)
#define all(x) (x).begin(), (x).end()
#define lint long long
#define ulint unsigned long long
#define fi first
#define se second
#define setpre(x) cout << fixed << setprecision(x)
#define ii(x) int x; cin >> (x)
#define ii2(x, y) int x, y; cin >> (x) >> (y)
#define ii3(x, y, z) int x, y, z; cin >> (x) >> (y) >> (z)
#define out(x) cout << (x) << endl
#define outs(x) cout << (x) << " "
#define yn(x) cout << ((x)?("Yes"):("No")) << endl
#define YN(x) cout << ((x)?("YES"):("NO")) << endl
#define bit_c(x) __builtin_popcountll(x)

inline void logger(){ cout << " [LOGGER] " << endl; }
template<typename A, typename... B>
void logger(const A& a, const B&... b){
    cout << a << " , ";
    logger(b...);
}

typedef pair<double, double> P;
const lint MOD = 1000000007;
const lint MOD9 = 998244353;
const lint INF = MOD * MOD;
const int MAX = 100005;

/* ...o(^-^)o... */
const lint mod = MOD;
class mint{
    public:
        long long x;

    constexpr mint(long long _x = 0) : x((_x%mod+mod)%mod) {}
    constexpr mint operator-() const{
        return mint(-x);
    }
    constexpr mint& operator+=(const mint& a){
        if((x += a.x) >= mod) x -= mod;
        return *this;
    }
    constexpr mint& operator-=(const mint& a){
        if((x += mod-a.x) >= mod) x -= mod;
        return *this;
    }
    constexpr mint& operator*=(const mint& a){
        (x *= a.x) %= mod;
        return *this;
    }
    constexpr mint operator+(const mint& a) const{
        mint res(*this);
        return res+=a;
    }
    constexpr mint operator-(const mint& a) const{
        mint res(*this);
        return res-=a;
    }
    constexpr mint operator*(const mint& a) const{
        mint res(*this);
        return res*=a;
    }
    constexpr mint pow(long long x) const{
        if(!x) return 1;
        mint a = pow(x>>1);
        a *= a;
        if(x&1) a *= *this;
        return a; 
    }
    constexpr mint inv() const{
        return pow(mod-2);
    }
    constexpr mint& operator/=(const mint& a){
        return (*this) *= a.inv();
    }
    constexpr mint& operator/(const mint& a) const{
        mint res(*this);
        return res/=a;
    }
    friend ostream& operator<<(ostream& os, const mint& m){
        os << m.x; return os;
    }
};

int main(){
    int n, m; cin >> n >> m;
    vector<int> a(n), b(m);
    rep(i, n){
        cin >> a[i]; a[i]--;
    }
    rep(i, m){
        cin >> b[i]; b[i]--;
    }
    sort(all(a), greater<int>());
    sort(all(b), greater<int>());

    vector<mint> c(n*m), d(n*m);
    int j = 0, k = 0;
    repr(i, n*m){
        if(i < n*m-1){
            c[i] = c[i+1]; d[i] = d[i+1];
        }
        if(j < n && a[j] == i){
            c[i] += 1;
            j++;
            if(a[j] == a[j-1]){
                out(0); return 0;
            }
        }
        if(k < m && b[k] == i){
            d[i] += 1;
            k++;
            if(b[k] == b[k-1]){
                out(0); return 0;
            }
        }
    }

    mint ans = 1; j = 0; k = 0;
    repr(i, n*m){
        if(j < n && i == a[j] && k < m && i == b[k]){
            j++; k++;
        }
        else if(j < n && i == a[j]){
            ans *= d[i]; j++;
        }
        else if(k < m && i == b[k]){
            ans *= c[i]; k++;
        }
        else{
            ans *= c[i] * d[i] - (n*m - i - 1);
        }
    }
    out(ans);
}

Measured memory_bytes: 15872