#include <bits/stdc++.h>
using namespace std;
using i128 = __int128_t;
using u128 = __uint128_t;
struct DPCacheItem {
bool ok = false;
i128 total = 0;
array<i128,10> cnt{};
};
struct DigitDP {
string s;
vector<array<array<DPCacheItem,2>,2>> memo; // [pos][tight][started]
DigitDP(long long M) { s = (M < 0) ? string("0") : to_string(M);
memo.assign(s.size()+1, {}); }
pair<i128, array<i128,10>> solve(int pos, int tight, int started){
auto &cell = memo[pos][tight][started];
if (cell.ok) return {cell.total, cell.cnt};
if (pos == (int)s.size()){
array<i128,10> z{}; z.fill(0);
// nếu chưa bắt đầu, đây là số 0 -> đếm một '0'
if (!started) z[0] = 1;
cell.ok = true; cell.total = 1; cell.cnt = z;
return {cell.total, cell.cnt};
}
int limit = tight ? (s[pos]-'0') : 9;
i128 total = 0; array<i128,10> cnt{}; cnt.fill(0);
for(int d=0; d<=limit; ++d){
int ntight = tight && (d == limit);
int nstarted = started || (d != 0);
auto [t2, c2] = solve(pos+1, ntight, nstarted);
total += t2;
if (nstarted) cnt[d] += t2; // đặt chữ số d (không phải số 0 vô nghĩa ở đầu)
for(int dd=0; dd<10; ++dd) cnt[dd] += c2[dd];
}
cell.ok = true; cell.total = total; cell.cnt = cnt;
return {total, cnt};
}
array<i128,10> run(){
if (s == "0"){ array<i128,10> z{}; z.fill(0); return z; }
return solve(0, 1, 0).second;
}
};
array<i128,10> counts_digits_0_to(long long M){
if (M < 0){ array<i128,10> z{}; z.fill(0); return z; }
return DigitDP(M).run();
}
// đếm từ 0..N với chữ số hàng đơn vị có parity p (p=0 chẵn, 1 lẻ)
array<i128,10> count_up_to_parity(long long N, int p){
array<i128,10> total{}; total.fill(0);
if (N < 0) return total;
for(int u=0; u<10; ++u){
if ((u&1) != p || N < u) continue;
long long M = (N - u)/10; // t chạy 0..M
auto prefix = counts_digits_0_to(M);
prefix[0] -= 1; // loại đóng góp của t=0 ở phần tiền tố
i128 cnt_u = (i128)M + 1; // số lần xuất hiện ở hàng đơn vị
prefix[u] += cnt_u;
for(int d=0; d<10; ++d) total[d] += prefix[d];
}
return total;
}
array<i128,10> count_interval_parity(long long a, long long b, int p){
auto R = count_up_to_parity(b, p);
auto L = count_up_to_parity(a-2, p);
array<i128,10> ans{};
for(int d=0; d<10; ++d) ans[d] = R[d] - L[d];
return ans;
}
string to_string_i128(i128 x){
if (x == 0) return "0";
bool neg = x < 0; u128 v = neg ? -(u128)x : (u128)x;
string s;
while(v){ s.push_back('0' + int(v%10)); v/=10; }
if (neg) s.push_back('-');
reverse(s.begin(), s.end());
return s;
}
int main(){ios::sync_with_stdio(false);
cin.tie(nullptr);
long long k; unsigned long long n;
if(!(cin >> k >> n)) return 0;
__int128 b128 = ( __int128)k + 2 * ( (__int128)n - 1 );
long long b = (long long)b128; // an toàn với k,n ≤ 1e18
int p = ( (k % 2) + 2 ) % 2;
auto ans = count_interval_parity(k, b, p);
for(int d=0; d<10; ++d){
if (d) cout << ' ';
cout << to_string_i128(ans[d]);
}
cout << "\n";
return 0;
}