// testgen.cpp
// Deterministic test generator for pairs problem.
// Produces pairs.%02d.in, where pairs.00.in is the fixed sample.
//
// Compile: g++ -std=gnu++17 -O2 testgen.cpp -o testgen
// Run: ./testgen l r
//
// Guarantees (this version):
// - Test 1:   T=1e5, values<=1e9,  reachable answer<=10, impossible TLE for linear-bwd.
// - Test 2:   T=1e5, values<=1e18, reachable answer<=10, impossible TLE for linear-bwd.
// - Tests 3-5: T=1e3, values<=1e5, full answer range.
// - Test 6:   T=1e5, values<=1e18, forced a=b=1.
// - Test 7:   T=1e5, values<=1e18, forced a=b.
// - Tests 8-10: T=1e5, values<=1e18, general.
// - Per test: 90% reachable, 10% impossible; within each: 90% main, 10% antitests.
// - Near-swap clusters (tests 1-2: ans<=10, 2-phase a>b + 3-phase for ceiling bug).
// - TLE kills:
//   * Tests 3-5: reachable (1,1)->(fib25,fib24) bomb: ~4B forward-recursion nodes.
//   * Tests 6-10: reachable fib bomb via strategy-A: ~733K nodes * T.
//   * Tests 1-2 impossible linear-bwd TLE:
//       Test 1 (vals<=1e9): 5x (1,2)->(2,maxVal_odd), ~5e8 steps each => ~2.5e9 total.
//       Test 2 (vals<=1e18): 5x (1,2)->(2,maxVal_odd), ~5e17 steps each >> 10^12 each.
//   NOTE: forward-brute (ans<=10) explores at most 2^10=1024 nodes; it PASSES tests 1-2.
//         That is intentional: tests 1-2 are the small-answer subtask.
// - Specific buggy solution kills for tests 1-2 (all answers <= 10, values scaled to max):
//   * SolI (wrong tail ci-bi vs ci-ai), SolN (tail=-1), SolH (tail off-by-1):
//       (g, 2g) -> (g, 12g), ans=10. SolI returns 11, SolN returns -1, SolH returns 11.
//       g scaled to maxVal/12.
//   * SolK (swaps a,b not c,d when a>b):
//       (2g, g) -> (12g, g), ans=10. SolK swaps to (g,2g) then gets d<b => -1.
//       g scaled to maxVal/12.
//   * SolC (swap ci/di at crossover, not ai/bi):
//       (1,2)->(2, maxVal_odd) impossible. SolC returns ~maxVal/2.
//   * SolF (swaps c,d not a,b when c<d):
//       Same (1,2)->(2, maxVal_odd) bomb. SolF swaps to (maxVal,2) and returns ~maxVal/2.
//   * SolE (no divisibility check in tail):
//       (1,3)->(5,3) impossible. SolE returns floor((5-1)/3)=1 instead of -1.
//   * SolB (sort each pair): killed by a>b near-swap clusters (ans<=10 clusters cover a>b).
//   * SolD (ceiling division): killed by 3-phase near-swap clusters (ans<=10).
// - Always terminates: bounded attempts + guaranteed fallbacks.

#include <bits/stdc++.h>
using namespace std;

using u64 = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;

static const u64 BASE_SEED = 123456789ULL;
static const int T_FULL = 100000;
static const int T_SMALL = 1000;
static const double ACCEPT_DIVISIBLE_PROB = 0.05;
static const int MAX_TRIES_PER_CASE = 800;

struct RNG {
    u64 s;
    RNG() : s(0) {}
    explicit RNG(u64 seed) : s(seed) {}
    u64 next() {
        u64 z = (s += 0x9e3779b97f4a7c15ULL);
        z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9ULL;
        z = (z ^ (z >> 27)) * 0x94d049bb133111ebULL;
        return z ^ (z >> 31);
    }
    u64 uniform_u64(u64 l, u64 r) {
        if (l > r) swap(l, r);
        u64 range = r - l + 1;
        if (range == 0) return l + next();
        __uint128_t m = (~(u64)0ULL);
        u64 limit = (u64)(m - (m % range));
        u64 x;
        do { x = next(); } while (x >= limit);
        return l + (x % range);
    }
    double uniform_double() { return (next() >> 11) * (1.0 / 9007199254740992.0); }
    bool one_in(u64 k) { return k <= 1 ? true : (uniform_u64(0, k - 1) == 0); }
};

static u64 gcd_u64(u64 a, u64 b) {
    while (b) { u64 t = a % b; a = b; b = t; }
    return a;
}

// Minimal steps or -1.
static long long solve_expected(u64 a, u64 b, u64 c, u64 d) {
    u64 ga = gcd_u64(a, b);
    u64 gc = gcd_u64(c, d);
    if (ga != gc) return -1;
    if (c < a || d < b) return -1;
    if (a == c && b == d) return 0;

    i128 ai = (i128)a, bi = (i128)b, ci = (i128)c, di = (i128)d;
    long long steps = 0;

    while (true) {
        if (ci == ai && di == bi) return steps;
        if (ci <= 0 || di <= 0) return -1;
        if (ci == di) return -1;

        if (ci > di) {
            if (di < bi) return -1;
            if (di == bi) {
                i128 diff = ci - ai;
                if (diff < 0) return -1;
                if (diff % di != 0) return -1;
                i128 add = diff / di;
                if (add > (i128)LLONG_MAX - steps) return -1;
                steps += (long long)add;
                return steps;
            }
            i128 numer = ci - ai;
            i128 k = numer / di;
            if (k <= 0) k = 1;
            ci -= k * di;
            if (k > (i128)LLONG_MAX - steps) return -1;
            steps += (long long)k;
        } else {
            if (ci < ai) return -1;
            if (ci == ai) {
                i128 diff = di - bi;
                if (diff < 0) return -1;
                if (diff % ci != 0) return -1;
                i128 add = diff / ci;
                if (add > (i128)LLONG_MAX - steps) return -1;
                steps += (long long)add;
                return steps;
            }
            i128 numer = di - bi;
            i128 k = numer / ci;
            if (k <= 0) k = 1;
            di -= k * ci;
            if (k > (i128)LLONG_MAX - steps) return -1;
            steps += (long long)k;
        }
    }
}

struct Test {
    u64 a, b, c, d;
    long long expected; // not printed
};

static inline bool is_divisible_ab(u64 a, u64 b) {
    if (a == 0 || b == 0) return false;
    if (a <= b) return (b % a == 0);
    return (a % b == 0);
}

static string filename_for_idx(int idx) {
    char buf[64];
    sprintf(buf, "pairs.%02d.in", idx);
    return string(buf);
}

struct TestConfig {
    int T;
    u64 maxValue;
    bool force_a_eq_b;
    bool force_a_b_1_1;
    bool enforce_small_1e9;
    bool enforce_small_1e5;
    bool enforce_ans_le10;   // tests 1-2: all reachable answers must be <= 10
};

