#include <bits/stdc++.h>
long long gcd(long long a, long long b) { return b ? gcd(b, a % b) : a; }
using namespace std;
inline int toInt(string s) {
  int v;
  istringstream sin(s);
  sin >> v;
  return v;
}
template <class T>
inline string toString(T x) {
  ostringstream sout;
  sout << x;
  return sout.str();
}
template <class T>
T maxt(T x, T y) {
  if (x > y)
    return x;
  else
    return y;
}
template <class T>
T mint(T x, T y) {
  if (x > y)
    return y;
  else
    return x;
}
double print_double(double d) { printf("%.10f", d); }
long long m = 1e9 + 7, mod = 1e9 + 7;
long long modinv(long long a, long long m = 1e9 + 7) {
  long long b = m, u = 1, v = 0;
  while (b) {
    long long t = a / b;
    a -= t * b;
    swap(a, b);
    u -= t * v;
    swap(u, v);
  }
  u %= m;
  if (u < 0) u += m;
  return u;
}
vector<long long> divisor(long long n) {
  vector<long long> ret;
  for (long long i = 1; i * i <= n; i++) {
    if (n % i == 0) {
      ret.push_back(i);
      if (i * i != n) ret.push_back(n / i);
    }
  }
  sort(begin(ret), end(ret));
  return (ret);
}
struct UnionFind {
  vector<int> par;
  vector<int> rank;
  UnionFind(int n = 1) { init(n); }
  void init(int n = 1) {
    par.resize(n);
    rank.resize(n);
    for (int i = 0; i < n; ++i) par[i] = i, rank[i] = 0;
  }
  int root(int x) {
    if (par[x] == x) {
      return x;
    } else {
      int r = root(par[x]);
      return par[x] = r;
    }
  }
  bool issame(int x, int y) { return root(x) == root(y); }
  bool merge(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y) return false;
    if (rank[x] < rank[y]) swap(x, y);
    if (rank[x] == rank[y]) ++rank[x];
    par[y] = x;
    return true;
  }
};
long long combination_mod(int n, int k) {
  k = mint(k, n - k);
  long long ans = 1;
  if (n == 0 || k == 0) return ans;
  for (int i = 0; i < k; i++) {
    ans = ans * (n - i) % mod;
    ans = ans * modinv(i + 1) % mod;
  }
  return ans;
}
struct edge {
  int from;
  int to;
  int cost;
};
vector<long long> bellman_ford(vector<edge> edges, int V, int E, int r,
                               long long INF = 100000000000) {
  vector<long long> cost_to(V, INF);
  cost_to[r] = 0;
  for (int i = 0; i < V; i++) {
    for (int j = 0; j < E; j++) {
      edge e = edges[j];
      if (cost_to[e.from] == INF) continue;
      if (cost_to[e.to] > cost_to[e.from] + e.cost) {
        cost_to[e.to] = cost_to[e.from] + e.cost;
        if (i == V - 1) {
          printf("NEGATIVE CYCLE\n");
          return {};
        }
      }
    }
  }
  return cost_to;
}
int main() {
  string N;
  long long K;
  cin >> N >> K;
  vector<vector<long long> > dp(N.size() + 1, vector<long long>(4, 0));
  dp[0][0] = 1;
  for (int i = 0; i < N.size(); i++) {
    int ni = N[N.size() - i - 1] - '0';
    dp[i + 1][1] = dp[i][1] + 9;
    dp[i + 1][2] = 9 * dp[i][1] + dp[i][2];
    dp[i + 1][3] = 9 * dp[i][2] + dp[i][3];
  }
  vector<int> memo;
  for (int i = 0; i < N.size(); i++) {
    if (N[i] - '0') {
      memo.push_back(N.size() - i);
      memo.push_back(N[i] - '0');
    }
    if (memo.size() == 2 * K) break;
  }
  long long ans = 0;
  for (int i = (1); i < (K + 1); ++i) {
    ans += (memo[2 * i - 1] - 1) * dp[memo[2 * i - 2] - 1][K - i] +
           dp[memo[2 * i - 2] - 1][K - i + 1];
  }
  cout << ans + memo[2 * K - 1] << endl;
}
