#include "testlib.h"
#include <bits/stdc++.h>

using namespace std;

static const int MAX_A = (1 << 30) - 1;
static const int MAX_N = 5e5;

struct Params {
    int n = 10;
    int t1 = 0, t2 = 0;
    int minA = 0, maxA = MAX_A;
    bool allDistinct = false;
    string kind = "mixed-perfect-2";
};

long long getll(const vector<string> &kv, string key, long long def) {
    for (auto &s: kv) {
        auto p = s.find('=');
        if (p != string::npos && s.substr(0, p) == key)
            return atoll(s.substr(p + 1).c_str());
    }
    return def;
}

int getInt(const vector<string> &kv, string key, int def) {
    return (int) getll(kv, key, def);
}

string getStr(const vector<string> &kv, string key, string def) {
    for (auto &s: kv) {
        auto p = s.find('=');
        if (p != string::npos && s.substr(0, p) == key)
            return s.substr(p + 1);
    }
    return def;
}

vector <int> gen_sum(int n, int t1, int minA, bool distinct) {
    vector<int> a;
    a.reserve(n);
    if (distinct) {
        assert(n <= t1 + 1);
        if (n * 2 >= t1) {
            vector <int> pairs;
            for (int i = 0; i <= t1 / 2; ++i){
                pairs.push_back(i);
            }
            shuffle(pairs.begin(), pairs.end());
            for (int i = 0; i < n / 2; ++i) {
                a.push_back(pairs[i]);
                a.push_back(t1 - pairs[i]);
            }
        } else {
            unordered_map <int, int> used;
            for (int i = 0; i < n / 2; ++i) {
                int x = rnd.next(0, t1 / 2);
                while (used.find(x) != used.end()) {
                    x = rnd.next(0, t1 / 2);
                }
                used[x] = 1;
                a.push_back(x);
                a.push_back(t1 - x);
            }
        }
    } else {
        int k1 = min(n / 2, (int) (rnd.wnext(t1 / 2 - minA, -3) + minA));
        vector<int> to;
        if (k1 * 2 > t1 / 2) {
            vector<int> okak;
            for (int i = minA; i <= t1 / 2; ++i) {
                okak.push_back(i);
            }
            shuffle(okak.begin(), okak.end());
            for (int i = 0; i < k1; ++i) {
                to.push_back(okak[i]);
            }
        } else {
            unordered_map<int, int> used;
            for (int i = 0; i < k1; ++i) {
                int x;
                x = rnd.next(minA, t1);
                while (used.find(x) != used.end()) {
                    x = rnd.next(minA, t1);
                }
                used[x] = 1;
                to.push_back(x);
            }
        }
        vector <int> pt = rnd.partition(k1, n / 2, 1);
        for (int i = 0; i < pt.size(); ++i) {
            for (int j = 0; j < pt[i]; ++j) {
                a.push_back(to[i]);
                a.push_back(t1 - to[i]);
            }
        }
    }
    shuffle(a.begin(), a.end());
    return a;
}

vector<int> gen_xor(int n, int t2, int minA, int maxA, bool distinct) {
    vector<int> a;
    a.reserve(n);
    vector <int> to;
    int k1;
    if (distinct) {
        k1 = n / 2;
    } else {
        k1 = rnd.wnext(1, n / 2, -2);
    }
    unordered_map <int, int> used;
    for (int i = 0; i < k1; ++i) {
        int x = rnd.next(minA, maxA);
        while (used[x] || used[x ^ t2]) {
            x = rnd.next(minA, maxA);
        }
        used[x] = used[x ^ t2] = 1;
        to.push_back(x);
    }
    vector <int> pt = rnd.partition(k1, n / 2, 1);
    for (int i = 0; i < pt.size(); ++i) {
        for (int j = 0; j < pt[i]; ++j) {
            a.push_back(to[i]);
            a.push_back(to[i] ^ t2);
        }
    }
    return a;
}

vector<int> gen_mixed(int n, int t1, int t2, int minA, int maxA, bool distinct) {
    int p = n / 2, x = rnd.next(0, n / 2), s = p - x;
    vector<int> a;
    auto vx = (x == 0 ? vector <int>() : gen_xor(x * 2, t2, minA, maxA, distinct));
    auto vs = (s == 0 ? vector <int>() : gen_sum(s * 2, t1, minA, distinct));
    a.reserve(n);
    a.insert(a.end(), vx.begin(), vx.end());
    a.insert(a.end(), vs.begin(), vs.end());
    shuffle(a.begin(), a.end());
    return a;
}

vector<int> gen_mixed2 (int n, int t1, int t2, int minA, int maxA, bool distinct, bool impossible = false, int leap = 0) {
    vector <int> a;
    a.reserve(n);
    unordered_map <int, int> was;
    int was_impossible = false;
    if (leap > 0) {
        if (t1 % 2 != 0) {
            if (t1 != MAX_A) {
                ++t1;
            } else {
                --t1;
            }
        }
    }
    while (a.size() < n) {
        unordered_map <int, int> used;
        vector <int> cur;
        int x = rnd.next(minA, maxA);
        if (distinct) {
            while (was[x]) {
                x = rnd.next(minA, maxA);
            }
        }
        if (leap > 0) {
            x = t1 / 2;
            while (leap--) {
                cur.push_back(x);
            }
        }
        while (a.size() + cur.size() < n) {
            if (was[x]) {
                break;
            }
            cur.push_back(x);
            used[x] = 1;
            int y = t1 - x;
            if (y >= 0 && !used[y]) {
                x = y;
                continue;
            }
            y = x ^ t2;
            if (!used[y]) {
                x = y;
                continue;
            }
            break;
        }
        if (!distinct && !was_impossible && cur.size() % 2 != 0) {
            int f = 0;
            for (int i : cur) {
                if ((t2 ^ i) == i || i * 2 == t1) {
                    cur.push_back(i);
                    f = 1;
                    break;
                }
            }
            if (!f) {
                continue;
            }
        }
        if (impossible) {
            int x = rnd.next(1, (int)cur.size() / 2) * 2 - 1;
            if (distinct) {
                for (int i : cur) {
                    was[i] = 1;
                }
            }
            for (int i = 0; i < x; ++i) {
                cur.pop_back();
            }
            impossible = false;
            was_impossible = true;
        }
        for (int i : cur) {
            was[i] = 1;
            a.push_back(i);
        }
    }
    shuffle(a.begin(), a.end());
    return a;
}

