### BUGGY CODE ###

## coding: UTF-8
from decimal import *
from itertools import permutations, combinations,combinations_with_replacement,product
import math


#計算量を無視して愚直に実装してみる
S = input() #文字列型で受け取る
N = len(S)
#print(len(S))

a = []
tmp = 0
for i in range(N):
    tmp = (tmp + int(S[i])) % 3
    a.append(tmp)
#print(a)




b = [(n+1)%3 for n in a]
c = [(n+2)%3 for n in a]
#print(b)
#print(c)

a_0 = []
b_0 = []
c_0 = []

for i in range(N):
    if(a[i] == 0):
        a_0.append(i)
    elif(b[i] == 0):
        b_0.append(i)
    else:
        c_0.append(i)
#print(a_0)
#print(b_0)
#print(c_0)

status = 'a'
counter = 0
#start = 0 #スタート地点最初は0
for start in range(N):
    #print('start:{}'.format(start))
    if(status == 'a'):
        for goal in a_0:
            if(start < goal):
                s = S[start:goal+1]
                #print(s)
                if(int(s) % 2019 == 0):
                    counter += 1
        if(int(S[start]) % 3 == 1):
            status = 'c'
        elif(int(S[start]) % 3 == 2):
            status = 'b'
    elif(status == 'b'):
        for goal in b_0:
            if(start < goal):
                s = S[start:goal+1]
                #print(s)
                if(int(s) % 2019 == 0):
                    counter += 1
        if(int(S[start]) % 3 == 1):
            status = 'a'
        elif(int(S[start]) % 3 == 2):
            status = 'c'
    elif(status == 'c'):
        for goal in c_0:
            if(start < goal):
                s = S[start:goal+1]
                #print(s)
                if(int(s) % 2019 == 0):
                    counter += 1
        if(int(S[start]) % 3 == 1):
            status = 'b'
        elif(int(S[start]) % 3 == 2):
            status = 'a'
print(counter)





'''
#5桁以上しか探索しないコード
sg = []
for i in range(N):
    j = 5
    while i+j <= N:
        sg.append([i, i+j])
        j += 1
#print(sg)
counter = 0
for i in range(len(sg)):
    s = S[sg[i][0]:sg[i][1]]
    if(int(s)%2019==0):
        counter += 1
        print('hit at s:{}, len(s):{}'.format(s, len(s)))
print(counter)
'''


'''
index = [i for i in range(len(S))]
combi = list(combinations(index, 2))
#print(combi)

counter = 0
for i in range(len(combi)):
    #print()
    #print('start:{},goal:{}'.format(combi[i][0], combi[i][1]+1))
    s = S[combi[i][0]:combi[i][1]+1]
    #print('s:{},s%2019:{}'.format(s, int(s)%2019))
    #print()
    if(int(s) % 2019 == 0):
        #print('hit')
        counter += 1
print(counter)
'''


'''
#実験1
def is_there_0(K):
    #文字列入力
    ret = 'No'
    for i in range(len(K)):
        if(K[i] == '0'):
            ret = 'Yes'
    return ret

for i in range(1000000000000000):
    if(is_there_0(str(2019*i)) == 'No'):
        print('i:{}, 2019*i:{},len(s):{}'.format(i, 2019*i, len(str(2019*i))))
'''
'''
for i in range(10):
    print((i*100000)%2019)
'''




















'''
#実験2
l = []
for i in range(10000):
    l.append( (2019*i)%10000 )

l = sorted(l)
#print(l)
print(len(l))
'''


### FIXED CODE ###

## coding: UTF-8

S = input()[::-1] #文字列型で受け取る
N = len(S)
#print(S)

remainder = [0] * 2019
tmp = 0
rad = 1 # *10**(i) % 2019
for i in range(N):
    r = int(S[i])
    tmp += r*rad
    tmp %= 2019
    #print(tmp)
    remainder[tmp] += 1
    rad *= 10
    rad %= 2019

    #print(S[i:], int(S[i:])%2019)
    #remainder[int(S[i:])%2019]+= 1
remainder[0] += 1
#print(-1)



answer = 0
for i in range(2019):
    p = remainder[i]
    answer += p*(p-1)/2
print(int(answer))