static TestConfig config_for_test(int testnum) {
    TestConfig cfg;
    cfg.T = T_FULL;
    cfg.maxValue = 1000000000000000000ULL;
    cfg.force_a_eq_b = false;
    cfg.force_a_b_1_1 = false;
    cfg.enforce_small_1e9 = false;
    cfg.enforce_small_1e5 = false;
    cfg.enforce_ans_le10 = false;

    if (testnum == 1) {
        cfg.maxValue = 1000000000ULL;
        cfg.enforce_small_1e9 = true;
        cfg.enforce_ans_le10 = true;
    }
    if (testnum == 2) {
        cfg.enforce_ans_le10 = true;
    }
    if (testnum >= 3 && testnum <= 5) { cfg.T = T_SMALL; cfg.maxValue = 100000ULL; cfg.enforce_small_1e5 = true; }
    if (testnum == 6) { cfg.force_a_b_1_1 = true; }
    if (testnum == 7) { cfg.force_a_eq_b = true; }
    return cfg;
}

static bool assert_case_in_constraints(const TestConfig &cfg, const Test &t) {
    auto in = [&](u64 x){ return x >= 1 && x <= cfg.maxValue; };
    if (!in(t.a) || !in(t.b) || !in(t.c) || !in(t.d)) return false;
    if (cfg.enforce_small_1e9) {
        if (t.a > 1000000000ULL || t.b > 1000000000ULL || t.c > 1000000000ULL || t.d > 1000000000ULL) return false;
    }
    if (cfg.enforce_small_1e5) {
        if (t.a > 100000ULL || t.b > 100000ULL || t.c > 100000ULL || t.d > 100000ULL) return false;
    }
    if (cfg.force_a_b_1_1) {
        if (!(t.a == 1 && t.b == 1)) return false;
    }
    if (cfg.force_a_eq_b) {
        if (t.a != t.b) return false;
    }
    return true;
}

static bool passes_divisible_filter(const TestConfig &cfg, const Test& t, RNG &rng) {
    // Disabled for forced tests and for tests 3-5 (small), to avoid stalling and to allow fallback patterns.
    if (cfg.force_a_eq_b || cfg.force_a_b_1_1) return true;
    if (cfg.enforce_small_1e5) return true;
    if (!is_divisible_ab(t.a, t.b)) return true;
    return rng.uniform_double() < ACCEPT_DIVISIBLE_PROB;
}

// ---------- Answer sampling ----------

static long long sample_ans_big(u64 maxValue, RNG &rng) {
    u64 maxAns = (maxValue > 1) ? (maxValue - 1) : 0;
    int maxLog = 60;
    int l = (int)rng.uniform_u64(0, (u64)maxLog);
    if (l == 0) return (long long)rng.uniform_u64(0, 1);

    u128 lo = (u128)1 << l;
    u128 hi = ((u128)1 << (l + 1)) - 1;
    u128 cap = (u128)maxAns;
    if (lo > cap) return (long long)maxAns;
    if (hi > cap) hi = cap;
    return (long long)rng.uniform_u64((u64)lo, (u64)hi);
}

static long long sample_ans(int testnum, const TestConfig &cfg, RNG &rng) {
    if (cfg.enforce_ans_le10) return (long long)rng.uniform_u64(0, 10);
    if (cfg.enforce_small_1e5) {
        long long maxAns = 99999;
        int maxL = 0;
        while ((1LL << (maxL + 1)) <= maxAns && maxL < 20) maxL++;
        int l = (int)rng.uniform_u64(0, (u64)maxL);
        if (l == 0) return (long long)rng.uniform_u64(0, 1);
        long long lo = 1LL << l;
        long long hi = min(maxAns, (1LL << (l + 1)) - 1);
        return (long long)rng.uniform_u64((u64)lo, (u64)hi);
    }
    return sample_ans_big(cfg.maxValue, rng);
}

// ---------- Special constructions ----------

// Forward-recursion TLE bomb.
// Tests 3-5 (vals<=1e5, T=1000): (1,1)->(75025,46368) = (fib25,fib24), ans=23.
//   ~4.23 billion forward-recursion nodes; 5 bombs guarantees TLE.
// Other full tests (vals<=1e18): strategy-A (g,g)->(988g,610g), impossible, ~733K nodes each.
//   With T=1e5 queries that's up to 73B total recursive calls when mixed in.
// Tests 1-2: forward brute force explores at most 2^10 = 1024 nodes (ans <= 10). It PASSES.
//   No TLE bomb needed for forward-brute on tests 1-2 -- that's intentional.
static bool make_forward_tle_bomb(int testnum, const TestConfig &cfg, RNG &rng, Test &out) {
    if (cfg.enforce_small_1e5) {
        out = {1ULL, 1ULL, 75025ULL, 46368ULL, 23LL};
        return solve_expected(1, 1, 75025, 46368) == 23LL;
    }
    // Strategy A for non-ans-le10 full tests
    u64 gmax = cfg.maxValue / 988;
    if (gmax == 0) return false;
    u64 glo = max<u64>(1, gmax * 9 / 10);
    if (glo > gmax) glo = gmax;
    for (int it = 0; it < 200; ++it) {
        u64 g = rng.uniform_u64(glo, gmax);
        u64 a = g, b = g, c = 988*g, d = 610*g;
        if (c > cfg.maxValue || d > cfg.maxValue) continue;
        out = {a, b, c, d, -1};
        if (solve_expected(a, b, c, d) == -1) return true;
    }
    return false;
}

// --- Targeted antitests for specific buggy solutions (tests 1-2, answer <= 10) ---
//
// Pattern: (g, 2g) -> (g, 12g), ans=10.  g = maxValue/12 (rounded down).
//
// This single case kills THREE bugs simultaneously:
//   SolI (wrong tail formula: ci-bi instead of ci-ai):
//     Backwards: ci=g=ai immediately. Tail: d2=di-ai=12g-g=11g. 11g%g=0. Returns 11. WRONG.
//   SolN (returns -1 when tail is reached):
//     Tail hit immediately, returns -1. WRONG.
//   SolH (off-by-one in tail: adds +1):
//     Tail: d2=di-bi=12g-2g=10g. Returns 10g/g + 1 = 11. WRONG.
//
// Scaled to g = floor(maxValue / 12) so values fit and answer stays exactly 10.
static Test make_sol_INH_killer(const TestConfig &cfg) {
    u64 g = cfg.maxValue / 12;
    if (g == 0) g = 1;
    Test t; t.a=g; t.b=2*g; t.c=g; t.d=12*g; t.expected=10LL;
    return t;
}

