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

#include <iostream>
#include <fstream>

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define rep(i, n) for(ll i=0; i<n; i++)
#define repr(i, s, e) for(ll i=s; i>=e; i--)
#define reps(i, s, e) for(ll i=s; i<=e; i++)
#define inf 1e18
#define all(v) v.begin(),v.end()
#define ceill(a, b) (a+b-1)/b
#define ok cout << "ok" << endl;
#define sp << " " <<
ll mod = 1e9+7;
void ans(bool b){ cout << (b ? "Yes" : "No") << endl; }
void ans2(bool b){ cout << (b ? "YES" : "NO") << endl; }
template<typename T> inline bool chmax(T &a, T b){ if(a<b) a=b; return a<b; }
template<typename T> inline bool chmin(T &a, T b){ if(b<a) a=b; return b<a; }
template<typename A, size_t N, typename T>
void Fill(A (&array)[N], const T &val){
    fill((T*)array, (T*)(array+N), val);
}
template<typename T> void vdeb(T v){
    cout << "#vector set debug" << endl;
    for(auto vv : v) cout << vv << " ";
    cout << endl;
}
template<typename T1, typename T2> void adeb(T1 arr[], T2 n){
    cout << "#adebug" << endl;
    for(int i=0; i<=n; i++) cout << arr[i] << " ";
    cout << endl;
}
template<typename T1> void mdeb(T1 mp){
    cout << "#map pair debug" << endl;
    for(auto const& m : mp) cout << m.first sp m.second << endl;
}
int dx[] = {1, 0, -1, 0, 1, -1, 1, -1};
int dy[] = {0, 1, 0, -1, 1, -1, -1, 1};


class DDoubleLandscape {
public:
	void solve(std::istream& in, std::ostream& out) {
        int n, m;
        in >> n >> m;
        vector<int> a(n), b(m);
        vector<int> exist_a(n*m+1, 0);
        rep(i, n){
            in >> a[i];
            if(exist_a[a[i]]){
                out << 0 << endl;
                return;
            }
            exist_a[a[i]] = 1;
        }

        vector<int> exist_b(n*m+1, 0);
        rep(i, m){
            in >> b[i];
            if(exist_b[b[i]]){
                out << 0 << endl;
                return;
            }
            exist_b[b[i]] = 1;
        }

        ll res = 1;
        rep(i, n){
            int cnt = 0;
            bool multi = false;
            rep(j, m){
                if(a[i] == b[j]) multi = true;
                if(a[i] < b[j]) cnt++;
            }
            if(multi) continue;
            res *= cnt;
            res %= mod;
        }

        rep(j, m){
            int cnt = 0;
            bool multi = false;
            rep(i, n){
                if(a[i] == b[j]) multi = true;
                if(b[j] < a[i]) cnt++;
            }
            if(multi) continue;
            res *= cnt;
            res %= mod;
        }

        vector<int> sum(n*m+1, 0);
        rep(i, n){
            rep(j, m){
                sum[min(a[i], b[j])-1]++;
            }
        }
        repr(i, n*m-1, 0){
            sum[i] += sum[i+1];
        }

        repr(i, n*m, 1){
            if(exist_a[i] || exist_b[i]) continue;
            res *= (sum[i] - (n*m-i));
            res %= mod;
        }

        out << res << endl;
	}
};


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


Measured memory_bytes: 12032