#include <bits/stdc++.h>

using namespace std;
using ll = long long;
using vec = vector<ll>;
using mat = vector<vec>;
using vec_b = vector<bool>;
using vec_str = vector<string>;
using graph = mat;
using edge = pair<ll,ll>;
using wgraph = vector<vector<edge>>;

#define INF (1LL << 60)
#define MOD 1000000007

#define REP(i,m,n) for(ll (i)=(m),i##_len=(n);(i)<(i##_len);++(i))
#define FORR(i,v) for(auto (i):v)
#define ALL(x) (x).begin(), (x).end()
#define _PR(x) cout << (x) << endl
#define _PS(x) cout << (x) << " "
#define SZ(x) ((ll)(x).size())
#define MAX(a,b) (((a)>(b))?(a):(b))
#define MIN(a,b) (((a)<(b))?(a):(b))
#define pb push_back


int main()
{
    string S;
    cin >> S;
    ll N = SZ(S);
    vec csum(N+1, 0);
    ll t = 1;

    REP(i,1,N+1) {
        csum[i] = (csum[i-1] + (t * (S[N-i] - '0'))) % 2019;
        t = (t * 10) % 2019;
        //_PR(csum[i]);
    }
    
    sort(ALL(csum));
    vec C;
    ll cnt = 1;
    REP(i,1,N) {
        if(csum[i] == csum[i-1]) ++cnt;
        else {
            C.pb(cnt);
            cnt = 1;
        }
    }
    if(csum[N] == csum[N-1]) ++cnt;
    C.pb(cnt);

    REP(i,0,N+1) _PR(csum[i]);

    ll sum = 0;
    FORR(c,C) sum += c * (c - 1) / 2;
    _PR(sum);


    return 0;
}

/*



*/