// Pattern: (2g, g) -> (12g, g), ans=10.
//
// Kills SolK (swaps a,b to a<=b but forgets to also swap c,d):
//   a=2g > b=g => SolK swaps to (g,2g), then calls correct(g,2g,12g,g).
//   In correct(g,2g,12g,g): d=g < b=2g => returns -1. WRONG.
//
// Kills SolB (sorts each pair independently):
//   sort(2g,g)=(g,2g), sort(12g,g)=(g,12g).
//   correct(g,2g,g,12g) = 10. But (2g,g)->(12g,g) is reachable in 10 steps.
//   Wait: correct(g,2g,g,12g) should equal correct(2g,g,12g,g)=10 by relabelling?
//   No: correct(g,2g,g,12g): ci=g=ai, di=12g, di>ci, tail: d2=12g-2g=10g, 10g%g=0, ret 10.
//   That's the same answer! SolB is NOT killed by this case.
//   SolB IS killed by a>b near-swap clusters (a>b but c<d, misrouted).
static Test make_sol_K_killer(const TestConfig &cfg) {
    u64 g = cfg.maxValue / 12;
    if (g == 0) g = 1;
    Test t; t.a=2*g; t.b=g; t.c=12*g; t.d=g; t.expected=10LL;
    return t;
}

// Impossible linear-backward TLE bomb for tests 1-2.
// Pattern: (1,2)->(2, maxVal_odd).
//   correct=-1. Linear: c=2, d=maxVal. Each step: d-=c, so d decreases by 2 each iteration.
//   Total steps ≈ (maxVal-2)/2 before d reaches 1 and then c>d, c-=d, c=1, c==d => impossible.
//   Test 1 (maxVal~1e9): ~5e8 steps per query. 5 queries => ~2.5e9 steps => TLE.
//   Test 2 (maxVal~1e18): ~5e17 steps per query >> 10^12 steps => TLE even with 1 query.
//
// Also kills SolC (swap ci/di at crossover, not ai/bi):
//   After ci=2, di decreases until ci>di crossover, then SolC swaps ci/di and proceeds wrong.
//   SolC returns ~maxVal/2 instead of -1.
//
// Also kills SolF (swap c,d when c<d, forgets a,b):
//   c=2 < d=maxVal => SolF swaps: correct(1,2,maxVal,2) = (maxVal-1)/2. WRONG.
static Test make_linear_tle_impossible(const TestConfig &cfg) {
    u64 B = cfg.maxValue;
    if (B % 2 == 0) B--;  // ensure B is odd so gcd(2,B)=1
    Test t; t.a=1; t.b=2; t.c=2; t.d=B; t.expected=-1;
    return t;
}

// Boundary-naive TL reachable: c==a and d=b+q*a, q huge.
static bool make_boundary_naive_tl(const TestConfig &cfg, RNG &rng, Test &out) {
    static const pair<u64,u64> bases[] = {{2,3},{3,5},{5,8},{8,13},{13,21},{21,34}};
    auto base = bases[rng.uniform_u64(0, (u64)(sizeof(bases)/sizeof(bases[0]) - 1))];
    u64 a0 = base.first, b0 = base.second;

    u64 gmax = cfg.maxValue / max(a0,b0);
    if (gmax == 0) return false;

    u64 gCap;
    if (cfg.maxValue <= 10000ULL) gCap = min<u64>(gmax, 50);
    else gCap = min<u64>(gmax, 1000000000ULL);
    if (gCap == 0) gCap = 1;

    for (int it = 0; it < 200; ++it) {
        u64 g = rng.uniform_u64(1, gCap);
        u64 a = a0 * g;
        u64 b = b0 * g;
        if (b >= cfg.maxValue) continue;
        u64 qmax = (u64)(((u128)cfg.maxValue - (u128)b) / (u128)a);
        if (qmax < 5) continue;

        u64 q_low;
        if (cfg.maxValue <= 10000ULL) q_low = min<u64>(qmax, 1000);
        else q_low = min<u64>(qmax, 2000000000000ULL);

        if (q_low < 1) q_low = 1;
        if (q_low > qmax) q_low = qmax;

        u64 q = rng.uniform_u64(q_low, qmax);
        u128 d128 = (u128)b + (u128)q * (u128)a;
        if (d128 > (u128)cfg.maxValue) continue;
        u64 c = a;
        u64 d = (u64)d128;
        out = {a,b,c,d,(long long)q};
        if (solve_expected(a,b,c,d) == (long long)q) return true;
    }
    return false;
}

// General near-swap cluster: 5 reachables with t in {3,4,5,6,7}.
// Structure A (d-dominant): C = a+q*b, D = b+t*C  =>  D > C, path reduces d first.
// Structure B (c-dominant): D = b+q*a, C = a+t*D  =>  C > D, path reduces c first.
//   B kills "ceiling division" bug (H): at each c-reduction step, (C-a) % D != 0 in general.
// Bases include a>b entries: kills "wrong floor formula" bug (C), which only fires when a>b.
static bool make_near_swap_cluster(const TestConfig &cfg, RNG &rng, array<Test,5> &cluster_out) {
    const long long t0 = 5; // t in 3..7
    // Mixed a<b and a>b bases; both orientations sampled equally.
    static const pair<u64,u64> bases[] = {
        {2,3},{3,4},{3,5},{5,7},{8,13},{13,21},{21,34},  // a < b (original)
        {3,2},{4,3},{5,3},{7,5},{13,8},{21,13},{34,21}   // a > b (new: kills solution C)
    };

    for (int attempt = 0; attempt < 600; ++attempt) {
        auto base = bases[rng.uniform_u64(0, (u64)(sizeof(bases)/sizeof(bases[0]) - 1))];
        u64 x = base.first, y = base.second;
        if (gcd_u64(x,y) != 1) continue;
        if (is_divisible_ab(x,y) || is_divisible_ab(y,x)) continue;

        u64 gmax = cfg.maxValue / max(x,y);
        if (gmax == 0) continue;

        u64 gCap;
        if (cfg.maxValue <= 10000ULL) gCap = min<u64>(gmax, 20);
        else if (cfg.maxValue <= 1000000000ULL) gCap = min<u64>(gmax, 100000);
        else gCap = min<u64>(gmax, 1000000000ULL);
        if (gCap == 0) gCap = 1;

        u64 g = rng.uniform_u64(1, gCap);
        u64 a = x*g, b = y*g;

        if (cfg.maxValue <= b) continue;
        u128 Ccap = ((u128)cfg.maxValue - (u128)b) / (u128)(t0 + 2); // worst t=7
        if (Ccap <= (u128)a) continue;

        u64 qmax = (u64)((Ccap - (u128)a) / (u128)b);
        if (qmax < 3) continue;

        u64 q_low;
        if (cfg.maxValue <= 10000ULL) q_low = min<u64>(qmax, 10);
        else if (cfg.maxValue <= 1000000000ULL) q_low = min<u64>(qmax, 50);
        else q_low = min<u64>(qmax, 2000);

        if (q_low < 1) q_low = 1;
        if (q_low > qmax) q_low = qmax;

        u64 q = rng.uniform_u64(q_low, qmax);

        // Alternate between two orientations each attempt:
        // Orientation A (d-dominant): C=a+q*b, D=b+t*C  -- original structure.
        // Orientation B (c-dominant): D=b+q*a, C=a+t*D  -- kills ceiling-division bug (H).
        //   In B, the backwards path reduces C first; (C-a) % D is NOT an exact multiple
        //   in general, so ceiling-division takes one extra step and overshoots past a.
        bool use_orient_B = (attempt % 2 == 1);

        bool okAll = true;
        int idx = 0;
        if (!use_orient_B) {
            // Orientation A: C = a + q*b, D = b + t*C
            u128 C128 = (u128)a + (u128)q*(u128)b;
            if (C128 > (u128)cfg.maxValue) continue;
            u64 C = (u64)C128;
            for (int delta=-2; delta<=2; ++delta) {
                long long t = t0 + delta;
                u128 D128 = (u128)b + (u128)t*(u128)C;
                if (D128 > (u128)cfg.maxValue) { okAll = false; break; }
                u64 D = (u64)D128;
                long long ans = (long long)q + t;
                Test tt{a,b,C,D,ans};
                if (solve_expected(tt.a,tt.b,tt.c,tt.d) != ans) { okAll = false; break; }
                cluster_out[idx++] = tt;
            }
        } else {
            // Orientation B: D = b + q*a, C = a + t*D  (c-dominant path)
            u128 D128 = (u128)b + (u128)q*(u128)a;
            if (D128 > (u128)cfg.maxValue) continue;
            u64 D = (u64)D128;
            // Ccap for worst t=t0+2=7
            u128 Ccap_B = (u128)cfg.maxValue;
            u128 C_max_B = (u128)a + (u128)(t0+2)*(u128)D;
            if (C_max_B > Ccap_B) continue;
            for (int delta=-2; delta<=2; ++delta) {
                long long t = t0 + delta;
                u128 C128b = (u128)a + (u128)t*(u128)D;
                if (C128b > (u128)cfg.maxValue) { okAll = false; break; }
                u64 C = (u64)C128b;
                long long ans = (long long)q + t;
                Test tt{a,b,C,D,ans};
                if (solve_expected(tt.a,tt.b,tt.c,tt.d) != ans) { okAll = false; break; }
                cluster_out[idx++] = tt;
            }
        }
        if (!okAll) continue;
        return true;
    }
    return false;
}

