#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> 
#include <ext/pb_ds/tree_policy.hpp> 

using namespace __gnu_pbds; 
using namespace std;

using   ll=long long;
using   ld=long double;

#define fast        	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define ordered_set1 	tree<ll, null_type,less<ll>, rb_tree_tag,tree_order_statistics_node_update>
#define endl        	"\n"
#define pb          	push_back
#define mp          	make_pair
#define F           	first
#define S           	second
#define pll         	pair<ll,ll>
#define vec     		vector<ll>
#define ALL(v)      	v.begin(),v.end()
#define ALLR(v)     	v.rbegin(),v.rend()
#define pii         	3.14159265358979323
#define linf     		LLONG_MAX
#define ones(x)     	__builtin_popcount(x)
#define fill(a,b)   	memset(a,b,sizeof(a))
#define mod 			1000000007

ll mod_pow(ll a,ll b)
{
    ll res = 1;
    while(b)
    {
        if(b&1) res=(res*a)%mod;
        a=(a*a)%mod;
        b>>=1;
    }
    return res;
}

ll mod_inverse(ll a)
{
	return mod_pow(a,mod-2);
}

void solve()
{
	string s;
	
	int n;
	
	cin>>s;
	
	n = s.size();
	
	map<int,int> rem;
	
	int remm = 0;
	
	rem[0] = 1;
	
	ll res = 0;
	
	int ten = 1;
	
	for(int i=n-1;i>=0;i--)
	{
		remm = (remm + (s[i]-'0')*ten)%2019;
		
		res += rem[remm];
		
		rem[remm]++;
		
		ten *= 10;
		
		ten %= 2019;
	}
	
	cout<<res;
}

signed main()
{
 
    fast;
 
    ll t;
    
    t=1;
    
    //cin>>t;
    
    while(t--)
    {
        solve();
    }
 
    return 0;
}
