/**
 * code generated by JHelper
 * More info: https://github.com/AlexeyDmitriev/JHelper
 * @author
 */

#include <bits/stdc++.h>
#define FOR(i, a, b) for(int (i)=(a);(i)<(b);++(i))
#define REP(i, n) FOR(i, 0, n)
#define RREP(i, n) FOR(i, 1, n+1)
#define ALL(v) (v).begin(), (v).end()
#define RALL(v) (v).rbegin(), (v).rend()
#define LEN(x) (int)(x).size()
#define DUMP(x) cout<<#x<<"="<<(x)<<endl;
#define pb push_back
#define eb emplace_back
using namespace std;
typedef long long lint;
typedef pair<int, int> pii;
typedef pair<lint, lint> pll;
typedef vector<int> vi;
typedef vector<lint> vl;
typedef vector<char> vc;
typedef vector<vector<int>> vii;
typedef vector<vector<lint>> vll;
typedef vector<vector<char>> vcc;

template <typename T> inline bool chmax(T &a, T b){if(a<b){a = b; return true;} return false;}
template <typename T> inline bool chmin(T &a, T b){if(a>b){a = b; return true;} return false;}

const lint MOD = (lint)1e9 + 7;

struct mint {
    lint x;
    mint(lint x=0):x((x%MOD+MOD)%MOD){}
    mint& operator+=(const mint a) {
        if ((x += a.x) >= MOD) x -= MOD;
        return *this;
    }
    mint& operator-=(const mint a) {
        if ((x += MOD-a.x) >= MOD) x -= MOD;
        return *this;
    }
    mint& operator*=(const mint a) {
        (x *= a.x) %= MOD;
        return *this;
    }
    mint operator+(const mint a) const {
        mint res(*this);
        return res+=a;
    }
    mint operator-(const mint a) const {
        mint res(*this);
        return res-=a;
    }
    mint operator*(const mint a) const {
        mint res(*this);
        return res*=a;
    }
    mint pow(lint t) const {
        if (!t) return 1;
        mint a = pow(t>>1);
        a *= a;
        if (t&1) a *= *this;
        return a;
    }
    mint inv() const {
        return pow(MOD-2);
    }
    mint& operator/=(const mint a) {
        return (*this) *= a.inv();
    }
    mint operator/(const mint a) const {
        mint res(*this);
        return res/=a;
    }
    friend ostream& operator<<(ostream& out, const mint& a){
        return out<<a.x;
    }
};

typedef vector<mint> vm;
typedef vector<vector<mint>> vmm;


class DDoubleLandscape {
public:
    int N, M;
    vl A, B;

    void input(std::istream& in, std::ostream& out){
        ios_base::sync_with_stdio(false);
        in>>N>>M;
        A = vl(N*M+1, 0), B = vl(N*M+1, 0);
        REP(i, N){
            int a;
            in>>a;
            a--;
            A[a]++;
        }
        REP(i, M){
            int b;
            in>>b;
            b--;
            B[b]++;
        }
    }

    void solve(std::istream& in, std::ostream& out){
        input(in, out);
        mint ans = 1;
        for(int i=N*M-1;0<=i;i--){
            if(A[i]>1 or B[i]>1){
                out<<"0\n";
                return;
            }else if(A[i]==1 and B[i]==1){
                A[i] += A[i+1], B[i] += B[i+1];
                continue;
            }else if(A[i]==1 and B[i]==0){
                ans *= B[i+1];
                A[i] += A[i+1], B[i] += B[i+1];
            }else if(A[i]==0 and B[i]==1){
                ans *= A[i+1];
                A[i] += A[i+1], B[i] += B[i+1];
            }else{
                A[i] += A[i+1], B[i] += B[i+1];
                ans *= A[i] * B[i] - N * M + i + 1;
            }
        }
        out<<ans<<'\n';
    }
};


int main() {
	DDoubleLandscape solver;
	std::istream& in(std::cin);
	std::ostream& out(std::cout);
	solver.solve(in, out);
	return 0;
}


Measured memory_bytes: 15872