// 3-phase near-swap cluster: specifically kills "ceiling division" bug (solution H).
// Path: q1 c-steps, q2 d-steps, then vary q3 c-steps in {3,4,5,6,7}.
// C1=a+q1*b, D=b+q2*C1, C=C1+q3*D.
// Backwards: ci=C > di=D. k_correct = floor((C-a)/D) = q3 + floor(q1*b/D).
// Since q1*b < D (typical), floor gives q3; ceiling gives q3+1.
// Extra step sends ci to C1-D = C1-(b+q2*C1) = (1-q2)*C1-b <= -b < 0 for q2>=1.
// So H always returns -1 on these while correct answer = q1+q2+q3.
static bool make_near_swap_cluster_3phase(const TestConfig &cfg, RNG &rng, array<Test,5> &cluster_out) {
    const long long t0 = 5; // q3 in {3,4,5,6,7}

    static const pair<u64,u64> bases[] = {
        {2,3},{3,4},{3,5},{5,7},{8,13},{13,21},{21,34},
        {3,2},{4,3},{5,3},{7,5},{13,8},{21,13},{34,21}
    };

    for (int attempt = 0; attempt < 600; ++attempt) {
        auto base = bases[rng.uniform_u64(0, (u64)(sizeof(bases)/sizeof(bases[0]) - 1))];
        u64 x = base.first, y = base.second;
        if (gcd_u64(x,y) != 1) continue;

        u64 gmax = cfg.maxValue / max(x,y);
        if (gmax == 0) continue;
        u64 gCap;
        if (cfg.maxValue <= 10000ULL) gCap = min<u64>(gmax, 20);
        else if (cfg.maxValue <= 1000000000ULL) gCap = min<u64>(gmax, 100000);
        else gCap = min<u64>(gmax, 1000000000ULL);
        if (gCap == 0) gCap = 1;

        u64 g = rng.uniform_u64(1, gCap);
        u64 a = x*g, b = y*g;

        // Pick q1, q2 in 1..3
        u64 q1 = rng.uniform_u64(1, 3);
        u64 q2 = rng.uniform_u64(1, 3);
        u128 C1 = (u128)a + (u128)q1*(u128)b;
        u128 D128 = (u128)b + (u128)q2*C1;
        if (D128 > (u128)cfg.maxValue) continue;
        u64 D = (u64)D128;

        // Ensure q1*b is NOT a multiple of D (guarantees ceiling != floor)
        if (((u128)q1*(u128)b) % D128 == 0) continue;

        // Check worst case q3=t0+2=7 fits
        u128 Cmax = C1 + (u128)(t0+2)*D128;
        if (Cmax > (u128)cfg.maxValue) continue;

        bool okAll = true;
        int idx = 0;
        for (int delta = -2; delta <= 2; ++delta) {
            long long q3 = t0 + delta;
            u128 C128 = C1 + (u128)q3*D128;
            if (C128 > (u128)cfg.maxValue) { okAll = false; break; }
            u64 C = (u64)C128;
            long long ans = (long long)q1 + (long long)q2 + q3;
            Test tt{a, b, C, D, ans};
            if (solve_expected(tt.a,tt.b,tt.c,tt.d) != ans) { okAll = false; break; }
            cluster_out[idx++] = tt;
        }
        if (!okAll) continue;
        return true;
    }
    return false;
}

