#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
#include <tuple>
#include <queue>
#include <bitset>
#include <unordered_map>
#include <tuple>
#include <utility>
#include <cmath>
#include <algorithm>
#include <numeric>
#include <sys/time.h>

using namespace std;

long long mod = 1000000007LL;
vector<long long> fact;
vector<long long> factinv;

void initfact(long long n) {
  fact.push_back(1LL);
  for (int i = 1; i < n+1; i++) {
    fact.push_back((fact.back()*static_cast<long long>(i))%mod);
  }
}

long long sqr(long long n) {
  return static_cast<long long>(n)*n%mod;
}

long long bipow(long long c, long long n) {
  if (n == 0) {
    return 1;
  } else if(n == 1) {
    return c;
  } else if(n%2 == 0) {
    return sqr(bipow(c, n/2))%mod;
  } else {
    return (static_cast<long long>(c)*sqr(bipow(c, (n-1)/2)))%mod;
  }
}

void initfactinv() {
  factinv.push_back(bipow(fact.back(), mod-2));
  for (int i = fact.size()-1; i > 0; i--) {
    factinv.push_back((factinv.back()*static_cast<long long>(i))%mod);
  }
  reverse(factinv.begin(), factinv.end());
}

long long C(long long n, long long m) {
  if (n < m) {
    return 0;
  }
  return (((static_cast<long long>(fact[n])*factinv[m])%mod)*factinv[n-m])%mod;
}

void solve(long long N, long long M, vector<long long> A, vector<long long> B){
  initfact(N*M+1);
  initfactinv();
  sort(A.begin(), A.end());
  sort(B.begin(), B.end());
  for (int i = 0; i < N-1; i++) {
    if (A[i] == A[i+1]) {
      std::cout << 0 << std::endl;
      return;
    }
  }
  for (int i = 0; i < M-1; i++) {
    if (B[i] == B[i+1]) {
      std::cout << 0 << std::endl;
      return;
    }
  }
  long long idx_a = 0;
  long long idx_b = 0;
  long long prev = 0;
  long long rest = 0;
  long long ret = 1;
  long long ms = 0;
  for (int i = 0; i < N+M; i++) {
    if (idx_a >= N) {
      rest += B[idx_b] - prev - 1;
      ms = N - idx_a - 1;
      if (rest - ms < 0) {
        std::cout << 0 << std::endl;
        return;
      }
      ret *= ms + 1;
      ret %= mod;
      ret *= (fact[rest] * factinv[rest-ms]) % mod;
      ret %= mod;
      rest -= ms;
      prev = B[idx_b];
      idx_b++;
    } else if (idx_b >= M) {
      rest += A[idx_a] - prev - 1;
      ms = M - idx_b - 1;
      if (rest - ms < 0) {
        std::cout << 0 << std::endl;
        return;
      }
      ret *= ms + 1;
      ret %= mod;
      ret *= (fact[rest] * factinv[rest-ms]) % mod;
      ret %= mod;
      rest -= ms;
      prev = A[idx_a];
      idx_a++;
    } else if (A[idx_a] == B[idx_b]) {
      rest += A[idx_a] - prev - 1;
      ms = (N - idx_a) + (M - idx_b) - 2;
      if (rest - ms < 0) {
        std::cout << 0 << std::endl;
        return;
      }
      ret *= (fact[rest] * factinv[rest-ms]) % mod;
      ret %= mod;
      i++;
      rest -= ms;
      prev = A[idx_a];
      idx_a++;
      idx_b++;
    } else {
      if (A[idx_a] < B[idx_b]) {
        rest += A[idx_a] - prev - 1;
        ms = M - idx_b - 1;
        if (rest - ms < 0) {
          std::cout << 0 << std::endl;
          return;
        }
        ret *= ms + 1;
        ret %= mod;
        ret *= (fact[rest] * factinv[rest-ms]) % mod;
        ret %= mod;
        rest -= ms;
        prev = A[idx_a];
        idx_a++;
      } else {
        rest += B[idx_b] - prev - 1;
        ms = N - idx_a - 1;
        if (rest - ms < 0) {
          std::cout << 0 << std::endl;
          return;
        }
        ret *= ms + 1;
        ret %= mod;
        ret *= (fact[rest] * factinv[rest-ms]) % mod;
        ret %= mod;
        rest -= ms;
        prev = B[idx_b];
        idx_b++;
      }
    }
  }
  std::cout << ret << std::endl;
}

int main(){
  long long N;
  long long M;
  scanf("%lld",&N);
  vector<long long> A(N);
  scanf("%lld",&M);
  vector<long long> B(M);
  for(int i = 0 ; i < N ; i++){
    scanf("%lld",&A[i]);
  }
  for(int i = 0 ; i < M ; i++){
    scanf("%lld",&B[i]);
  }
  solve(N, M, A, B);
  return 0;
}


Measured memory_bytes: 22764