vector<int> gen_impossible(int n, int t1, int t2, int minA, int maxA, bool distinct) {
    return gen_mixed2(n, t1, t2, minA, maxA, distinct, true);
}

vector<int> gen_random(int n, int minA, int maxA, bool distinct) {
    vector<int> a;
    a.reserve(n);
    unordered_map <int, int> used;
    for (int i = 0; i < n; i++) {
        int x = rnd.next(minA, maxA);
        if (distinct) {
            while (used.find(x) != used.end()) {
                x = rnd.next(minA, maxA);
            }
            used[x] = 1;
        }
        a.push_back(x);
    }
    return a;
}

void check_subtask(int sub, Params &p) {
    auto even = [&] {
        if (p.n < 2) p.n = 2;
        if (p.n % 2) ++p.n;
        p.n = min(p.n, MAX_N);
    };
    p.t1 = rnd.next(0, MAX_A);
    p.t2 = rnd.next(0, MAX_A);
    switch (sub) {
        case 0:
            p.n = 8;
            p.t1 = 10;
            p.t2 = 5;
            break;
        case 1:
            p.n = rnd.wnext(2, 18, 5);
            break;
        case 2:
            p.n = rnd.wnext(2, 100, 5);
            break;
        case 3:
            p.n = rnd.wnext(2, MAX_N, 5);
            p.t1 = rnd.next(0, 1);
            p.minA = 1;
            break;
        case 4:
            p.n = rnd.wnext(2, MAX_N, 5);
            p.t2 = 0;
            break;
        case 5:
            p.n = rnd.wnext(100, 2000, 5);
            break;
        case 6:
            p.n = rnd.wnext(50, MAX_N, 5);
            p.allDistinct = true;
            p.t1 = rnd.next(p.n, MAX_A);
            break;
        case 7:
            p.n = rnd.wnext(1000, 100000, 5);
            break;
        case 8:
        default:
            p.n = rnd.wnext(50, MAX_N, 5);
            break;
    }
    even();
}

int main(int argc, char *argv[]) {
    registerGen(argc, argv, 1);
    long long seed = (argc >= 2 ? atoll(argv[1]) : 1);
    rnd.setSeed(seed);
    vector<string> kv;
    for (int i = 2; i < argc; i++) kv.emplace_back(argv[i]);
    Params p;
    int sub = getInt(kv, "subtask", 8);
    p.kind = getStr(kv, "kind", "auto");
    check_subtask(sub, p);
    int n_ = getInt(kv, "n", -1);
    long long t1_ = getll(kv, "t1", -1);
    long long t2_ = getll(kv, "t2", -1);
    int minA_ = getInt(kv, "minA", -1);
    int maxA_ = getInt(kv, "maxA", -1);
    int distinct_ = getInt(kv, "distinct", -1);
    int leap_ = getInt(kv, "leap", 0);
    if (n_ != -1) {
        p.n = max(2, min(n_, MAX_N));
        if (p.n % 2) ++p.n;
    }
    if (t1_ != -1) {
        p.t1 = max(0ll, min(t1_, 2ll * MAX_A));
    }
    if (t2_ != -1) {
        p.t2 = max(0ll, min(t2_, 2ll * MAX_A));
    }
    if (minA_ != -1) {
        p.minA = max(0, min(minA_, MAX_A));
    }
    if (maxA_ != -1) {
        p.minA = max(0, min(maxA_, MAX_A));
    }
    if (distinct_ != -1) {
        p.allDistinct = (distinct_ != 0);
    }
    if (p.kind == "auto") {
        vector<string> v = {"sum-perfect", "xor-perfect", "mixed-perfect", "mixed-perfect-2", "impossible", "random"};
        p.kind = v[rnd.next(0, (int) v.size() - 1)];
    }
    vector<int> a;
    if (p.kind == "sum-perfect") {
        a = gen_sum(p.n, p.t1, p.minA, p.allDistinct);
    }
    else if (p.kind == "xor-perfect") {
        a = gen_xor(p.n, p.t2, p.minA, p.maxA, p.allDistinct);
    }
    else if (p.kind == "mixed-perfect") {
        a = gen_mixed(p.n, p.t1, p.t2, p.minA, p.maxA, p.allDistinct);
    }
    else if (p.kind == "mixed-perfect-2") {
        a = gen_mixed2(p.n, p.t1, p.t2, p.minA, p.maxA, p.allDistinct, false, leap_); // the best func
    }
    else if (p.kind == "impossible") {
        a = gen_impossible(p.n, p.t1, p.t2, p.minA, p.maxA, p.allDistinct);
    }
    else {
        a = gen_random(p.n, p.minA, p.maxA, p.allDistinct);
    }
    println(p.n, p.t1, p.t2);
    for (int i = 0; i < p.n; i++) {
        if (i) printf(" ");
        printf("%d", a[i]);
    }
    printf("\n");
}
