#include <bits/stdc++.h>
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
typedef long long   ll;
#define pb                push_back
#define mp                make_pair
#define all(a)            (a).begin(), (a).end()
#define clr(a,h)          memset(a, (h), sizeof(a))
#define mem(a,h)          memset(a, (h), sizeof(a))
#define fi first
#define se second
#define por(a,b) (((a%MOD) * (b%MOD))%MOD)
#define forg(i, b, e, c)    for (ll i = (ll)b; i < (ll)e; i+=c)
#define forr(i, b, e)    for (ll i = b; i < e; i++)
 
 
using namespace std;
//using namespace __gnu_pbds;
typedef double lldb;
typedef pair<int, int>  ii;
typedef pair<ll, ii>  iii;
typedef vector<ll>     vi;
typedef vector<vi>     vvi;
typedef vector<ii>      vii;
typedef vector<ll>      vll;
//typedef tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update> ordered_set;
const ll INF = 1e9;
const double PI = acos(-1);
#define tam 300000
#define offset 
const ll MOD= 1e9+7;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());


#define sim template < class c
#define ris return * this
#define dor > debug & operator <<
#define eni(x) sim > typename \
  enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) {

template < class c > struct rge { c b, e; };
template < class c > rge<c> range(c i, c j) { return rge<c>{i, j}; }
template < class c > auto dud(c* x) -> decltype(cerr << *x, 0);
template < class c > char dud(...);

struct debug {
    ~debug() { cerr << endl; }
    
    //     Part 1
    
    template < class c > typename \
    enable_if<sizeof dud<c>(0) != 1, debug&>::type operator<<(c i) {
        cerr << boolalpha << i;
        return * this;
    }
    
    //     Part 2
    
    template < class c > typename \
    enable_if<sizeof dud<c>(0) == 1, debug&>::type operator<<(c i) {
        return * this << range(begin(i), end(i)); 
    }
    
    //   Part 3
    
    template < class c, class b > debug & operator << (pair < b, c > d) {
        return * this << "(" << d.first << ", " << d.second << ")";
    }
    
    //   Part 4
    
    template < class c > debug & operator <<(rge<c> d) {
        *this << "[";
        for (auto it = d.b; it != d.e; ++it)
            *this << ", " + 2 * (it == d.b) << *it;
        return * this << "]";
    }
    
};
#define qwer(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "

int mapa[3000][3000];
int main()
{
    

    string txt;
    cin>>txt;
    int val=0,base=1;
    const int m=2019;


    forr(i,0,txt.size())
    {
        val*=10;
        val+=txt[i]-'0';
        val%=m;
        mapa[base][val]++;
        base*=10;
        base%=m;
    }
    val=0;
    base=1;
    ll formas=0;
    forr(i,0,txt.size())
    {
        
        val*=10;
        val+=txt[i]-'0';
        val%=m;
        if (val==0)
            formas++;
        mapa[base][val]--;
        int auxval=val,auxbase=base;
        forr(j,0,224)
        {
            formas+=mapa[auxbase][(auxval)%m];

            auxval*=10;
            auxbase*=10;
            auxbase%=m;
            auxval%=m;
        }
        base*=10;
        base%=m;
    }

    cout<<formas<<endl;
}
// PLUS ULTRA!
    

Measured memory_bytes: 6328