import random
import argparse

def sample_unique(rng, n, k, prefer=None):
    if k <= 0:
        return []
    if prefer is not None and len(prefer) > 0:
        take = min(k, len(prefer))
        part = rng.sample(prefer, take)
        k -= take
    else:
        part = []
    if k > 0:
        part2 = rng.sample(range(1, n + 1), k)
        part.extend(part2)
    rng.shuffle(part)
    return part

def pick_size(rng, rem, left, n, small_hi, big_lo, big_hi, p_big):
    mx = rem - left
    if mx < 1:
        return 1
    mx = min(mx, n)
    if mx <= small_hi:
        return rng.randint(1, mx)
    if rng.random() < p_big:
        lo = min(big_lo, mx)
        hi = min(big_hi, mx)
        if lo <= hi:
            return rng.randint(lo, hi)
    return rng.randint(1, min(small_hi, mx))

def gen_case(mode, seed, outfile):
    rng = random.Random(seed)

    if mode == 0:
        n, m, q = 200, 50, 50
        LA, LB = 500, 500
    elif mode == 1:
        n, m, q = 300000, 120000, 100000
        LA, LB = 300000, 300000
    elif mode == 2:
        n = 200000
        m = min(n - 1, 150000)
        q = 200000
        LA, LB = 300000, 300000
    elif mode == 3:
        n, m, q = 300000, 1, 100000
        LA, LB = 300000, 300000
    elif mode == 4:
        n, m, q = 300000, 60000, 100000
        LA, LB = 60000, 60000
    elif mode == 5:
        n, m, q = 300000, 80000, 100000
        LA, LB = 300000, 300000
    else:
        raise ValueError("unknown mode")

    remA, remB = LA, LB

    As = []
    Bs = []
    hub = [1]

    if mode == 2:
        for i in range(m):
            As.append([i + 1])
            Bs.append([i + 2])
        remA -= m
        remB -= m

    elif mode == 3:
        half = n // 2
        A = list(range(1, half + 1))
        B = list(range(half + 1, n + 1))
        As.append(A)
        Bs.append(B)
        remA -= len(A)
        remB -= len(B)

    else:
        for i in range(m):
            left = m - i - 1
            ai = pick_size(rng, remA, left, n, small_hi=5, big_lo=2000, big_hi=20000, p_big=0.06)
            bi = pick_size(rng, remB, left, n, small_hi=5, big_lo=2000, big_hi=20000, p_big=0.06)

            force = (i < 300) or (mode == 5 and i % 7 == 0)
            if force:
                A = sample_unique(rng, n, ai, prefer=hub)
                B = sample_unique(rng, n, bi, prefer=hub)
            else:
                A = sample_unique(rng, n, ai)
                B = sample_unique(rng, n, bi)

            remA -= len(A)
            remB -= len(B)

            As.append(A)
            Bs.append(B)

            if i < 2000:
                t = rng.choice(A) if len(A) else 1
                hub.append(t)
                if len(hub) > 20000:
                    hub = hub[-20000:]

        if mode == 4:
            for i in range(m):
                if i % 3 == 0:
                    As[i] = [rng.randint(2, n)]
                if i % 3 == 1:
                    Bs[i] = [rng.randint(2, n)]

    with open(outfile, "w", encoding="utf-8") as f:
        f.write(f"{n} {m} {q}\n")
        for i in range(m):
            A = As[i]
            B = Bs[i]
            f.write(str(len(A)) + "".join(" " + str(x) for x in A) + "\n")
            f.write(str(len(B)) + "".join(" " + str(x) for x in B) + "\n")

        if mode in (1, 2, 5):
            f.write("1\n")
            for _ in range(q - 1):
                if rng.random() < 0.7:
                    f.write(str(rng.randint(1, min(n, 50000))) + "\n")
                else:
                    f.write(str(rng.randint(1, n)) + "\n")
        else:
            for _ in range(q):
                f.write(str(rng.randint(1, n)) + "\n")

def main():
    ap = argparse.ArgumentParser()
    ap.add_argument("--mode", type=int, default=1)
    ap.add_argument("--seed", type=int, default=1)
    ap.add_argument("--out", type=str, default="1.in")
    ap.add_argument("--batch", action="store_true")
    args = ap.parse_args()

    if not args.batch:
        gen_case(args.mode, args.seed, args.out)
        return

    idx = 1
    for i in range(1, 11):
        gen_case(1, args.seed * 1000 + idx, f"{idx}.in")
        idx += 1
    for i in range(2):
        gen_case(2, args.seed * 1000 + idx, f"{idx}.in")
        idx += 1
    for i in range(2):
        gen_case(3, args.seed * 1000 + idx, f"{idx}.in")
        idx += 1
    for i in range(2):
        gen_case(4, args.seed * 1000 + idx, f"{idx}.in")
        idx += 1
    for i in range(2):
        gen_case(5, args.seed * 1000 + idx, f"{idx}.in")
        idx += 1

if __name__ == "__main__":
    main()
