import std.stdio, std.array, std.string, std.conv, std.algorithm;
import std.typecons, std.range, std.random, std.math, std.container;
import std.numeric, std.bigint, core.bitop, core.stdc.string;

immutable long MOD = 10^^9 + 7;

void main() {
    auto s = readln.split.map!(to!int);
    auto H = s[0];
    auto W = s[1];
    auto A = readln.split.map!(to!int).array;
    auto B = readln.split.map!(to!int).array;

    int[int] cnta;
    int[int] cntb;
    foreach (a; A) cnta[a] += 1;
    foreach (b; B) cntb[b] += 1;

    if (cnta.values.map!(v => v >= 2).any || cntb.values.map!(v => v >= 2).any) {
        writeln(0);
        return;
    }

    auto AA = H.iota.map!(i => tuple(A[i], i)).array;
    auto BB = W.iota.map!(i => tuple(B[i], i)).array;
    AA.sort!"a > b";
    BB.sort!"a > b";
    auto usedr = new bool[](H);
    auto usedc = new bool[](W);
    long ans = 1;
    long tmpr = 0;
    long tmpc = 0;

    for (int i = 0, j = 0, k = H * W; k > 0; --k) {
        bool fa, fb;
        if (i < H && AA[i][0] == k) fa = true;
        if (j < W && BB[j][0] == k) fb = true;

        if (fa && fb) {
            usedr[AA[i][1]] = true;
            usedc[BB[j][1]] = true;
            tmpr += 1;
            tmpc += 1;
            ++i;
            ++j;
        } else if (fa) {
            if (tmpc == 0) {
                writeln(0);
                return;
            }
            ans = ans * tmpc % MOD;
            usedr[AA[i][1]] = true;
            tmpr += 1;
            ++i;
        } else if (fb) {
            if (tmpr == 0) {
                writeln(0);
                return;
            }
            ans = ans * tmpr % MOD;
            usedc[BB[j][1]] = true;
            tmpc += 1;
            ++j;
        } else {
            if (tmpr == 0 || tmpc == 0 || tmpr * tmpc <= H * W - k) {
                writeln(0);
                return;
            }
            ans = ans * (tmpr * tmpc % MOD - (H * W % MOD - k)) % MOD;
            ans = (ans + MOD) % MOD;
        }
    }

    ans.writeln;
}
