#include <iostream>
#include <queue>
#include <map>
#include <bitset>
#include <string>
#include <set>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <iomanip>
#include <ctime>
#include <stack>
#include <cstdlib>
#include <numeric>
#include <cassert>
#include <complex>
#include <iterator>
//#include <unordered_map>
using namespace std;
#define maxn 100007
#define maxm 500007
#define maxq 1000007
#define maxl 1234
#define modn 1000000007
#define scan(a) scanf("%d",&a)
#define scanl(a) scanf("%lld",&a)
#define scanl2(a,b) scanf("%lld%lld",&a,&b)
#define scans(a) scanf("%s",a)
#define scans2(a,b) scanf("%s%s",a,b)
#define scand(a) scanf("%lf",&a)
#define scan2(a,b) scanf("%d%d",&a,&b)
#define scand2(a,b) scanf("%lf%lf",&a,&b)
#define scan3(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define scan4(a,b,c,d) scanf("%d%d%d%d",&a,&b,&c,&d)
#define scan5(a,b,c,d,e) scanf("%d%d%d%d%d",&a,&b,&c,&d,&e)
#define print(a) printf("%d\n",a);
#define print2(a,b) printf("%d %d\n",a,b);
#define printl(a) printf("%lld\n",a);
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define rrep(i,a,b) for(int i=a;i>= b;i--)
#define fscan(a) fscanf(stream,"%d", &a);
#define mp      make_pair	
#define pb      push_back
#define eb      emplace_back
#define mm(a,b) memset(a,b,sizeof a)
#define log2(n) (double)(log(n) / log(2.0))
#define _crt_disable_perfcrit_locks
#define bll __int128
#pragma warning(disable:4996)
typedef long long ll;
typedef unsigned long long ull;
const int inf = 0x3f3f3f3f;
typedef vector <int> vi;
typedef vector <ll> vll;
typedef map <ll, ll> mll;
typedef pair <ll, ll> pll;
typedef map <int, int> mii;
typedef pair <int, int> pii;
typedef map <char, int> mci;
typedef map <char, char> mcc;
typedef pair <char, int> pci;
typedef complex<double> cd;
typedef vector<complex<double> > vcd;
const double eps = 1e-8;
const double PI = 2 * acos(0.0);

ll cc, bb; char ch; inline ll F() {
	while (ch = getchar(), (ch < 48 || ch> 57) && ch != '-'); ch == '-' ? cc = bb = 0 : (cc = ch - '0', bb = 1);
	while (ch = getchar(), ch > 47 && ch < 58)cc = (cc << 1) + (cc << 3) + (ch ^ 48); return bb ? cc : -cc;
}
void write(int x) {
	int y = 10, len = 1;
	while (y <= x) { y *= 10; len++; }
	while (len--) { y /= 10; putchar(x / y + 48); x %= y; }
}
ll gcd(ll a, ll b) {
	ll r;
	if (a < 0)a = -a;
	if (b < 0)b = -b;
	while (b != 0) {
		r = a % b;
		a = b;
		b = r;
	}
	return a;
}
ll mod_mul(ll a, ll b, ll mod) {
	ll res = 0;
	while (b) {
		if (b & 1) if ((res += a) > mod)res -= mod;
		if ((a <<= 1) > mod)a -= mod;
		b >>= 1;
	}
	return res;
}
ll pow2(ll a, ll b, ll mod) {
	ll r = 1, base = a;
	while (b) {
		if (b & 1) r = mod_mul(r, base, mod);
		base = mod_mul(base, base, mod);
		b >>= 1;
	}
	return r;
}
ll inv(ll a, ll n) {
	return pow2(a, n - 2, n);
	//return pow2(a, oula(n) - 1, n);
}
bool MillerRabin(ll n) {
	if (n < 2)return false;
	if (n == 2)return true;
	if (!(n & 1))return false;
	ll u = n - 1;
	while (!(u & 1))u >>= 1;
	ll m = u;
	ll a[13] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37 };
	for (int i = 0; i < 12; i++) {
		if (a[i] >= n)
			break;
		ll x = pow2(a[i], u, n);
		ll y;
		while (u < n) {
			y = pow2(x, 2, n);
			if (y == 1 && x != 1 && x != n - 1)
				return false;
			x = y;
			u <<= 1;
		}
		if (x != 1)return false;
		u = m;
	}
	return true;
}
vector<ll> prime;
ll find_factorplus(ll n, ll c) {//pollard-rho函数
	ll i = 1, k = 2;
	ll x0 = rand() % (n - 1) + 1;//随机一个因子来判断
	ll y = x0;
	while (1) {
		i++;
		x0 = (mod_mul(x0, x0, n) + c) % n;
		ll d = gcd(y - x0, n);
		if (d != 1 && d != n) return d;
		if (y == x0) return n;
		if (i == k) {
			y = x0;
			k += k;
		}
	}
}
void find(ll n, ll c) {
	if (n == 1) return;
	if (MillerRabin(n)) {
		prime.push_back(n);
		return;
	}
	ll x = n, k = c;
	while (x == n) {
		x = find_factorplus(x, c--);
	}
	find(n / x, k);
	find(x, k);
}
ll extend_gcd(ll a, ll  b, ll& x, ll& y) {
	if (b == 0) { x = 0; y = 1; return a; };
	if (a % b == 0) {
		x = 0;
		y = 1;
		return b;
	}
	ll res = extend_gcd(b, a % b, y, x);
	y -= a / b * x;
	return res;
}
vector<ll> w;
void fj(ll a) {
	for (ll i = 1; i * i <= a; i++)
		if (!(a % i)) {
			w.push_back(i);
			if (i * i != a)
				w.push_back(a / i);
		}

}


int main() {
	//ios::sync_with_stdio(0);
	//cin.tie(0);
	//FILE* stream = fopen("L:/20.in", "rb+")
	clock_t start, end;
	start = clock();

	/*int s, w;
	scan2(s, w);
	if (s > w)printf("safe\n");
	else printf("unsafe\n");*/
	/*int a, b, c, d;
	scan4(a, b, c, d);
	int e = (a + d - 1) / d, f = (c + b - 1) / b;
	if (e < f)printf("No\n");
	else printf("Yes\n");*/
	/*map<string,int> gg;
	int n;
	string s;
	cin >> n;
	for (int i = 0; i < n ; i++){
		cin >> s;
		gg[s]++;
	}
	cout << gg.size() << endl;*/
	string s;
	cin >> s;
	int len = s.length();
	reverse(s.begin(), s.end());
	ll sum[2222] = { 1 };
	int now = 0;
	int p = 1;
	for (int i = 0; i < len; i++) {
		now += (s[i] - '0') * p;
		p = p * 10 % 2019;
		now %= 2019;
		sum[now]++;
	}
	ll res = 0;
	rep(i, 0, 2018)
		res += sum[i] * (sum[i] - 1) / 2;
	cout << res << endl;

	end = clock();
	cerr << (end - start) * 1000.0 / CLOCKS_PER_SEC << "ms\n";
	return 0;
}

Measured memory_bytes: 3876