#include <bits/stdc++.h>
using namespace std;
vector<int> remdup(vector<int> A) {
  sort(A.begin(), A.end());
  vector<int> res;
  if (A.size() == 0) return res;
  res.push_back(A[0]);
  for (int i = 1; i < A.size(); i++)
    if (A[i] != A[i - 1]) res.push_back(A[i]);
  return res;
}
vector<int> scit(vector<int> A) {
  vector<int> res;
  for (int i = 0; i < (1 << A.size()); i++) {
    int p = 0;
    for (int j = 0; j < (A.size()); j++)
      if (i & (1 << j))
        p += A[j];
      else
        p -= A[j];
    res.push_back(p);
  }
  return remdup(res);
}
vector<int> nasobky;
vector<vector<int> > Bet;
void nasob(int nas, int kde) {
  if (kde == Bet.size()) {
    nasobky.push_back(nas);
    return;
  }
  for (int i = 0; i < (Bet[kde].size()); i++) nasob(nas * Bet[kde][i], kde + 1);
}
vector<int> pom;
vector<int> C;
vector<int> rozdel(int kde) {
  vector<int> res;
  if (kde == C.size()) {
    Bet.clear();
    vector<int> p;
    p.push_back(C[0]);
    for (int i = 1; i < C.size(); i++) {
      if (pom[i] == pom[i - 1])
        p.push_back(C[i]);
      else {
        Bet.push_back(scit(p));
        p.clear();
        p.push_back(C[i]);
      }
    }
    Bet.push_back(scit(p));
    nasobky.clear();
    nasob(1, 0);
    res = nasobky;
    return remdup(res);
  }
  if (kde == 0) {
    pom.push_back(0);
    res = rozdel(kde + 1);
    pom.pop_back();
    return remdup(res);
  }
  pom.push_back(pom[pom.size() - 1]);
  res = rozdel(kde + 1);
  pom.pop_back();
  pom.push_back(pom[pom.size() - 1] + 1);
  vector<int> p = rozdel(kde + 1);
  pom.pop_back();
  for (int i = 0; i < (p.size()); i++) res.push_back(p[i]);
  return remdup(res);
}
vector<vector<int> > P;
int main() {
  P.resize(20047);
  vector<int> A, res;
  for (int i = 0; i < (10000); i++) {
    A.clear();
    int x = i;
    for (int j = 0; j < (4); j++) {
      A.push_back(x % 10);
      x /= 10;
    }
    C = A;
    res = rozdel(0);
    res = remdup(res);
    for (int j = 0; j < (res.size()); j++) P[10000 + res[j]].push_back(i);
  }
  int n, k;
  scanf("%d %d", &n, &k);
  set<pair<int, int> > V;
  for (int i = 0; i < (20042); i++) {
    if (V.size() >= k) break;
    int mam = i - 10000;
    int x = n - mam;
    if (x < 0) x = mam - n;
    if (x < 0) continue;
    if (x > 9999) continue;
    if (P[i].size() == 0) continue;
    int kde = 0;
    while (kde != P[i].size() && V.size() != k) {
      V.insert(make_pair((P[i][kde]), (x)));
      V.insert(make_pair((x), (P[i][kde])));
      kde++;
    }
  }
  vector<pair<int, int> > v(V.begin(), V.end());
  vector<int> p1, p2;
  p1.resize(4);
  p2.resize(4);
  for (int i = 0; i < (min(k, (int)v.size())); i++) {
    for (int j = 0; j < (4); j++) {
      p1[j] = v[i].first % 10;
      v[i].first /= 10;
    }
    for (int j = 0; j < (4); j++) {
      p2[j] = v[i].second % 10;
      v[i].second /= 10;
    }
    for (int j = 0; j < (4); j++) printf("%d", p1[3 - j]);
    for (int j = 0; j < (4); j++) printf("%d", p2[3 - j]);
    printf("\n");
  }
  return 0;
}
