#include <bits/stdc++.h>
using namespace std;
class ParseError {};
class SegmentTree {
 private:
  long long cont_num = 2;
  pair<double, double> initial_v;
  vector<pair<double, double> > dat;

 public:
  SegmentTree(){};
  void init(long long size, double initial_value_first,
            double initial_value_second) {
    cont_num = 2;
    initial_v.first = initial_value_first;
    initial_v.second = initial_value_second;
    while (cont_num < size) {
      cont_num *= 2;
    }
    dat.resize(2 * cont_num);
    for (int i = 0; i < 2 * cont_num; i++) dat[i] = initial_v;
  }
  void Update(long long position, double value_f, double value_s) {
    long long k = cont_num + position;
    dat[k].first = value_f;
    dat[k].second = value_s;
    while (k > 1) {
      k /= 2;
      dat[k].first = dat[k * 2 + 1].first * dat[k * 2].first;
      dat[k].second =
          dat[k * 2 + 1].first * dat[k * 2].second + dat[k * 2 + 1].second;
    }
  }
  double query() { return dat[1].first + dat[1].second; }
};
template <typename T>
class Zip {
  vector<T> d;
  bool flag;
  void init() {
    sort(d.begin(), d.end());
    d.erase(unique(d.begin(), d.end()), d.end());
    flag = false;
  }

 public:
  Zip() { flag = false; }
  void add(T x) {
    d.push_back(x);
    flag = true;
  }
  long long getNum(T x) {
    if (flag) init();
    return lower_bound(d.begin(), d.end(), x) - d.begin();
  }
  long long size() {
    if (flag) init();
    return (long long)d.size();
  }
};
long long N, M, K, a, b, c, d, e, H, W, L, T;
long long x, y;
long long A[2000004] = {};
long long B[2000004] = {};
long long C[2000004] = {};
long long D[1000006] = {};
long long E[1000006] = {};
bool f;
string S[200000];
string SS;
set<long long> sll;
pair<long long, long long> bufpl;
vector<long long> vl[30005];
vector<long long> llv[30005];
vector<long long> vll;
vector<long long> v;
vector<pair<long long, long long> > vpl;
vector<string> vs;
set<long long> llset;
multiset<long long> llmset;
queue<long long> ql;
multiset<pair<long long, long long> > plmset;
struct ST {
  long long first;
  long long second;
  long long cost;
  bool operator<(const ST& another) const { return first < another.first; };
  bool operator>(const ST& another) const { return first > another.first; };
};
priority_queue<ST, vector<ST>, greater<ST> > qst;
multiset<ST> stmset;
ST bufst;
ST stt[100000];
long long modinv(long long aa, long long mm) {
  long long bb = mm, uu = 1, vv = 0;
  while (bb) {
    long long tt = aa / bb;
    aa -= tt * bb;
    swap(aa, bb);
    uu -= tt * vv;
    swap(uu, vv);
  }
  uu %= mm;
  if (uu < 0) uu += mm;
  return uu;
}
long long zettai(long long aa) {
  if (aa < 0) {
    aa *= -1;
  }
  return aa;
}
class UnionFind {
 public:
  vector<long long> pairent;
  vector<long long> depth;
  vector<long long> size;
  UnionFind(long long Amount)
      : pairent(Amount, 1), depth(Amount, 1), size(Amount, 1) {
    for (long long i = 0; i < Amount; i++) {
      pairent[i] = i;
    }
  }
  long long FindPairent(long long x) {
    if (pairent[x] == x)
      return x;
    else
      return pairent[x] = FindPairent(pairent[x]);
  }
  long long Merge(long long x, long long y) {
    x = FindPairent(x);
    y = FindPairent(y);
    if (x != y) {
      if (depth[x] > depth[y]) {
        pairent[y] = pairent[x];
        return size[x] += size[y];
      } else {
        pairent[x] = pairent[y];
        if (depth[x] == depth[y]) {
          depth[y]++;
        }
        return size[y] += size[x];
      }
    } else {
      return -1;
    }
  }
  bool IsSame(long long x, long long y) {
    if (FindPairent(x) == FindPairent(y))
      return true;
    else
      return false;
  }
  long long GetSize(long long x) {
    x = FindPairent(x);
    return size[x];
  }
};
class Nibutan {
 public:
  long long hidari = 0;
  long long migi = 0;
  long long abc;
  vector<long long> contents;
  bool Jouken(int ser) {
    if (contents[ser] > abc) {
      return true;
    } else {
      return false;
    }
  }
  void Settings(int amount, long long terget) {
    migi = amount - 1;
    abc = terget;
  }
  long long tansaku() {
    hidari = -1;
    migi = contents.size();
    long long jud;
    while (hidari != migi - 1) {
      jud = hidari + migi;
      jud /= 2;
      if (Jouken(jud)) {
        migi = jud;
      } else {
        hidari = jud;
      }
    }
    return hidari;
  }
};
long long RepeatSquaring(long long N, long long P, long long M) {
  if (P == 0) return 1;
  if (P % 2 == 0) {
    long long t = RepeatSquaring(N, P / 2, M) % M;
    return t * t % M;
  }
  return N * RepeatSquaring(N, P - 1, M) % M;
}
SegmentTree seguki;
map<long long, long long> llmap;
long long dp[2][5][200] = {};
int main() {
  cin >> SS >> K;
  for (int i = 0; i < SS.size(); i++) {
    A[i] = SS[i] - '0';
  }
  dp[0][0][0] = 1;
  dp[0][1][0] = A[0] - 1;
  dp[1][1][0] = 1;
  for (int i = 1; i < SS.size(); i++) {
    dp[0][0][i] = dp[0][0][i - 1];
    dp[0][1][i] = dp[0][0][i - 1] * 9 + dp[0][1][i - 1];
    if (A[i] != 0) dp[0][1][i] += dp[1][1][i - 1];
    dp[0][2][i] =
        dp[0][1][i - 1] * 9 + dp[0][2][i - 1] + dp[1][1][i - 1] * (A[i] - 1);
    if (A[i] != 0) dp[0][2][i] += dp[1][2][i - 1];
    dp[0][3][i] =
        dp[0][2][i - 1] * 9 + dp[0][3][i - 1] + dp[1][2][i - 1] * (A[i] - 1);
    if (A[i] != 0) dp[0][3][i] += dp[1][3][i - 1];
    if (A[i] == 0) {
      for (int j = 1; j <= 3; j++) dp[1][j][i] = dp[1][j][i - 1];
    } else {
      for (int j = 1; j <= 3; j++) dp[1][j][i] = dp[1][j - 1][i - 1];
    }
  }
  cout << dp[0][K][SS.size() - 1] + dp[1][K][SS.size() - 1] << endl;
  return 0;
}
