1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#include <cstdio>
#include <cstdint>
#include <algorithm>
#include <iostream>

typedef int64_t int64;

int64 MAX;
int64 TMP[20000];

class PerSize;
PerSize** PER_SIZE;

class PerSize {
  public:
  int size;
  int64 maxInv;
  long* values;
  int valuesLen;

  PerSize() {
    size = 1;
    maxInv = 0;
    values = new long[1] {1};
    valuesLen = 1;
    //printf("valuesLen: %d\n", valuesLen);
  }

  PerSize(PerSize* other) {
    //printf("QQQ?\n");
    size = other->size + 1;
    maxInv = ((long)size * (size - 1) / 2);
    valuesLen = (int)std::min(other->valuesLen + (int64)size, maxInv / 2 + 1);
    //printf("valuesLen: %d\n", valuesLen);
    //printf("other->valuesLen: %d\n", other->valuesLen);
    //printf("maxInv: %ld\n", maxInv / 2 + 1);
    for (int inv = 1; inv < valuesLen; inv++) {
      TMP[inv] = other->get(inv) + TMP[inv - 1];
      if (TMP[inv] > 2 * MAX) {
        valuesLen = inv;
        break;
      }
    }
    for (int inv = valuesLen - 1; inv >= size; inv--) {
      TMP[inv] -= TMP[inv - size];
    }
    while (TMP[valuesLen - 1] > MAX) {
      valuesLen--;
    }
    //printf("valuesLen: %d\n", valuesLen);
    values = new long[valuesLen];
    for (int i = 0; i < valuesLen; i++) {
      values[i] = TMP[i];
    }
  }

  int64 get(int64 idx) {
    idx = std::min(idx, maxInv - idx);
    if (idx < 0) {
      return 0;
    }
    return idx < valuesLen ? values[(int)idx] : MAX;
  }

  bool solve1(int64 idx, std::vector<int>* result) {
    return maxInv % 2 == 0 && solve2(this, maxInv / 2, idx - 1, result);
  }

  static bool solve2(
      PerSize* current, int64 base, int64 idx, std::vector<int>* result) {
    m: while (current->size > 1) {
      PerSize* previous = PER_SIZE[current->size - 2];
      int64 baseStart = std::min(base, previous->maxInv);
      int64 baseEnd = std::max((int64)0, base - current->size + 1);
      for (int64 newBase = baseStart; newBase >= baseEnd; newBase--) {
        int64 v = previous->get(newBase);
        if (idx < v) {
          result->push_back((int)(base - newBase));
          base = newBase;
          current = previous;
          goto m;
        }
        idx -= v;
      }
      return false;
    }
    return true;
  }

};

void print(std::vector<int> result) {
  std::vector<std::vector<int>> free;
  int f = 1;
  for (int q = result.size(); q > 1; q = (q + 1) / 2) {
    free.emplace_back(std::vector<int>(q, f));
    f *= 2;
  }
  for (int v : result) {
    int idx = 0;
    for (int q = free.size() - 1; q >= 0; q--) {
      idx *= 2;
      int onLeft = free[q][idx];
      if (v >= onLeft) {
        idx++;
        v -= onLeft;
      }
      free[q][idx]--;
    }
    printf("%d ", (idx + 1));
  }
  printf("\n");
}

void solve(int size, int64 idx) {
  //printf("INIT\n");
  MAX = idx + 1;
  TMP[0] = 1;
  PER_SIZE = new PerSize*[size];
  PER_SIZE[0] = new PerSize();
  for (int i = 1; i < size; i++) {
    PER_SIZE[i] = new PerSize(PER_SIZE[i - 1]);
  }
  std::vector<int> result;
  //printf("SOLVING\n");
  if (!PER_SIZE[size - 1]->solve1(idx, &result)) {
    printf("NIE\n");
    return;
  }
  printf("TAK\n");
  //printf("PRINTING\n");
  result.push_back(0);
  print(result);
}

int main(int argc, char **argv) {
  int64 a, b;
  //scanf("%lli%lli", &a, &b);
  std::cin >> a >> b;
  solve(a, b);
  return 0;
}