// #include <bits/stdc++.h>

#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <functional>
#include <math.h>
#include <map>

typedef long long ll;
typedef unsigned long long ull;

#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define RFOR(i,a,b) for(int i=(b-1);i>=(a);--i)
#define REP(i,n)   FOR(i,0,n)
#define RREP(i,n)   RFOR(i,0,n)

const double INF = 1e+09;
const int MOD = 1e9+7;

using namespace std;

template <typename _Ty>
ostream& operator << (ostream& ostr, const vector<_Ty>& v) {if (v.empty()) {ostr << "{ }"; return ostr;}
    ostr << "{" << v.front(); for (auto itr = ++v.begin(); itr != v.end(); itr++) {ostr << ", " << *itr;}
    ostr << "}";
    return ostr;}

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return true; } return false; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return true; } return false; }

vector<int> uniq(vector<int> vec){
  sort(vec.begin(), vec.end());
  vec.erase(unique(vec.begin(), vec.end()), vec.end());
  return vec;}


  /*
  ll tmp = 1;
  for (int i = n - 1; i >= 0; i--){ vec[i] = (vec[i+1] + tmp*(s[i] - '0')) % 2019;
    tmp *= 10;
    tmp %= 2019;
  }
  */
int main(void){
  ios::sync_with_stdio(false);
  string s;
  cin >> s;
  ll n = s.size();
  vector<int> vec(n+1);
  vec[n] = 0;
  int tmp = 1;
  for (int i=n-1; i>=0; i--){
    vec[i] = (vec[i+1] + tmp*int(s[i] - '0')) % 2019;
    tmp *= 10;
    tmp %= 2019;
  }
  sort(vec.begin(), vec.end());
  ll ans = 0;
  int memo = vec[0];
    ll conf = 1;
  FOR(i, 1, n+1){
    if (vec[i] == memo){
      conf++;
    }
    else{
      ans += conf * (conf-1) /2;
      memo = vec[i];
      conf = 1;
    }
  }
  cout << ans << endl;
  return 0;
}

