#include <bits/stdc++.h>
using namespace std;
template <class T>
T By(T x, T y, T P) {
  T F1 = 0;
  while (y) {
    if (y & 1) {
      F1 += x;
      if (F1 < 0 || F1 >= P) F1 -= P;
    }
    x <<= 1;
    if (x < 0 || x >= P) x -= P;
    y >>= 1;
  }
  return F1;
}
template <class T>
T Mul(T x, T y, T P) {
  T F1 = 1;
  x %= P;
  while (y) {
    if (y & 1) {
      F1 = By(F1, x, P);
    }
    x = By(x, x, P);
    y >>= 1;
  }
  return F1;
}
template <class T>
T Gcd(T x, T y) {
  if (y == 0) return x;
  T z;
  while (z = x % y) {
    x = y, y = z;
  }
  return y;
}
template <class T>
void UpdateMin(T &x, T y) {
  if (y < x) {
    x = y;
  }
}
template <class T>
void UpdateMax(T &x, T y) {
  if (x < y) {
    x = y;
  }
}
template <class T>
T Sqr(const T x) {
  return x * x;
}
template <class T>
T Abs(const T x) {
  return x < 0 ? -x : x;
}
class ReadBuffer {
 private:
  char buff[20000000];
  char *buf;

 public:
  void init(int size = 20000000) {
    fread(buff, 1, size, stdin);
    buf = buff;
  }
  template <class T>
  bool readInteger(T &x) {
    x = 0;
    while (*buf && isspace(*buf)) ++buf;
    if (*buf == 0) return false;
    static bool flag;
    flag = 0;
    if (*buf == '-')
      flag = true;
    else
      x = *buf - '0';
    while (isdigit(*++buf)) x = x * 10 + *buf - '0';
    if (flag) x = -x;
    return true;
  }
  template <class T>
  bool readFloat(T &x) {
    long double nowpos = 0.1;
    x = 0;
    while (*buf && isspace(*buf)) ++buf;
    if (*buf == 0) return false;
    static bool flag, decimal;
    decimal = flag = 0;
    if (*buf == '-')
      flag = true, ++buf;
    else if (*buf == '.')
      decimal = true;
    while (isdigit(*buf) || *buf == '.') {
      if (*buf == '.')
        decimal = true;
      else {
        if (decimal) {
          x += nowpos * (*buf - '0');
          nowpos *= 0.1;
        } else {
          x = x * 10 + *buf - '0';
        }
      }
      ++buf;
    }
    return true;
  }
  bool readChar(char c) {
    if (*buf == 0) return 0;
    return c = *buf++, 1;
  }
  bool readString(char *s) {
    while (*buf && isspace(*buf)) ++buf;
    if (!*buf) return false;
    while (!isspace(*buf)) *s++ = *buf++;
    *s++ = 0;
    return true;
  }
  int countSpacetonext() {
    int total = 0;
    while (*buf && *buf == ' ') ++total, ++buf;
    return total;
  }
  bool splitBycharactor(char *s, char Split = '\n') {
    while (*buf && *buf != Split) *s++ = *buf++;
    *s++ = 0;
    return *buf != 0;
  }
};
struct EDGE {
  int T;
  EDGE *Nxt;
};
pair<long long, int> dp[20][11][11];
long long maxn = 1;
vector<int> V;
long long ans = 0;
int maxi[30];
int nowpos;
void deal(int &x) {
  while (x != int(V.size()) - 1) {
    while (V[x] == 9 && x != int(V.size()) - 1) ++x;
    while (V[x] >= 0) {
      ans += dp[x][max(maxi[x + 1], V[x])][V[0]].first;
      V[0] = dp[x][max(maxi[x + 1], V[x])][V[0]].second;
      --V[x];
      if (x == int(V.size()) - 1 && V[x] == 0) break;
    }
    if (V[x] == -1) {
      V[x] = 9;
      --V[x + 1];
      while (V[x + 1] == -1) ++x, V[x] = 9, V[x + 1]--;
    }
    if (V[V.size() - 1] == 0) V.pop_back(), x = V.size() - 1;
  }
}
int main() {
  for (int i = 1; i < 10; ++i) dp[0][i][i] = make_pair(1LL, 0);
  for (int i = 1; i < 20; ++i, maxn *= 10)
    for (int j = 1; j < 10; ++j) {
      for (int k = 0; k < 10; ++k) {
        pair<long long, int> &x = dp[i][j][k];
        if (i == 1) {
          if (j == 1)
            x = make_pair(k == 0 ? 1 : 2, 9);
          else {
            if (k >= j)
              x = make_pair(2, 10 - j);
            else
              x = make_pair(1, 10 + k - j);
          }
        } else {
          int fk = k;
          for (int l = 9; l > -1; --l) {
            if (j >= l) {
              x.first += dp[i - 1][j][fk].first;
              fk = dp[i - 1][j][fk].second;
            } else {
              x.first += dp[i - 1][l][fk].first;
              fk = dp[i - 1][l][fk].second;
            }
          }
          x.second = fk;
        }
      }
    }
  long long n;
  cin >> n;
  if (n == 0) {
    cout << 0 << endl;
    return 0;
  }
  if (n < 10) {
    cout << 1 << endl;
    return 0;
  }
  while (n) V.push_back(n % 10), n /= 10;
  maxi[V.size() - 1] = V[V.size() - 1];
  for (int i = (int(V.size()) - 1) - 1; - 1 < i; --i) {
    maxi[i] = max(V[i], maxi[i + 1]);
  }
  nowpos = 1;
  deal(nowpos);
  while (V.size() != 1) {
    while (V[nowpos]) {
      ans += dp[nowpos][V[nowpos]][V[0]].first;
      V[0] = dp[nowpos][V[nowpos]][V[0]].second;
      --V[nowpos];
    }
    --nowpos, V.pop_back();
  }
  cout << ans + 1 << endl;
  cin >> n;
  return 0;
}
