#include <bits/stdc++.h>
using namespace std;
#define ll long long int
#define deb(x) cout << #x << " " << x << endl;
#define mod 1000000007
#define fast std::ios::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
#define endl "\n"

const ll INF = 1e18;
const ll NEGINF = -1 * INF;

/*NOTES: Take care of ll vs int
         Never use an iterator after erasing it
*/

const int N = 20;

ll dp[1 << N];
vector<array<int, 2>> arr[N];
int n, m;

ll build(int mask)
{
    if (mask == 0)
    {
        return 1;
    }
    if (dp[mask] != -1)
    {
        return dp[mask];
    }
    int currBits = __builtin_popcountll(mask);
    vector<int> a(n + 1, 0);
    for (int i = 0; i < n; i++)
    {
        if (mask & (1 << i))
        {
            a[i + 1]++;
        }
    }
    for (int i = 1; i <= n; i++)
    {
        a[i] += a[i - 1];
    }
    for (auto it : arr[currBits])
    {
        if (a[it[0]] > it[1])
        {
            return dp[mask] = 0;
        }
    }
    ll ways = 0;
    for (int i = 0; i < n; i++)
    {
        if (mask & (1 << i))
        {
            ways += build(mask ^ (1 << i));
        }
    }
    return dp[mask] = ways;
}

// out of the first 'x' elements, at most 'z' elements should be <= 'y'
void solve()
{
    cin >> n >> m;
    int x, y, z;
    for (int i = 0; i < m; i++)
    {
        cin >> x >> y >> z;
        arr[x].push_back({y, z});
    }
    memset(dp, -1, sizeof(dp));
    cout << build((1 << n) - 1) << endl;
}

int main()
{
    fast;
#ifndef ONLINE_JUDGE
    freopen("/home/kalit/Desktop/Data Structures-Algo-Competitive/src/codeforces/input.txt", "r", stdin);
    freopen("/home/kalit/Desktop/Data Structures-Algo-Competitive/src/codeforces/output.txt", "w", stdout);
#endif
    int T = 1;
    while (T--)
    {
        solve();
    }
    //cout<< "Done in " << clock() / CLOCKS_PER_SEC <<"sec"<< endl;
    return 0;
}
#include "bits/stdc++.h"
#include "ext/pb_ds/assoc_container.hpp"
#include "ext/pb_ds/tree_policy.hpp"
using namespace std;
 
#pragma GCC optimize("O3","unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#pragma GCC target("avx2")

using namespace __gnu_pbds;
template <typename T> using oset = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
// find_by_order(k) -> iterator of kth element (in sorted fashion : low - high)
// order_of_key(x) -> #numbers strictly less than x

#define sync ios_base::sync_with_stdio(0); cin.tie(0);
#define all(x) x.begin(),x.end()
#define unq(a) sort(all(a));a.resize(unique(all(a)) - a.begin())
#define fi first
#define se second
//#define endl '\n'
 
using pii = pair<int , int>;
using ll = long long;
using ld = long double;
 
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
//mt19937 rng(0);

// const int N = 3e6 + 5;
// vector<ll> f(N);

// void u(int x, int way){
//   for (int i = x; i < N; i += (i & -i)){
//     f[i] += way;
//   }
// }

// ll gt(int x){
//   ll r = 0;
//   for (int i = x; i > 0; i -= (i & -i)){
//     r += f[i];
//   }
//   return r;
// }

int main(){
 
    #ifndef ONLINE_JUDGE 
        freopen("input.txt", "r", stdin);
        freopen("output.txt", "w", stdout);
    #endif
 
    sync

    int t = 1;
    //cin >> t;
    while(t--){
      int n;
      ll k, gn = 0;
      cin >> n >> k;
      int smblk = -1;

      vector<ll> way2(2 * n + 1);
      int l = 2, r = 2 * n, cnt = 0;
      while(l <= r){
        way2[l] = way2[r] = ++cnt;
        l++; r--;
      }
      vector<ll> df(3 * n + 5);
      for (int i = 1; i <= 2 * n; i++){
        df[i + 1] += way2[i];
        df[i + n + 1] -=  way2[i];
      }
      for (int i = 1; i <= 3 * n; i++){
        df[i] += df[i - 1];
      }
      for (ll sm = 3; sm <= 3 * n; sm++){
        if (gn + df[sm] < k){
          gn += df[sm];
        }
        else{
          smblk = sm;
          break;
        }
      }
      assert(smblk != -1);
      int bu = -1, ts = -1;
      for (int b = 1; b <= n; b++){
        if (smblk - b < 0 or smblk - b > 2 * n) continue;
        if (gn + way2[smblk - b] < k){
          gn += way2[smblk - b];
        }
        else{
          bu = b;
          break;
        }
      }
      assert(bu != -1);
      //cout << smblk << " " << bu << endl << flush;
      for (int tz = 1; tz <= n; tz++){
        if (smblk - bu - tz < 0 or smblk - bu - tz > n) continue;
        gn++;
        //cout << tz << " " << gn << " " << k << endl << flush;
        if (gn == k){
          ts = tz;
          break;
        }
      }
      assert(ts >= 1 && ts <= n);
      cout << bu << " " << ts << " " << smblk - bu - ts << endl;
    }
    cerr << "processor time: " << clock() / (double) CLOCKS_PER_SEC << "s    ";
    return 0;
}