#include <iostream>
#include <algorithm>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <string.h>
#include <vector>
#include <queue>
#include <cmath>
#include <complex>
#include <functional>
#include <numeric>
#include <iomanip>
#include <cassert>
#include <random>
#include <chrono>

/* #include <atcoder/all> */
/* using namespace atcoder; */
using namespace std;

void debug_out(){ cout << "\n"; }
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
  cout << H << " ";
  debug_out(T...);
}
#ifdef _DEBUG
#define debug(...) debug_out(__VA_ARGS__)
#else
#define debug(...)
#endif

#define SPBR(w, n) std::cout<<(w + 1 == n ? '\n' : ' ');
#define YES cout << "YES" << endl
#define Yes cout << "Yes" << endl
#define NO cout << "NO" << endl
#define No cout << "No" << endl
#define ALL(i) (i).begin(), (i).end()
#define FOR(i, a, n) for(int i=(a);i<(n);++i)
#define RFOR(i, a, n) for(int i=(n)-1;i>=(a);--i)
#define REP(i, n) for(int i=0;i<int(n);++i)
#define RREP(i, n) for(int i=int(n)-1;i>=0;--i)
#define IN(a, x, b) (a<=x && x<b)
#define OUT(a, x, b) (x<a || b<=x)
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

#define int ll
using ll = long long;
using ull = unsigned long long;
using ld = long double;
const ll MOD = 1000000007;
/* const ll MOD = 998244353; */
const ll INF = 1ll<<60;
const double PI = acos(-1);

struct INIT { INIT(){
  cin.tie(0); ios::sync_with_stdio(false);
  cout << fixed << setprecision(10);
}}INIT;


signed main() {
  int N, K;
  cin >> N >> K; K--;

  vector<vector<int>> dp(4, vector<int>(3*N+1));
  dp[0][0] = 1;

  int c;
  REP(i, 3){
    c = 0;
    REP(j, 3*N+1){
      dp[i+1][j] += c;
      c += dp[i][j];
      if(j-N >= 0) c -= dp[i][j-N];
    }
  }

  int sum, i, j;
  for(sum = 3; K-dp[3][sum] >= 0; sum++){
    K -= dp[3][sum];
  }
  for(i = 1; K-dp[2][sum-i] >= 0; i++){
    K -= dp[2][sum-i];
  }
  for(j = 1; K-dp[1][sum-i-j] >= 0; j++){
    K -= dp[1][sum-i-j];
  }
  cout << i << " " << j << " " << sum-i-j << "\n";

  return 0;
}

#include <iostream>
#include <algorithm>
#include <vector> //動的配列
#include <string>
#include <list> //双方向リスト
#include <map> //連想配列
#include <set> //集合
#include <stack>
#include <queue>
#include <deque>
#include <cmath>
#include <bitset>
#include <numeric>
#include <tuple>



typedef long long ll;


using namespace std;

typedef pair<int, int> P;
#define FOR(i,a,b) for(int i=(int)(a) ; i < (int) (b) ; ++i )
#define rep(i,n) FOR(i,0,n)
#define sz(x) int(x.size())


template <class T>ostream &operator<<(ostream &o,const vector<T>&v)
{o<<"{";for(int i=0;i<(int)v.size();i++)o<<(i>0?", ":"")<<v[i];o<<"}";return o;}

// n次元配列の初期化。第２引数の型のサイズごとに初期化していく。
template<typename A, size_t N, typename T>
void Fill(A (&array)[N], const T &val){
    std::fill( (T*)array, (T*)(array+N), val );
}

//小さい順から取り出すヒープ
//priority_queue<ll, vector<ll>, greater<ll> > pque1;



int main(){
    int  n, m;
    cin>>n>>m;
    vector<ll> a(n);
    vector<ll> b(m);
    rep(i,n){
        cin>>a[i];
    }
    rep(i,m){
        cin>>b[i];
    }

    //dpで解く
    //dp[aの最後に使ったインデックス][bの最後]: 一致できる数を格納
    int inf = 1001002;
    vector<vector<int> > dp(n+1, vector<int>(m+1,inf));
    dp[0][0]=0;
    rep(i,n+1) rep(j,m+1){
        if (0<i) dp[i][j]=min(dp[i][j], dp[i-1][j]+1);
        if (0<j) dp[i][j]=min(dp[i][j], dp[i][j-1]+1);
        if (0<i && 0<j) {
            int co=1;
            if (a[i-1]==b[j-1]) co=0;
            dp[i][j]=min(dp[i][j], dp[i-1][j-1]+co);
        }
    }
    
    
    int ans=dp[n][m];

    cout<<ans;

    return 0;
}