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
#include <cstdio>
#include <iostream>
#include <vector>

using namespace std;

const int kN = 1 << 18;

class Tree {
 public:
  Tree() : v_(2 * kN) {}

  void Add(int i, const int delta) {
    i += kN;
    while (i) {
      v_[i] += delta;
      i /= 2;
    }
  }

  int Smallest(int k) const {
    int i = 1;
    while (i < kN) {
      i <<= 1;
      if (k >= v_[i]) k -= v_[i++];
    }
    // cerr << i << endl;
    return i - kN;
  }

 private:
  vector<int> v_;
};

const long long kInfinity = 1000LL * 1000LL * 1000LL * 1000LL * 1000LL * 1000LL;
const int kMaxN = 250000;
const int kSumCount = 106;

vector<vector<long long> > d(kMaxN + 1, vector<long long>(kSumCount));

void Precalc() {
  d[0][0] = 1;
  for (int i = 0; i < kMaxN; ++i) {
    bool is_infinity = false;
    long long s = 0;
    // printf("%d:", i + 1);
    for (int j = 0; j < kSumCount; ++j) {
      const long long old_s = s;
      s += d[i][j];
      if (j > i) s -= d[i][j - i - 1];
      if (is_infinity) {
        if (old_s >= kInfinity && s < kInfinity && s >= 0) is_infinity = false;
      } else {
        if (old_s >= 0 && old_s < kInfinity && s >= kInfinity) is_infinity = true;
      }
      d[i + 1][j] = is_infinity ? kInfinity : s;
      // if (d[i + 1][j] != 0) printf(" %lld", d[i + 1][j]);
    }
    // printf("\n");
  }
}

long long GetMaxInversions(const long long n) {
  return (n * (n - 1)) / 2;
}

long long GetWays(const long long i, long long j) {
  // cerr << "GetWays " << i << " " << j << endl;
  if (j < kSumCount) return d[i][j];
  j = GetMaxInversions(i) - j;
  if (j < 0) return 0;
  if (j < kSumCount) return d[i][j];
  return kInfinity;
}

void Solve(const int n, long long k) {
  const long long total = GetMaxInversions(n);
  if (total % 2 == 1) {
    printf("NIE\n");
    return;
  }

  long long desired = total / 2;
  if (k > GetWays(n, desired)) {
    printf("NIE\n");
    return;
  }

  printf("TAK\n");

  Tree t;
  for (int i = 0; i < n; ++i) t.Add(i + 1, 1);

  for (int i = 1; i < n; ++i) {
    int j = max(0LL, desired - GetMaxInversions(n - i));
    desired -= j;
    // cerr << "step " << i << endl;
    while (k > GetWays(n - i, desired)) {
      // cerr << "!" << endl;
      k -= GetWays(n - i, desired);
      ++j;
      --desired;
    }
    // cerr << "after while" << endl;
    // cerr << j << "th" << endl;
    j = t.Smallest(j);
    // cerr << j << endl;
    printf("%d ", j);
    t.Add(j, -1);
    // cerr << "updated" << endl;
  }
  printf("%d\n", t.Smallest(0));
}

int main() {
  Precalc();

  int n;
  long long k;
  scanf("%d%lld", &n, &k);

  Solve(n, k);

  return 0;
}