#include <iostream>
#include <fstream>
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <string>
#include <tuple>
#include <vector>
#include <map>
#include <unordered_map>
#include <list>
#include <set>
#include <stack>
#include <queue>
#include <cstdlib>
#include <algorithm>
#include <random>
#include <cassert>
using namespace std;
#define LL long long
#define MP(a, b) make_pair(a, b)
#define MAX 1000000000
#undef INT_MIN
#undef INT_MAX
#define INT_MIN -2147483647
#define INT_MAX 2147483647
#define LL_MIN (LL)-9223372036854775807
#define LL_MAX (LL)9223372036854775807
#define PI 3.14159265359
/*
int main(){
    ios::sync_with_stdio(false);

    int N,D;
    cin >> N >> D;
    int A[200000];
    LL cost[200000];
    for(int i=0; i<N; i++){
        cin >> A[i];
        cost[i] = LL_MAX;
    }
    cost[0] = 0;

    priority_queue<pair<LL,int> > que;
    que.push(MP(LL_MAX, 0));
    while(!que.empty()){
        int now = que.top().second;
        int c = LL_MAX - que.top().first;
        for(int i=0; i<N; i++){
            if(i == now) continue;
            if(cost[i] > c + abs(i-now)*D+A[now]+A[i]){
                cost[i] = c + abs(i-now)*D+A[now]+A[i];
                que.push(MP(LL_MAX - cost[i], i));
            }
        }
        que.pop();
    }

    LL ans = 0;
    set<pair<int,int> > s;
    que.push(MP(LL_MAX, 0));
    while(!que.empty()){
        int now = que.top().second;
        int c = LL_MAX - que.top().first;
        for(int i=0; i<N; i++){
            if(i == now) continue;
            if(cost[i] == c + abs(i-now)*D+A[now]+A[i]){
                int a = now;
                int b = i;
                if(i < now) swap(a,b);
                if(s.count(MP(a,b)) == 0){
                    cout << a << " " << b << endl;
                    ans += abs(i-now)*D+A[now]+A[i];
                    s.insert(MP(a,b));
                    que.push(MP(LL_MAX - cost[i], i));
                }
            }
        }
        que.pop();
    }
    cout << ans << endl;

    return 0;
}*/

/*
int N,M;
int A[1000];
int B[1000];

#define MOD 1000000007

int main(){
    iostream::sync_with_stdio(false);
    
    cin >> N >> M;
    for(int i=0; i<N; i++) cin >> A[i];
    for(int i=0; i<M; i++) cin >> B[i];
    sort(A, A+N);
    sort(B, B+M);

    int X = 0;
    int nX = 0;
    int Y = 0;
    int nY = 0;
    LL ans = 1;
    int way = -1;
    int now = 1;
    while(now-1 < N*M){
        if(X == N || Y == M){
            X = nX;
            Y = nY;
            way = -1;
        }
        if(way == -1){
            if(A[X] <= B[Y]){
                way = 0;
                nY++;
            }
            else{
                way = 1;
                nX++;
            }
        }
        else if(way == 0){
            if(A[X] != B[Y]) ans *= max(min(A[X], B[Y]) - now + 1, 0);
            ans %= MOD;
            X++; now++;
        }
        else if(way == 1){
            if(A[X] != B[Y]) ans *= max(min(A[X], B[Y]) - now + 1, 0);
            ans %= MOD;
            Y++; now++;
        }
    }
    cout << ans << endl;
    
    return 0;
}*/



int N,M;
vector<int> A;
vector<int> B;

#define MOD 1000000007

int main(){
    iostream::sync_with_stdio(false);
    
    cin >> N >> M;
    for(int i=0; i<N; i++){
        int tmp;
        cin >> tmp;
        A.push_back(tmp);
    }
    for(int i=0; i<M; i++){
        int tmp;
        cin >> tmp;
        B.push_back(tmp);
    }
    sort(A.begin(), A.end());
    sort(B.begin(), B.end());

    for(int i=1; i<N; i++){
        if(A[i-1] == A[i]){
            cout << 0 << endl;
            return 0;
        }
    }
    for(int i=1; i<M; i++){
        if(B[i-1] == B[i]){
            cout << 0 << endl;
            return 0;
        }
    }

    LL answer = 1;
    for(int i=N*M; i>0; i--){
        auto X = lower_bound(A.begin(), A.end(), i);
        auto Y = lower_bound(B.begin(), B.end(), i);
        if(*X == i && *Y == i) answer *= 1;
        else if(*X == i) answer *= max(0, M-(int)(Y-B.begin()) );
        else if(*Y == i) answer *= max(0, N-(int)(X-A.begin()) );
        else answer *= max(0, (M-(int)(Y-B.begin())) * (N-(int)(X-A.begin())) - (N*M-i) );
        //cout << (M-(int)(Y-B.begin())) << " " << (N-(int)(X-A.begin())) << " " << answer << endl;
        answer %= MOD;
    }
    cout << answer << endl;
    
    return 0;
}

Measured memory_bytes: 256