#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <sstream>
#include <set>
#include <map>
#include <vector>
#include <list>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <string>
#include <stack>
#include <queue>
#include <bitset>     //UWAGA - w czasie kompilacji musi byc znany rozmiar wektora - nie mozna go zmienic
#include <cassert>
#include <iomanip>        //do setprecision
#include <ctime>
#include <complex>
using namespace std;

#define FOR(i,b,e) for(int i=(b);i<(e);++i)
#define FORQ(i,b,e) for(int i=(b);i<=(e);++i)
#define FORD(i,b,e) for(int i=(b)-1;i>=(e);--i)
#define REP(x, n) for(int x = 0; x < (n); ++x)

#define ST first
#define ND second
#define PB push_back
#define PF push_front
#define MP make_pair
#define LL long long
#define ULL unsigned LL
#define LD long double
#define pii pair<int,int>
#define pll pair<LL,LL>

const double pi = 3.14159265358979323846264;
const int mod=1000000007;


//mod演算ライブラリ
//mod=1000000007

LL add(LL a,LL b){
  return (a+b)%mod;
}

LL sub(LL a,LL b){
  return (a+mod-b)%mod;
}

LL mul(LL a,LL b){
  return ((a % mod) * (b % mod)) % mod;
}

LL power(LL x,LL y){//繰り返し二乗法 単品利用可
  if(y==0)return 1;
  else if(y==1)return x%mod;
  else if(y%2==0){
    LL tmp=power(x, y/2) % mod;
    return tmp*tmp%mod;
  }else {
    LL tmp=power(x, y/2) % mod;
    return ((tmp*tmp)%mod)*x%mod;
  }
}

LL dvs(LL a,LL b){
  return mul(a,power(b,mod-2));
}

const int SIZE_mod=200005;
int invfact[SIZE_mod];
int fact[SIZE_mod];

LL factset(int a){//aまでの階乗%mod表を作成
  fact[0]=1;
  FORQ(i,1,a){
    fact[i]=mul(fact[i-1],i);
  }
}

LL cmbset(int a){//1~aまでの階乗と階乗数の逆元のmod(mod)を用意 O(a)
  factset(a);
  invfact[a]=power(fact[a],mod-2);
  invfact[0]=1;
  FORD(i,a,1){
    invfact[i]=mul(invfact[i+1],i+1);
  }

}

LL cmb(int n,int r){//nCr%mod  (cmbset後に使用)
  if(n<r||r<0||n<0)return 0;
  return mul(fact[n],mul(invfact[r],invfact[n-r]));
}

LL prm(int n,int r){//nPr%mod
    return mul(cmb(n,r),fact[n]);
}

LL homo(int n,int r){//nHr%mod
  return cmb(n+r-1,r);
}


int main(){
	int n,m;
	cin>>n>>m;
	int nm=n*m,lim_mn=m+n-1;
	vector<vector<int>> brd=vector<vector<int>>(n,vector<int>(m,0));
	vector<int> a(n);
	vector<int> b(m);
	vector<int> ncnt(n*m+1,0);
	vector<int> mcnt(n*m+1,0);
	vector<int> nused(n+1,0);
	vector<int> mused(m+1,0);
	map<int,int> nmp;
	map<int,int> mmp;

	FOR(i,0,n){
		cin>>a[i];
		ncnt[a[i]]++;
		if(ncnt[a[i]]>=2){
			cout<<0<<endl;
			return 0;
		}
		nmp[a[i]]=i;
	}
	FOR(i,0,m){
		cin>>b[i];
		mcnt[b[i]]++;
		if(mcnt[b[i]]>=2){
			cout<<0<<endl;
			return 0;
		}
		mmp[b[i]]=i;
	}
	FOR(i,1,lim_mn){
		if(ncnt[i]>=1||mcnt[i]>=1){
			cout<<0<<endl;
			return 0;
		}
	}

	if(!(ncnt[nm]==1&&mcnt[nm]==1)){
		cout<<0<<endl;
		return 0;
	}
	//cerr<<"passed"<<endl;
	LL ans=1;
	int pn=0,pm=0;
	FORD(i,nm+1,1){
		if(ncnt[i]==1&&mcnt[i]==1){
			int ii=nmp[i];
			int jj=mmp[i];
			//nused[ii]++;
			//mused[jj]++;
			pn++;
			pm++;
		}else if(ncnt[i]==1){
			int ii=nmp[i];
			ans=mul(pm,ans);
			//nused[ii]++;
			pn++;
		}else if(mcnt[i]==1){
			int jj=mmp[i];
			ans=mul(pn,ans);
			//mused[jj]++;
			pm++;
		}else{
			int already=nm-i;
			ans=mul(ans,pn*pm-already);
		}
	}
	cout<<ans<<endl;


	return 0;
}


Measured memory_bytes: 12160