// Small-answer near-swap cluster for tests 1-2: always ans <= 10.
// Alternates between 2-phase and 3-phase orientations.
// 2-phase with a<b or a>b: kills solution C (wrong floor formula).
// 3-phase: kills solution H (ceiling division).
static bool make_near_swap_cluster_smallAns(const TestConfig &cfg, RNG &rng, array<Test,5> &cluster_out) {
    // Use t0=3 => t in {1,2,3,4,5}. Keep total ans <= 10.
    // 2-phase (C=a+q*b, D=b+t*C): q<=2 ensures ans=q+t<=7.
    // 3-phase (q1+q2+q3): q1=q2=1, q3 in {1..5}, ans=2+q3<=7.
    const long long t0 = 3;
    bool use_3phase = (rng.next() & 1ULL);
    bool use_a_gt_b = (rng.next() & 1ULL);

    // bases: a<b or a>b, coprime, no divisibility
    static const pair<u64,u64> bases_lt[] = {{2,3},{3,5},{5,7},{3,4}};
    static const pair<u64,u64> bases_gt[] = {{3,2},{5,3},{7,5},{4,3}};

    if (!use_3phase) {
        // 2-phase: C=a+q*b, D=b+t*C
        auto& bset = use_a_gt_b ? bases_gt : bases_lt;
        int nb = 4;
        for(int attempt=0; attempt<200; ++attempt) {
            auto bp = bset[rng.uniform_u64(0,(u64)(nb-1))];
            u64 x=bp.first, y=bp.second;
            if(gcd_u64(x,y)!=1) continue;

            u64 gmax = cfg.maxValue / max(x,y);
            if(gmax==0) continue;
            u64 g = rng.uniform_u64(1, min<u64>(gmax, 1000000ULL));
            u64 a=x*g, b=y*g;

            u64 q = rng.uniform_u64(1, 2); // q<=2 so total ans<=7

            u128 C128 = (u128)a + (u128)q*(u128)b;
            if(C128 > (u128)cfg.maxValue) continue;
            u64 C = (u64)C128;

            int idx=0; bool ok=true;
            for(int delta=-2;delta<=2;++delta){
                long long t=t0+delta; // 1..5
                u128 D128=(u128)b+(u128)t*(u128)C;
                if(D128>(u128)cfg.maxValue){ok=false;break;}
                u64 D=(u64)D128;
                long long ans=(long long)q+t; // <=7
                Test tt{a,b,C,D,ans};
                if(!assert_case_in_constraints(cfg,tt)){ok=false;break;}
                if(solve_expected(tt.a,tt.b,tt.c,tt.d)!=ans){ok=false;break;}
                cluster_out[idx++]=tt;
            }
            if(ok) return true;
        }
        return false;
    } else {
        // 3-phase: C1=a+q1*b, D=b+q2*C1, C=C1+q3*D, q1=q2=1, q3 in {1..5}
        auto& bset = bases_lt; // a<b works fine for H kill
        int nb = 4;
        for(int attempt=0; attempt<200; ++attempt) {
            auto bp = bset[rng.uniform_u64(0,(u64)(nb-1))];
            u64 x=bp.first, y=bp.second;
            if(gcd_u64(x,y)!=1) continue;

            u64 gmax = cfg.maxValue / max(x,y);
            if(gmax==0) continue;
            u64 g = rng.uniform_u64(1, min<u64>(gmax, 100ULL));
            u64 a=x*g, b=y*g;

            u128 C1=(u128)a+(u128)b;        // q1=1
            u128 D128=(u128)b+C1;           // q2=1
            if(D128>(u128)cfg.maxValue) continue;
            u64 D=(u64)D128;

            // Check q1*b % D != 0 (ensures H fails)
            if(((u128)b) % D128 == 0) continue;

            // q3 in {1..5}, ans = 1+1+q3 in {3..7} <= 10
            int idx=0; bool ok=true;
            for(int delta=-2;delta<=2;++delta){
                long long q3=3+delta; // 1..5
                u128 C128=C1+(u128)q3*D128;
                if(C128>(u128)cfg.maxValue){ok=false;break;}
                u64 C=(u64)C128;
                long long ans=2+q3; // <=7
                Test tt{a,b,C,D,ans};
                if(!assert_case_in_constraints(cfg,tt)){ok=false;break;}
                if(solve_expected(tt.a,tt.b,tt.c,tt.d)!=ans){ok=false;break;}
                cluster_out[idx++]=tt;
            }
            if(ok) return true;
        }
        return false;
    }
}

// Near-swap cluster for test6 constraint (a,b)=(1,1).
static bool make_near_swap_cluster_11(const TestConfig &cfg, RNG &rng, array<Test,5> &cluster_out) {
    const long long t0 = 5; // variants t=3..7
    u64 maxV = cfg.maxValue;
    if (maxV < 10) return false;
    // Need q*(t+1)+1 <= maxV for worst t=7 => (t+1)=8
    u64 qmax = (u64)(((u128)maxV - 1) / (u128)8);
    if (qmax < 3) return false;

    u64 q_low;
    if (maxV <= 10000ULL) q_low = min<u64>(qmax, 10);
    else if (maxV <= 1000000000ULL) q_low = min<u64>(qmax, 50);
    else q_low = min<u64>(qmax, 1000);
    if (q_low < 1) q_low = 1;
    if (q_low > qmax) q_low = qmax;

    u64 q = rng.uniform_u64(q_low, qmax);

    int idx = 0;
    for (int delta=-2; delta<=2; ++delta) {
        long long t = t0 + delta; // 3..7
        u64 D = (u64)(t + 1);
        u128 C = (u128)q * (u128)D + 1;
        if (C > (u128)maxV) return false;
        long long ans = (long long)q + t;
        Test tt{1,1,(u64)C,D,ans};
        if (rng.next() & 1ULL) swap(tt.c, tt.d);
        if (!assert_case_in_constraints(cfg, tt)) return false;
        if (solve_expected(tt.a,tt.b,tt.c,tt.d) != ans) return false;
        cluster_out[idx++] = tt;
    }
    return true;
}

// Near-swap cluster for test7 constraint (a,b)=(g,g): scale a test6 cluster by g.
static bool make_near_swap_cluster_gg(const TestConfig &cfg, RNG &rng, array<Test,5> &cluster_out) {
    u64 maxV = cfg.maxValue;

    TestConfig inner = cfg;
    inner.force_a_eq_b = false;
    inner.force_a_b_1_1 = true;

    array<Test,5> base{};
    if (!make_near_swap_cluster_11(inner, rng, base)) return false;

    u64 gmax = maxV;
    for (int i=0;i<5;i++) {
        gmax = min<u64>(gmax, (u64)((u128)maxV / (u128)base[i].c));
        gmax = min<u64>(gmax, (u64)((u128)maxV / (u128)base[i].d));
    }
    if (gmax == 0) return false;
    gmax = min<u64>(gmax, 1000000000ULL);

    u64 g = rng.uniform_u64(1, gmax);

    for (int i=0;i<5;i++) {
        u128 c = (u128)base[i].c * (u128)g;
        u128 d = (u128)base[i].d * (u128)g;
        if (c > (u128)maxV || d > (u128)maxV) return false;
        Test tt{g,g,(u64)c,(u64)d,base[i].expected};
        if (!assert_case_in_constraints(cfg, tt)) return false;
        if (solve_expected(tt.a,tt.b,tt.c,tt.d) != tt.expected) return false;
        cluster_out[i] = tt;
    }
    return true;
}

// ---------- Baseline reachable / impossible ----------

