#include "testlib.h"
#include <cstdlib>
#include <cstdio>
#include <vector>
#include <iostream>
#include <cassert>

using namespace std;

const int SMALLW = 10000, INF = 999990000;
const long long LLINF = 2117117117117117117LL;

inline bool check_diff(vector<long long> &a)
{
    for (int i = 1; i < (int) a.size(); i++)
        if (a[i] == a[i - 1])
            return false;
    return true;
}

int compare(int, int) { return 1; }

// weights_pkun.cpp started
const int MAXN = 30;

struct item {
    long long x;
    long long y;
    long long mask;
};

long long deg3[MAXN];
item *buffer;

item* calc(int n, long long* a, long long* b) {
    item *result0 = new item[deg3[n]];
    item *result1 = new item[deg3[n]];

    result0[0] = {0, 0, 0};

    for (int i = 0; i < n; i++) {
        int p[3];
        p[0] = p[1] = p[2] = 0;
        int ptr = 0;
        while (true) {
            int best = -1;
            if (p[0] != deg3[i]) {
                best = 0;
            }
            if (p[1] != deg3[i] && (best == -1 || result0[p[1]].x < result0[p[best]].x + (best - 1) * a[i])) {
                best = 1;
            }
            if (p[2] != deg3[i] && (best == -1 || result0[p[2]].x + a[i] < result0[p[best]].x + (best - 1) * a[i])) {
                best = 2;
            }
            if (best == -1) break;
            assert(ptr < deg3[n]);
            result1[ptr].x = result0[p[best]].x + (best - 1) * a[i];
            result1[ptr].y = result0[p[best]].y + (best - 1) * b[i];
            result1[ptr].mask = result0[p[best]].mask + deg3[i] * best;
            ptr++;
            p[best]++;
        }
        swap(result0, result1);
    }
    delete[] result1;
    return result0;
}

int check_set(int n, long long* a, long long* b) {
    int m = n / 2;
    item *left = calc(m, a, b);
    item *right = calc(n - m, a + m, b + m);

    int rptr = (int)deg3[n - m];
    long long bestm = -1;
    long long bestval = 1LL << 60;

    long long mask = -1;
    int zero = 0;


    /*
       for (int i = 0; i < deg3[m]; i++) {
       fprintf(stderr, "left[i] = (%lld, %lld, %lld)\n", left[i].x, left[i].y, left[i].mask);
       }
       for (int i = 0; i < deg3[n - m]; i++) {
       fprintf(stderr, "right[i] = (%lld, %lld, %lld)\n", right[i].x, right[i].y, right[i].mask);
       }
       */


    for (int i = 0; i < deg3[m]; i++) {
        while (rptr && left[i].x + right[rptr - 1].x > 0) {
            rptr--;
            if (bestval > right[rptr].y) {
                bestval = right[rptr].y;
                bestm = right[rptr].mask;
            }
        }
        if (left[i].y + bestval <= 0) {
            mask = left[i].mask + bestm * deg3[m];
            zero = 1;
            //fprintf(stderr, "When mask = %llx, x > %lld, y = %lld\n", mask, left[i].x + right[rptr].x, left[i].y + bestval);
            break;
        }
    }
    if (mask == -1) {
        rptr = deg3[n - m];
        bestval = 1LL << 60;
        for (int i = 0; i < deg3[m]; i++) {
            while (rptr && left[i].x + right[rptr - 1].x >= 0) {
                rptr--;
                if (bestval > right[rptr].y) {
                    bestval = right[rptr].y;
                    bestm = right[rptr].mask;
                }
            }
            if (left[i].y + bestval < 0) {
                mask = left[i].mask + bestm * deg3[m];
                zero = 0;
                //fprintf(stderr, "When mask = %llx, x >= %lld, y = %lld\n", mask, left[i].x + right[rptr].x, left[i].y + bestval);
                break;
            }
        }
    }
    delete[] left;
    delete[] right;

    if (mask == -1) {
        return -1;
    }

    int lf_mask = 0;
    int rg_mask = 0;

    for (int i = 0; i < n; i++) {
        int cur = (int)((mask / deg3[i]) % 3);
        if (cur == 2) {
            lf_mask += (1LL << i);
        }
        if (cur == 0) {
            rg_mask += (1LL << i);
        }
    }


    int res = compare(lf_mask, rg_mask);

    //fprintf(stderr, "check on (%08x, %08x) = %d\n", lf_mask, rg_mask, res);

    if (res > 0) {
        return 0;
    }
    if (res == 0) {
        return zero;
    }
    return 1;

}

void precalc() {
    deg3[0] = 1;
    for (int i = 1; i < MAXN; i++) {
        deg3[i] = deg3[i-1] * 3;
    }
}

int identify_set(int n, int k, long long **sets) {
    precalc();
    buffer = new item[deg3[(n + 1) / 2]];
    int cur_set = -1;
    int count = 0;

    for (int i = 0; i < k; i++) {
        if (count == 0) {
            cur_set = i;
            count = 1;
        } else {
            //fprintf(stderr, "check %d %d\n", cur_set, i);
            int res = check_set(n, sets[cur_set], sets[i]);
            if (res == -1) {
                count++;
            } else if (res == 0) {
            } else if (res == 1) {
                cur_set = i;
                count = 1;
            } else {
                assert(0);
            }
        }
    }
    assert(count != 0);
    if (count == 1) return cur_set;
    return -1;
}
// weights_pkun.cpp finished

int main(int argc, char* argv[])
{
    registerGen(argc, argv, 1);

    int n = atoi(argv[1]), k = atoi(argv[2]), T = atoi(argv[3]), pos = rnd.next(k);
    printf("%d %d %d\n%d\n", n, k, T, pos);
    vector<long long> a(n);
    do
    {
        for (int j = 0; j < n; j++)
            a[j] = rnd.next(1, SMALLW);
        sort(a.begin(), a.end());
    } 
    while (!check_diff(a));
    int ll = 0, rr = INF, xx;
    long long **sets = new long long*[2];
    sets[0] = new long long[n];
    sets[1] = new long long[n];
    for (int i = 0; i < n; i++)
        sets[0][i] = a[i] + INF;
    while (rr - ll > 1)
    {
        xx = (ll + rr) >> 1;
        for (int i = 0; i < n; i++)
            sets[1][i] = a[i] + xx;
        if (identify_set(n, 2, sets) == -1)
            rr = xx;
        else
            ll = xx;
    }
    delete [] sets[0];
    delete [] sets[1];
    delete [] sets;
    for (int i = 0; i < k; i++)
    {
        if (i == pos)
        {
            for (int j = 0; j < n; j++)
                printf("%lld%c", a[j] + INF, "\n "[j < n - 1]);
        }
        else
        {
            for (int j = 0; j < n; j++)
                printf("%lld%c", a[j] + ll, "\n "[j < n - 1]);
            ll--;
        }
    }

    return 0;
}
