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

namespace {
    static vector<pair<int, int>> points;
    static vector<int> p;
    static int n;
    static int q;
    static int qt;
}
#include <bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
using namespace std;
typedef long long ll;
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> indexedset;
//int randi = (mt19937(null));
int Pitaj(int i, int j, int k) {
    qt--;

    assert(1 <= i && i <= n);
    assert(1 <= j && j <= n);
    assert(1 <= k && k <= n);
    assert(i != j && i != k && j != k);
    assert(qt >= 0);
    int pi = p[i];
    int pj = p[j];
    int pk = p[k];
    cout << pi << " " << pj << " " << pk << endl;
    assert(1 <= pi && pi <= n);
    assert(1 <= pj && pj <= n);
    assert(1 <= pk && pk <= n);

    auto [ax, ay] = points[pi];
    auto [bx, by] = points[pj];
    auto [cx, cy] = points[pk];

    long long cross =
        1LL * (bx - ax) * (cy - ay) -
        1LL * (by - ay) * (cx - ax);

    if (cross > 0) return 1;
    if (cross < 0) return -1;
    return 0;
}
ll stepen(ll x){
    ll res = 1;
    while(x % 2 == 0){
        x /= 2;
        res++;
    }
    return res;
}
vector<pair<int, int>> ZapisiTacke(int n){
    vector<pair<int, int>>res(n + 1);
    ll dva = 1;
    ll brst = 1;
    while(dva < n){
        brst++;
        dva*=2;
    }
    brst--;
    ll velicina = 1000;
    ll dole = dva / 2;
    ll brojac;
    brojac = (dole/2)*(-1000) + 500;
    res[n] = make_pair(0, -100000008);
    for(int j = dole; j < n; j++){
        res[j] = make_pair(brojac, 0);
        brojac += 1000;
    }
    brojac = (dole/2)*(-1000) + 500;
    for(int i = dole; i < 2*dole; i++){
        ll naj = stepen(i - dole + 1);
        res[i / (pow(2, naj))] = make_pair((((brojac + 500) * (brst - naj)) /brst), naj*velicina);
        brojac += 1000;
    }
    return res;
}
vector<int> Resi(int n, int Q){
    vector<int>imamo(n);
    for(int i = 0; i < n; i++){
        imamo[i] = i + 1;
    }
    vector<int>brnivo(stepen(n));
    int n1 = n - 1;
    for(int i = 0; i < n; i++){
        int gaga = pow(2, i);
        brnivo[i] = min(gaga, n1);
        n1 -= brnivo[i];
    }
    int poslednji;
    vector<vector<int>>nivo(brnivo.size());
    cout << "aaaaaaaaaaaaa" << endl;
    while(imamo.size() > 4){
        int rand1 = (rand() + 6767) % imamo.size();
        int rand2 = (rand() + 676767) % imamo.size();
        int rand3 = (rand() + 7676) % imamo.size();
        if(rand1 == rand2){
            rand2++;
        }
        if(rand1 == rand3){
            rand3++;
        }
        if(rand2 == rand3){
            rand3++;
        }
        if(rand3 == rand1){
            rand3++;
        }
        cout << rand1 << " " << rand2 << " " << rand3 << "   " << endl;
        int odg = Pitaj(imamo[rand1], imamo[rand2], imamo[rand3]);
        cout << odg << endl;
        if(odg == 0){
            cout << "DAAAAAA1111" << endl;
            int nula = 2, minus1 = 0, plus1 = 0;
            vector<int>tu;
            tu.push_back(imamo[rand1]);
            tu.push_back(imamo[rand2]);
            cout << "DAAAAAA111sssssssss1" << endl;
            for(int i = 0; i < imamo.size(); i++){
                cout << "DAAAAAA1111" << endl;
                if(i != rand1 and i != rand2){

                    odg = Pitaj(imamo[rand1], imamo[rand2], imamo[i]);
                    if(odg == 0){
                        nula++;
                        tu.push_back(imamo[i]);
                    }
                    else if(odg == -1){
                        minus1++;
                    }
                    else{
                        plus1++;
                    }
                }
            }
            cout << "NEE" << endl;
            sort(tu.begin(), tu.end());
            for(auto x : tu){
                cout << x << " ";
            }
            cout << endl;
            ll istih = 0;
            ll gore = 0;
            for(int i = 0; i < brnivo.size(); i++){
                if(brnivo[i] == nula){                             //imagresku mora da se popravi ako donji i skoro donji imaju isti broj
                    for(int j = 0; j < tu.size(); j++){
                        nivo[i].push_back(tu[j]);
                    }
                }
                gore += brnivo[i];
            }
            for(int i = 0; i < brnivo.size(); i++){
                for(auto x : nivo[i]){
                    cout << x << " ";
                }
                cout << endl;
            }
            vector<int>novi;
            for(int i = 0; i < imamo.size(); i++){
                if(!binary_search(tu.begin(), tu.end(), imamo[i])){
                    novi.push_back(imamo[i]);
                }
            }
            imamo = novi;
        }

    }

    for(int i = 0; i < imamo.size(); i++){
        for(int j = i + 1; j < imamo.size(); j++){
            int plus11 = 0, minus11 = 0;
            for(int k = 0; k < nivo[2].size(); k++){
                int nzm = Pitaj(imamo[i], imamo[j], nivo[2][k]);
                if(nzm == -1){
                    minus11++;
                }
                else{
                    plus11++;
                }

            }
            if(min(plus11, minus11) == 0){
                nivo[1].push_back(imamo[i]);
                nivo[1].push_back(imamo[j]);
                int drugi;
                int treci;
                if(i != 0){
                    drugi = 0;
                }
                else if(j != 1){
                    drugi = 1;
                }
                else{
                    drugi = 2;
                }
                treci = 6 - (i + j + drugi);
                int nez = Pitaj(imamo[drugi], imamo[i], imamo[j]);
                int aa;
                if(nez == 1){
                    aa = Pitaj(imamo[j], imamo[i], imamo[drugi]);
                }
                else{
                    aa = Pitaj(imamo[i], imamo[j], imamo[drugi]);
                }
                if(aa == 1){
                    nivo[0].push_back(imamo[drugi]);
                    poslednji = imamo[treci] ;
                }
                else{
                    nivo[0].push_back(imamo[treci]);
                    poslednji = imamo[drugi] ;
                }
            }
        }
    }
    // sad smo lagani imamo segmentno stablo;
    vector<string>resenja(n + 1, "");
    for(int i = 0; i < brnivo.size(); i++){
        for(int j = 0; j < nivo[j].size(); j++){
            for(int x = 0; x <= j; x++){
                resenja[nivo[i][j]]+= '0';
            }
        }
    }
    for(int i = 1; i < n; i++){
        if(i != nivo[0][0] and i != poslednji){
            int s = Pitaj(poslednji, nivo[0][0], i);
            if(s == -1){
                resenja[i][1] = '1';
            }
        }
    }
    for()
    for(int i = 0; i < brnivo.size(); i++){
        for(auto x : nivo[i]){
            cout << x << " ";
        }
        cout << endl;
    }
    return imamo;
}



int main() {
    cin >> n >> q;

    points = ZapisiTacke(n);
    set<pair<int, int>> used_points;

    assert((int)points.size() == n + 1);

    for (int i = 1; i <= n; i++) {
        int x, y;
        x = points[i].first;
        y = points[i].second;

        assert(!used_points.count({x, y}));
        used_points.insert({x, y});
        assert(-1000000000LL <= x && x <= 1000000000LL);
        assert(-1000000000LL <= y && y <= 1000000000LL);
    }

    p.resize(n + 1);
    for (int i = 1; i <= n; i++) {
        cin >> p[i];
    }
    for(auto x : p){
        cout << x << " ";
    }
    cout << endl;
    vector<int> provera_permutacije = p;
    sort(provera_permutacije.begin()+1, provera_permutacije.end());
    for(int i = 1; i<=n; i++){
        assert(provera_permutacije[i] == i);
    }
    qt = q;

    vector<int> ans = Resi(n, q);

    assert((int)ans.size() == n + 1);

    for (int i = 1; i <= n; i++) {
        if (i > 1) cout << ' ';
        cout << ans[i];
    }
    cout << '\n';

    return 0;
}