static bool build_reachable_baseline(int testnum, const TestConfig &cfg, RNG &rng, Test &out) {
    // forced (1,1)
    if (cfg.force_a_b_1_1) {
        long long ans = sample_ans_big(cfg.maxValue, rng);
        if ((u128)(ans + 1) > (u128)cfg.maxValue) ans = (long long)cfg.maxValue - 1;
        out.a = 1; out.b = 1;
        if (rng.next() & 1ULL) { out.c = (u64)(ans + 1); out.d = 1; }
        else { out.c = 1; out.d = (u64)(ans + 1); }
        out.expected = ans;
        return solve_expected(out.a,out.b,out.c,out.d) == ans;
    }

    // forced a=b
    if (cfg.force_a_eq_b) {
        long long ans = sample_ans_big(cfg.maxValue, rng);
        u64 gmax = (u64)((u128)cfg.maxValue / (u128)(ans + 1));
        if (gmax == 0) return false;
        u64 g = rng.uniform_u64(1, gmax);
        out.a = g; out.b = g;
        if (rng.next() & 1ULL) { out.c = (u64)((u128)(ans+1)*(u128)g); out.d = g; }
        else { out.c = g; out.d = (u64)((u128)(ans+1)*(u128)g); }
        out.expected = ans;
        return solve_expected(out.a,out.b,out.c,out.d) == ans;
    }

    long long ans = sample_ans(testnum, cfg, rng);

    // tests 3-5: try a few diverse tails, else guaranteed fallback (1,1)->(ans+1,1)
    if (cfg.enforce_small_1e5) {
        for (int it=0; it<60; ++it) {
            u64 x = rng.uniform_u64(2, 20);
            u64 y = rng.uniform_u64(2, 20);
            if (gcd_u64(x,y) != 1) continue;
            if (is_divisible_ab(x,y) || is_divisible_ab(y,x)) continue;
            bool tail_on_a = (rng.next() & 1ULL);
            u64 a = x, b = y;
            if (tail_on_a) {
                u128 cc = (u128)a + (u128)ans*(u128)b;
                if (cc > (u128)cfg.maxValue) continue;
                out = {a,b,(u64)cc,b,ans};
            } else {
                u128 dd = (u128)b + (u128)ans*(u128)a;
                if (dd > (u128)cfg.maxValue) continue;
                out = {a,b,a,(u64)dd,ans};
            }
            if (solve_expected(out.a,out.b,out.c,out.d) == ans) return true;
        }
        if (ans < 0) ans = 0;
        if (ans > 99999) ans = 99999;
        out.a = 1; out.b = 1;
        if (rng.next() & 1ULL) { out.c = (u64)(ans + 1); out.d = 1; }
        else { out.c = 1; out.d = (u64)(ans + 1); }
        out.expected = ans;
        return solve_expected(out.a,out.b,out.c,out.d) == ans;
    }

    // General full tests: try non-divisible base with scaling; if ans too huge, fall back.
    for (int it=0; it<120; ++it) {
        u64 x = rng.uniform_u64(2, 200);
        u64 y = rng.uniform_u64(2, 200);
        if (gcd_u64(x,y) != 1) continue;
        if (is_divisible_ab(x,y) || is_divisible_ab(y,x)) continue;
        bool tail_on_a = (rng.next() & 1ULL);
        u128 denom = tail_on_a ? ((u128)x + (u128)ans*(u128)y) : ((u128)y + (u128)ans*(u128)x);
        if (denom == 0) continue;
        u64 gmax = (u64)((u128)cfg.maxValue / denom);
        if (gmax == 0) continue;
        // Also ensure the non-tail side fits: tail_on_a uses b=y*g, so gmax also bounded by maxValue/y.
        // tail_on_!a uses a=x*g, so gmax also bounded by maxValue/x.
        u64 side_max = tail_on_a ? (u64)((u128)cfg.maxValue / (u128)y)
                                 : (u64)((u128)cfg.maxValue / (u128)x);
        gmax = min(gmax, side_max);
        if (gmax == 0) continue;
        u64 g = (gmax >= 1000000ULL) ? rng.uniform_u64(1, min<u64>(gmax, 1000000000ULL)) : rng.uniform_u64(1, gmax);
        u64 a = x*g, b = y*g;
        if (tail_on_a) {
            u128 cc = (u128)a + (u128)ans*(u128)b;
            if (cc > (u128)cfg.maxValue) continue;
            out = {a,b,(u64)cc,b,ans};
        } else {
            u128 dd = (u128)b + (u128)ans*(u128)a;
            if (dd > (u128)cfg.maxValue) continue;
            out = {a,b,a,(u64)dd,ans};
        }
        if (solve_expected(out.a,out.b,out.c,out.d) == ans) return true;
    }

    // fallback: (2,3)->(2, 3+ans*2) for enforce_ans_le10; (1,2)->(1,2+ans) otherwise.
    // Use non-divisible base (2,3) for tests 1-2 so divisible filter always passes.
    // Formula: c=a, d=b+ans*a. So (2,3)->(2, 3+2*ans).
    if (cfg.enforce_ans_le10) {
        u64 a = 2, b = 3;
        u128 d128 = (u128)b + (u128)ans * (u128)a;
        if (d128 <= (u128)cfg.maxValue) {
            out = {a, b, a, (u64)d128, ans};
            if (solve_expected(out.a,out.b,out.c,out.d) == ans) return true;
        }
        return false;
    }
    {
        u64 a = 1, b = 2;
        if ((u128)b + (u128)ans <= (u128)cfg.maxValue) {
            u64 d = (u64)((u128)b + (u128)ans);
            out = {a,b,a,d,ans};
            if (solve_expected(out.a,out.b,out.c,out.d) == ans) return true;
        }
    }
    return false;
}

static bool build_impossible_baseline(const TestConfig &cfg, RNG &rng, const vector<Test> &reachable_pool, Test &out) {
    if (cfg.force_a_b_1_1) {
        for (int it=0; it<300; ++it) {
            u64 c = rng.uniform_u64(2, min<u64>(cfg.maxValue, 1000000000000ULL));
            u64 d = rng.uniform_u64(2, min<u64>(cfg.maxValue, 1000000000000ULL));
            if (gcd_u64(c,d) == 1) {
                if (d <= cfg.maxValue/2) d *= 2;
                else c = 4, d = 6;
            }
            out = {1,1,c,d,-1};
            if (solve_expected(out.a,out.b,out.c,out.d) == -1) return true;
        }
        if (cfg.maxValue >= 4) { out = {1,1,2,4,-1}; return true; }
        return false;
    }

    if (!reachable_pool.empty()) {
        static const int primes[] = {2,3,5,7,11,13};
        for (int it=0; it<600; ++it) {
            const Test &base = reachable_pool[rng.uniform_u64(0, (u64)reachable_pool.size()-1)];
            int p = primes[rng.uniform_u64(0, (u64)(sizeof(primes)/sizeof(primes[0])-1))];
            if (base.c <= cfg.maxValue/(u64)p && base.d <= cfg.maxValue/(u64)p) {
                Test t = base;
                t.c *= (u64)p;
                t.d *= (u64)p;
                t.expected = -1;
                if (solve_expected(t.a,t.b,t.c,t.d) == -1) { out = t; return true; }
            }
        }
    }

    for (int it=0; it<600; ++it) {
        u64 a = rng.uniform_u64(1, min<u64>(cfg.maxValue, 1000000000ULL));
        u64 b = rng.uniform_u64(1, min<u64>(cfg.maxValue, 1000000000ULL));
        u64 g = gcd_u64(a,b);
        u64 c = rng.uniform_u64(1, min<u64>(cfg.maxValue, 1000000000ULL));
        u64 d = rng.uniform_u64(1, min<u64>(cfg.maxValue, 1000000000ULL));
        if (g != gcd_u64(c,d)) {
            out = {a,b,c,d,-1};
            if (solve_expected(out.a,out.b,out.c,out.d) == -1) return true;
        }
    }
    return false;
}

