#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define F first
#define S second
#define pi acos(-1)
using ll = long long;
using namespace std;
using namespace __gnu_pbds;
using vl = vector<ll>;
using pll =  pair<ll,ll>;
const ll mod = 1000000007;
const ll infi = 1000000000000000;
const ll md = 998244353;
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update>ordered_set;


ll power(ll x,ll y){
	x = x%mod;
    ll res = 1;
    while(y){
        if(y&1)
            res = (res*x)%mod;
        x = (x*x)%mod;
        y = y/2;
    }
    return res;
}



void solve(){
	string s;
	cin>>s;
	reverse(s.begin(),s.end());
	ll ans = 0,remainder = 0,power_ten = 1;;
	map<ll,ll> mp;
	mp[0]++;
	for(int i=0;i<s.size();i++){
		remainder = ( remainder + power_ten*(s[i] - '0'))%2019;
		mp[remainder]++;
		power_ten = power_ten *10%2019;
	}
	
	for(int i=0;i<2019;i++)
		ans += (mp[i]*(mp[i] - 1))/2;
	
	cout<<ans;
}	


 
int main()
{
    
    #ifndef ONLINE_JUDGE
    // for getting input from input.txt
    freopen("input.txt", "r", stdin);
    // for writing output to output.txt
    freopen("output.txt", "w", stdout);
    #endif

    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    //int n; cin>>n; for (int i = 0; i < n; ++i)
    solve();
    return 0;
}