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

long long rand_with_parity(int maxA, int parity) {
    while (true) {
        long long x = rnd.next(1, maxA);
        if ((x & 1) == parity)
            return x;
    }
}

int main(int argc, char* argv[]) {
    registerGen(argc, argv, 1);
    if (argc < 5) {
        fprintf(stderr, "Usage: gen TYPE t maxn maxA\n");
        return 1;
    }
    string type = argv[1];
    int t      = atoi(argv[2]);
    int maxn   = atoi(argv[3]);
    int maxA   = atoi(argv[4]);
    cout << t << "\n";
    for (int tc = 0; tc < t; ++tc) {
        int n, k;
        vector<long long> a;
        if (type == "random") {
            n = rnd.next(1, maxn);
            k = rnd.next(1, n);
            a.resize(n);
            for (int i = 0; i < n; ++i)
                a[i] = rnd.next(1, maxA);
        } else if (type == "random_yes") {
            n = rnd.next(1, maxn);
            k = rnd.next(1, n);
            int need = n / k;
            a.assign(n, 0);
            for (int i = 0; i < n; ++i)
                a[i] = rand_with_parity(maxA, 1);
            if (need > 0) {
                vector<int> idx(n);
                iota(idx.begin(), idx.end(), 0);
                shuffle(idx.begin(), idx.end());
                for (int i = 0; i < need; ++i)
                    a[idx[i]] = rand_with_parity(maxA, 0);
            }

        } else if (type == "random_no") {
            n = rnd.next(1, maxn);
            k = rnd.next(1, n);
            int need = n / k;
            a.assign(n, 0);
            for (int i = 0; i < n; ++i)
                a[i] = rand_with_parity(maxA, 1);
            bool borderline = (need >= 2 && rnd.next(0, 1) == 0);
            if (borderline) {
                vector<int> idx(n);
                iota(idx.begin(), idx.end(), 0);
                shuffle(idx.begin(), idx.end());
                for (int i = 0; i < need - 1; ++i)
                    a[idx[i]] = rand_with_parity(maxA, 0);
            }
        } else if (type == "k1") {
            n = rnd.next(1, maxn);
            k = 1;
            int need = n;
            a.assign(n, 0);
            bool makeYes = rnd.next(0, 1);
            if (makeYes) {
                for (int i = 0; i < n; ++i)
                    a[i] = rand_with_parity(maxA, 0);
            } else {
                for (int i = 0; i < n; ++i)
                    a[i] = rand_with_parity(maxA, 0);
                int cntOdd = rnd.next(1, min(n, 3));
                vector<int> idx(n);
                iota(idx.begin(), idx.end(), 0);
                shuffle(idx.begin(), idx.end());
                for (int i = 0; i < cntOdd; ++i)
                    a[idx[i]] = rand_with_parity(maxA, 1);
            }

        } else if (type == "kn") {
            n = rnd.next(1, maxn);
            k = n;
            a.assign(n, 0);
            bool makeYes = rnd.next(0, 1);
            if (makeYes) {
                for (int i = 0; i < n; ++i)
                    a[i] = rand_with_parity(maxA, 1);
                int cntEven = rnd.next(1, min(n, 3));
                vector<int> idx(n);
                iota(idx.begin(), idx.end(), 0);
                shuffle(idx.begin(), idx.end());
                for (int i = 0; i < cntEven; ++i)
                    a[idx[i]] = rand_with_parity(maxA, 0);
            } else {
                for (int i = 0; i < n; ++i)
                    a[i] = rand_with_parity(maxA, 1);
            }

        } else if (type == "offby") {
            while (true) {
                n = rnd.next(2, maxn);
                if (n == 1) continue;
                k = rnd.next(1, n - 1);
                if (n % k != 0) break;
            }
            int need = n / k;
            a.assign(n, 0);
            for (int i = 0; i < n; ++i)
                a[i] = rand_with_parity(maxA, 1);
            vector<int> idx(n);
            iota(idx.begin(), idx.end(), 0);
            shuffle(idx.begin(), idx.end());
            for (int i = 0; i < need; ++i)
                a[idx[i]] = rand_with_parity(maxA, 0);

        } else if (type == "pos_bad") {
            while (true) {
                n = rnd.next(1, maxn);
                k = rnd.next(1, n);
                int need = n / k;
                if (need == 0) continue;
                if (2 * need <= n) {
                    break;
                }
            }
            int need = n / k;
            a.assign(n, 0);
            for (int i = 0; i < n; ++i)
                a[i] = rand_with_parity(maxA, 1);
            vector<int> freePos;
            for (int i = 1; i <= n; ++i) {
                if (i % k != 0)
                    freePos.push_back(i);
            }
            shuffle(freePos.begin(), freePos.end());
            for (int i = 0; i < need; ++i) {
                int pos = freePos[i] - 1;
                a[pos] = rand_with_parity(maxA, 0);
            }
        } else if (type == "hardk1") {
            n = maxn;
            k = 1;
            a.assign(n, 0);
            for (int i = 0; i < n; ++i)
                a[i] = rand_with_parity(maxA, 0);
        } else {
            ensuref(false, "Unknown TYPE = %s", type.c_str());
        }

        cout << n << " " << k << "\n";
        for (int i = 0; i < n; ++i) {
            if (i) cout << ' ';
            cout << a[i];
        }
        cout << "\n";
    }

    return 0;
}