int main(int argc, char** argv) {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    if (argc < 3) {
        cerr << "Usage: " << argv[0] << " l r\n";
        return 1;
    }
    int l = atoi(argv[1]);
    int r = atoi(argv[2]);
    if (l < 0 || r < l || r > 10) {
        cerr << "Invalid range. Expect 0 <= l <= r <= 10\n";
        return 1;
    }

    if (l == 0) {
        string fname = filename_for_idx(0);
        ofstream out(fname);
        if (!out) { cerr << "Cannot write " << fname << "\n"; return 1; }
        out << "5\n";
        out << "2 4 2 8\n";
        out << "5 3 5 2\n";
        out << "5 3 8 19\n";
        out << "5 3 5 3\n";
        out << "1 2 2 1\n";
        out.close();
    }

    for (int testnum = max(l,1); testnum <= r; ++testnum) {
        TestConfig cfg = config_for_test(testnum);
        RNG rng(BASE_SEED ^ (u64)testnum);

        int T = cfg.T;
        int reachable_total = (int)(0.9 * T);
        int impossible_total = T - reachable_total;
        int reachable_main = (int)(0.9 * reachable_total);
        int reachable_anti = reachable_total - reachable_main;
        int impossible_main = (int)(0.9 * impossible_total);
        int impossible_anti = impossible_total - impossible_main;

        vector<Test> tests;
        tests.reserve((size_t)T);
        vector<Test> reachable_pool;
        reachable_pool.reserve((size_t)reachable_total);

        // --- Near-swap clusters in every test ---
        // Keep these small enough not to dominate.
        // Full: 40 clusters => 200 cases; Small: 10 clusters => 50 cases.
        int cluster_cnt = (T == T_FULL ? 40 : 10);
        int cluster_cases = cluster_cnt * 5;
        if (cluster_cases > reachable_main) cluster_cases = reachable_main - (reachable_main % 5);

        int injected_cluster = 0;
        for (int cl = 0; cl < cluster_cases/5; ++cl) {
            array<Test,5> clus{};
            bool ok = false;
            for (int tr=0; tr<800 && !ok; ++tr) {
                if (cfg.force_a_b_1_1) ok = make_near_swap_cluster_11(cfg, rng, clus);
                else if (cfg.force_a_eq_b) ok = make_near_swap_cluster_gg(cfg, rng, clus);
                else if (cfg.enforce_ans_le10) ok = make_near_swap_cluster_smallAns(cfg, rng, clus);
                else {
                    // Alternate: even clusters use 2-phase (a>b bases kill SolB/SolK),
                    // odd clusters use 3-phase (kills ceiling-division SolD/SolH bug).
                    if (cl % 2 == 0) ok = make_near_swap_cluster(cfg, rng, clus);
                    else             ok = make_near_swap_cluster_3phase(cfg, rng, clus);
                }
            }
            if (!ok) { cerr << "Failed to build near-swap cluster test " << testnum << "\n"; return 1; }
            for (int i=0;i<5;i++) {
                Test t = clus[i];
                if (!assert_case_in_constraints(cfg, t)) { cerr << "Cluster violates constraints\n"; return 1; }
                if (solve_expected(t.a,t.b,t.c,t.d) != t.expected) { cerr << "Cluster solve mismatch\n"; return 1; }
                if (cfg.enforce_ans_le10 && t.expected > 10) { cerr << "Cluster ans>10 in test " << testnum << "\n"; return 1; }
                tests.push_back(t);
                reachable_pool.push_back(t);
                injected_cluster++;
            }
        }
        reachable_main -= injected_cluster;

        // --- TLE injections and specific solution kills ---
        //
        // Tests 1-2 (ans<=10, no forward-brute TLE needed):
        //   Reachable killers (answers exactly 10, values scaled to maxValue):
        //     sol_INH_killer: (g,2g)->(g,12g) kills SolI, SolN, SolH simultaneously.
        //     sol_K_killer:   (2g,g)->(12g,g) kills SolK.
        //   Impossible killers (also serve as linear-backward TLE):
        //     linear_tle_impossible: (1,2)->(2,maxVal_odd) kills SolC, SolF, and TLEs linear-bwd.
        //     sole_bomb: (1,3)->(5,3) kills SolE.
        //
        // Tests 3-5 (vals<=1e5, T=1000): forward-brute TLE via fib bomb.
        //   sol_INH, sol_K killers also injected here (scaled to 1e5).
        if (cfg.enforce_ans_le10) {
            // Reachable killers: SolI + SolN + SolH (one case), SolK (one case)
            if (reachable_anti >= 2) {
                Test ti = make_sol_INH_killer(cfg);
                if (assert_case_in_constraints(cfg, ti) &&
                    solve_expected(ti.a,ti.b,ti.c,ti.d) == ti.expected &&
                    ti.expected <= 10) {
                    tests.push_back(ti);
                    reachable_pool.push_back(ti);
                    reachable_anti--;
                }
                Test tk = make_sol_K_killer(cfg);
                if (assert_case_in_constraints(cfg, tk) &&
                    solve_expected(tk.a,tk.b,tk.c,tk.d) == tk.expected &&
                    tk.expected <= 10) {
                    tests.push_back(tk);
                    reachable_pool.push_back(tk);
                    reachable_anti--;
                }
            }
            // Impossible killers injected into impossible_anti (handled below in SolC/SolE section)
        } else if (testnum >= 3 && testnum <= 5) {
            // Forward-brute TLE: 5 copies of fib(25)/fib(24) bomb
            int want_fib = min(5, reachable_anti);
            for (int i = 0; i < want_fib; i++) {
                Test t{};
                bool ok = make_forward_tle_bomb(testnum, cfg, rng, t);
                if (!ok) { cerr << "Failed fib TLE bomb test " << testnum << "\n"; return 1; }
                if (!assert_case_in_constraints(cfg, t)) { cerr << "fib TLE bomb constraint\n"; return 1; }
                if (solve_expected(t.a,t.b,t.c,t.d) != t.expected) { cerr << "fib TLE bomb mismatch\n"; return 1; }
                tests.push_back(t);
                reachable_pool.push_back(t);
            }
            reachable_anti -= want_fib;

            // sol_INH and sol_K killers for tests 3-5 as well
            if (reachable_anti >= 2) {
                Test ti = make_sol_INH_killer(cfg);
                if (assert_case_in_constraints(cfg, ti) &&
                    solve_expected(ti.a,ti.b,ti.c,ti.d) == ti.expected) {
                    tests.push_back(ti);
                    reachable_pool.push_back(ti);
                    reachable_anti--;
                }
                Test tk = make_sol_K_killer(cfg);
                if (assert_case_in_constraints(cfg, tk) &&
                    solve_expected(tk.a,tk.b,tk.c,tk.d) == tk.expected) {
                    tests.push_back(tk);
                    reachable_pool.push_back(tk);
                    reachable_anti--;
                }
            }
        }

        // --- SolD kill for tests 6 (a=b=1) and 7 (a=b=g) ---
        // SolD (ceiling division) is structurally immune when a=b for simple 2-phase paths,
        // BUT fails on 3-phase paths even from (a,a).
        // Test 6: inject (1,1)->(3,5): reachable, ans=3, SolD returns -1.
        // Test 7: inject (g,g)->(3g,5g): same structure scaled, SolD returns -1.
        // (Valid since 5g <= maxValue for any g up to ~2e17.)
        if (cfg.force_a_b_1_1 && reachable_anti >= 1) {
            Test t{1, 1, 3, 5, 3};
            if (assert_case_in_constraints(cfg, t) &&
                solve_expected(t.a,t.b,t.c,t.d) == 3LL) {
                tests.push_back(t);
                reachable_pool.push_back(t);
                reachable_anti--;
            }
        }
        if (cfg.force_a_eq_b && !cfg.force_a_b_1_1 && reachable_anti >= 1) {
            // Use g = maxValue/5 to get large values; 5g <= maxValue.
            u64 g = cfg.maxValue / 5;
            if (g >= 1) {
                Test t{g, g, 3*g, 5*g, 3};
                if (assert_case_in_constraints(cfg, t) &&
                    solve_expected(t.a,t.b,t.c,t.d) == 3LL) {
                    tests.push_back(t);
                    reachable_pool.push_back(t);
                    reachable_anti--;
                }
            }
        }
        auto gen_reachable = [&](int need)->bool {
            for (int i=0;i<need;i++) {
                Test t{};
                bool ok = false;
                for (int tr=0; tr<MAX_TRIES_PER_CASE && !ok; ++tr) ok = build_reachable_baseline(testnum, cfg, rng, t);
                if (!ok) return false;
                if (!assert_case_in_constraints(cfg, t)) return false;
                if (!passes_divisible_filter(cfg, t, rng)) { i--; continue; }
                if (solve_expected(t.a,t.b,t.c,t.d) != t.expected) return false;
                if (cfg.enforce_ans_le10 && t.expected > 10) { i--; continue; }
                tests.push_back(t);
                reachable_pool.push_back(t);
            }
            return true;
        };

        if (!gen_reachable(reachable_main)) { cerr << "Fail reachable_main fill test " << testnum << "\n"; return 1; }
        if (!gen_reachable(reachable_anti)) { cerr << "Fail reachable_anti fill test " << testnum << "\n"; return 1; }

        // --- Fill impossible blocks ---
        auto gen_impossible = [&](int need)->bool {
            for (int i=0;i<need;i++) {
                Test t{};
                bool ok = false;
                for (int tr=0; tr<MAX_TRIES_PER_CASE && !ok; ++tr) ok = build_impossible_baseline(cfg, rng, reachable_pool, t);
                if (!ok) return false;
                if (!assert_case_in_constraints(cfg, t)) return false;
                if (!passes_divisible_filter(cfg, t, rng)) { i--; continue; }
                if (solve_expected(t.a,t.b,t.c,t.d) != -1) return false;
                tests.push_back(t);
            }
            return true;
        };

        if (!gen_impossible(impossible_main)) { cerr << "Fail impossible_main fill test " << testnum << "\n"; return 1; }

        // --- Impossible kill bombs (SolC, SolF, SolE, linear-backward TLE) ---
        // Tests 6 (a=b=1) and 7 (a=b=g): immune since bugs require a != b.
        //
        // For tests 1-2 (enforce_ans_le10):
        //   linear_tle_impossible: (1,2)->(2, maxVal_odd)
        //     - impossible (correct=-1)
        //     - SolC: returns ~maxVal/2 (wrong)
        //     - SolF: returns ~maxVal/2 (wrong)
        //     - Linear-bwd: ~maxVal/2 steps => TLE
        //     Inject 5 copies. For test1 that's ~5×5e8=2.5e9 total steps (TLE).
        //     For test2 each copy alone is ~5e17 steps >> 10^12.
        //   sole_bomb: (1,3)->(5,3) -- impossible, kills SolE.
        //     gcd(1,3)=1=gcd(5,3), but 5-1=4 not divisible by 3. Correct=-1, SolE returns 1.
        //
        // For tests 3-5 (vals<=1e5):
        //   solc_d=99999 (odd), sole_c=5.
        //
        // For tests 8-10 (general full, vals<=1e18):
        //   solc_d=999999999999999999 (odd), sole_c=999999999999999998.
        if (!cfg.force_a_b_1_1 && !cfg.force_a_eq_b) {
            // linear-TLE / SolC / SolF impossible bomb
            Test lt = make_linear_tle_impossible(cfg);
            bool lt_ok = (solve_expected(lt.a,lt.b,lt.c,lt.d) == -1) &&
                         assert_case_in_constraints(cfg, lt);
            int n_lt = lt_ok ? min(5, impossible_anti) : 0;
            for (int i = 0; i < n_lt; i++) {
                if (solve_expected(lt.a,lt.b,lt.c,lt.d) != -1) { cerr << "LinTLE bomb not impossible\n"; return 1; }
                tests.push_back(lt);
                impossible_anti--;
            }

            // SolE impossible bomb: (1,3)->(5,3) for all non-forced tests.
            // For tests with maxValue < 5, skip (but all our tests have maxValue >= 1e5).
            u64 sole_c = 5, sole_d = 3;
            bool sole_ok = (sole_c <= cfg.maxValue && sole_d <= cfg.maxValue) &&
                           solve_expected(1,3,sole_c,sole_d) == -1;
            int n_sole = sole_ok ? min(5, impossible_anti) : 0;
            for (int i = 0; i < n_sole; i++) {
                Test t{1, 3, sole_c, sole_d, -1};
                tests.push_back(t);
                impossible_anti--;
            }
        }

        if (!gen_impossible(impossible_anti)) { cerr << "Fail impossible_anti fill test " << testnum << "\n"; return 1; }

        if ((int)tests.size() != T) {
            cerr << "Size mismatch test " << testnum << " got " << tests.size() << " expected " << T << "\n";
            return 1;
        }

        // Deterministic shuffle
        std::mt19937_64 shuf(BASE_SEED ^ (u64)testnum ^ 0xA5A5A5A5ULL);
        shuffle(tests.begin(), tests.end(), shuf);

        for (const auto &t : tests) {
            if (!assert_case_in_constraints(cfg, t)) {
                cerr << "Final constraint assert failed test " << testnum << "\n";
                return 1;
            }
        }

        string fname = filename_for_idx(testnum);
        ofstream out(fname);
        if (!out) { cerr << "Cannot write " << fname << "\n"; return 1; }
        out << T << "\n";
        for (const auto &t : tests) out << t.a << " " << t.b << " " << t.c << " " << t.d << "\n";
        out.close();
        cerr << "Generated " << fname << " with T=" << T << "\n";
    }

    return 0;
}
