#include<algorithm>
#include<cmath>
#include<cstdio>
#include<functional>
#include<iomanip>
#include<iostream>
#include<numeric>
#include<math.h>
#include<map>
#include<queue>
#include<set>
#include<string>
#include<utility>
#include<vector>
// 追加１
#include <fstream>



using namespace std;
typedef long long ll;
typedef pair<ll, ll> P;
const ll mod = 2019;
#define rep(i,n) for(int i=0;i<n;i++)
#define repl(i,s,e) for(int i=s;i<e;i++)
#define reple(i,s,e) for(int i=s;i<=e;i++)
#define revrep(i,n) for(int i=n-1;i>=0;i--)
#define all(x) (x).begin(),(x).end()


ll pmod(ll n, ll p) {
    ll m = n % mod;
    if (p == 0) return 1;
    ll rtn = pmod((m * m) % mod, p / 2) % mod;
    if (p % 2 == 1) rtn = rtn * m % mod;
    return rtn;
}

ll modinv(ll n) {
    return pmod(n, mod - 2);
}

int main()
{
    string S;
    cin >> S;

    vector<int> X(S.size() + 1, 0);

    int tmp = 1;

    for(int i = S.size() - 1;i >= 0;i--)
    {
        int a = S[i] - '0';
        X[i] = (a * tmp + X[i + 1]) % mod;
        tmp *= 10;
        tmp %= mod;
    }

    vector<vector<int>> R(2019, vector<int>());

    rep(i, S.size())
    {
        R[X[i]].push_back(i);
    }

    ll count = 0;

    rep(i, S.size())
    {
        int idx = S.size() - i;

        int m = 0;
        if (idx < S.size()) m = X[idx];

        auto iter = lower_bound(all(R[m]), idx);

        count += distance(R[m].begin(), iter);
    }

    cout << count << endl;

    return 0;
}