#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const ll INF=mod*mod;
#define rep(i, n) for (ll i = 0; i < (ll)(n); i++)
#define all(x) (x).begin(),(x).end()
ll min(ll a,ll b){
  if(a>b){
    return b;
    }
      else{
        return a;
      }
  }
  
  ll max(ll a,ll b){
    if(a>b){
      return a;
    }
    else{
      return b;
    }
  }

ll power(ll a,ll b){
 ll ans=1;
 for(ll i=1;i<=b;i++){
ans*=a;
  }
  return ans;
}

 ll gcd(ll m,ll n){
 	if(n==0){
       return m;
     }
   return gcd(n,m%n);
 }
ll lcm(ll a,ll b){
  return a/gcd(a,b)*b;
		

}


int main(){
  
  string S;
  cin>>S;
  vector<ll>date(S.size());
  vector<ll>pile(S.size());
  ll ans=0;
  
  ll index=0;
for(ll i=S.size()-1;i>=0;i--){
  date[i]=(power(10,index)*(S[i]-'0'))%2019; 
  index++;
}
  
  ll now=0;
  ll sum=0;
  
  for(ll i=S.size()-1;i>=0;i--){
    now+=date[i];
    now%=2019;
 pile[i]=now;
    
}
  
sort(all(pile));

  
   for(ll i=S.size()-1;i>=0;i--){
     if(i!=0){
     rep(j,S.size()){
       
   if(pile[lower_bound(all(pile),date[i+1])-pile.begin()]==date[i+1]){
     ans+=lower_bound(all(pile),date[i+1]+1)-lower_bound(all(pile),date[i+1]);
   }
     }
     }
else{
  if(pile[lower_bound(all(pile),0)-pile.begin()]==0){
     ans+=lower_bound(all(pile),1)-lower_bound(all(pile),0);
   }

}

   }
  
  
  cout<<ans<<endl;
}

