#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
typedef pair<ll, ll> PLL;
#define chmax(x, y) do { x = max(x, y); } while(0)
#define chmin(x, y) do { x = min(x, y); } while(0)
#define _overload3(_1, _2, _3, name, ...) name
#define _rep(i, n) repi(i, 0, n)
#define repi(i, a, b) \
  for (ll i = static_cast<ll>(a); i < static_cast<ll>(b); ++i)
#define rep(...) _overload3(__VA_ARGS__, repi, _rep, ) (__VA_ARGS__)  // NOLINT
template<typename T>
using reversed_priority_queue = std::priority_queue<T, std::vector<T>, std::greater<T> >;

// {{{ Modint
// using mint = modint<1000000007>;
// mint x = 2;
// std::cout << x.a << std::endl;
template <std::int64_t M>
class modint {
 public:
  int64_t a;

  explicit constexpr modint(const int64_t x = 0) noexcept :
    a((x % M + M) % M) {}
  constexpr int64_t &value() noexcept { return a; }
  constexpr const int64_t &value() const noexcept { return a; }
  constexpr modint operator+(const modint rhs) const noexcept {
    return modint(*this) += rhs;
  }
  constexpr modint operator-(const modint rhs) const noexcept {
    return modint(*this) -= rhs;
  }
  constexpr modint operator*(const modint rhs) const noexcept {
    return modint(*this) *= rhs;
  }
  constexpr modint operator/(const modint rhs) const noexcept {
    return modint(*this) /= rhs;
  }
  constexpr modint &operator+=(const modint rhs) noexcept {
    a += rhs.a;
    if (a >= M) {
      a -= M;
    }
    return *this;
  }
  constexpr modint &operator-=(const modint rhs) noexcept {
    if (a < rhs.a) {
      a += M;
    }
    a -= rhs.a;
    return *this;
  }
  constexpr modint &operator*=(const modint rhs) noexcept {
    a = a * rhs.a % M;
    return *this;
  }
  constexpr modint &operator/=(modint rhs) noexcept {
    int64_t exp = M - 2;
    while (exp) {
      if (exp % 2) {
        *this *= rhs;
      }
      rhs *= rhs;
      exp /= 2;
    }
    return *this;
  }
  constexpr modint pow(ll t) const {
    if (!t) return modint(1);
    modint a = pow(t>>1);
    a *= a;
    if (t&1) a *= *this;
    return a;
  }
};
// }}}
using mint = modint<1000000007>;

signed main() {
  ll N, M;
  cin >> N >> M;
  set<ll> sa, sb;
  vector<ll> a, b;
  rep(i, N) {
    ll val;
    cin >> val;
    if (sa.find(val) != sa.end()) {
      cout << 0 << endl;
      return 0;
    }
    sa.insert(val);
    a.push_back(val);
  }
  rep(i, M) {
    ll val;
    cin >> val;
    if (sb.find(val) != sb.end()) {
      cout << 0 << endl;
      return 0;
    }
    sb.insert(val);
    b.push_back(val);
  }
  sort(begin(a), end(a));
  sort(begin(b), end(b));

  mint ans(1);
  for (ll val = N * M; val >= 1; val--) {
    auto it = lower_bound(begin(a), end(a), val);
    auto jt = lower_bound(begin(b), end(b), val);
    if (*it == val && *jt == val) {
      ans = ans * mint(1);
    } else if (*it == val) {
      mint d(distance(jt, b.end()));
      ans = ans * d;
    } else if (*jt == val) {
      mint d(distance(it, a.end()));
      ans = ans * d;
    } else {
      ll dx = (distance(it, a.end()));
      ll dy = (distance(jt, b.end()));
      ll d = dx * dy - (N * M - val);
      if (d <= 0)
        d = 0;
      ans = ans * mint(d);
    }
  }
  cout << ans.value() << endl;
  return 0;
}


Measured memory_bytes: 384