CodeEff/ECCO huggingface dataset:
# Original solution
from collections import Counter
S = str(eval(input()))
N = len(S)

#smod = [int(S[i:])%2019 for i in range(N)]
smod = [0]
tmod = 0
keta = 1
for i in range(N):
    temp = tmod + int(S[(N-1)-i])*keta
    #print(temp)
    tmod = temp%2019
    smod.append(tmod)
    keta *= 10


cmod = Counter(smod)
#print(cmod)

ans = 0
for i in list(cmod.values()):
    ans += i*(i-1)/2
print((int(ans)))

# Optimized solution
from collections import Counter
S = str(eval(input()))
N = len(S)

#smod = [int(S[i:])%2019 for i in range(N)]
smod = [0]
tmod = 0
keta = 1
for i in range(N):
    temp = tmod + int(S[(N-1)-i])*keta
    #print(temp)
    tmod = temp%2019
    smod.append(tmod)
    keta = keta*10%2019


cmod = Counter(smod)
#print(cmod)

ans = 0
for i in list(cmod.values()):
    ans += i*(i-1)/2
print((int(ans)))
# Original solution
s = input()[::-1]
n = len(s)
amari = [0]*2019
amari[0] = 1

temp = 0
d = 1
for char in s:
    temp += int(char)*d
    temp %= 2019
    amari[temp] += 1
    d *= 10

ans = 0
for i in amari:
    ans += i*(i-1)/2

print((int(ans)))



# Optimized solution
s = input()[::-1]
n = len(s)
amari = [0]*2019
amari[0] = 1

temp = 0
d = 1
for char in s:
    temp += int(char)*d
    temp %= 2019
    d *= 10
    d %= 2019  
    amari[temp] += 1

ans = 0
for i in amari:
    ans += i*(i-1)/2

print((int(ans)))
# Original solution
s = input()[::-1]

sum_of_digits = 0

cnts = [0] * 2019

cnts[0] = 1

d = 1

for c in s:
    sum_of_digits += int(c) * d
    sum_of_digits %= 2019
    d *= 10
    d %= 2019
    cnts[sum_of_digits] += 1

ans = 0
    
for cnt in cnts:
    ans += cnt * (cnt - 1) // 2

print(ans)


# Optimized solution
s = input()[::-1]
n = len(s)
counts = [0] * 2019
counts[0] = 1
current = 0
d = 1

for c in s:
    current += int(c) * d
    d *= 10
    current %= 2019
    d %= 2019
    counts[current] += 1

ans = 0
for count in counts:
    if count > 1:
        # print(i)
        ans += count * (count-1) //2
print(ans)
# Original solution
def main():
    import sys
    input = sys.stdin.readline
    from collections import defaultdict
    S = input().rstrip()
    counter = defaultdict(int)
    mod = 2019
    counter[0] += 1
    num = 0
    for i, c in enumerate(S[::-1]):
        num += int(c) * (10**(i)%mod)
        num %= mod
        counter[num] += 1
    ans = 0
    for v in list(counter.values()):
        ans += (v * (v-1)) // 2
    print(ans)

if __name__ == '__main__':
    main()

# Optimized solution
def main():
    import sys
    input = sys.stdin.readline
    from collections import defaultdict
    S = input().rstrip()
    counter = defaultdict(int)
    mod = 2019
    counter[0] += 1
    num = 0
    d = 1
    for c in S[::-1]:
        num += int(c) * d
        num %= mod
        counter[num] += 1
        d *= 10
        d %= mod
    ans = 0
    for v in list(counter.values()):
        ans += (v * (v-1)) // 2
    print(ans)

if __name__ == '__main__':
    main()
# Original solution
s = str(eval(input()))

num = [int(s[-1])]
for i in range(1, len(s)):
    num.append(num[-1] + pow(10, i) * int(s[-i - 1]))

mod = [1] + [0] * 2018
ans = 0
for i in num:
    m = i % 2019
    ans += mod[m]
    mod[m] += 1
print(ans)


# Optimized solution
s = str(eval(input()))

num = [int(s[-1])]
for i in range(1, len(s)):
    tmp = num[-1] + pow(10, i, 2019) * int(s[-i - 1])
    num.append(tmp % 2019)

mod = [1] + [0] * 2018
ans = 0
for i in num:
    m = i % 2019
    ans += mod[m]
    mod[m] += 1
print(ans)
# Original solution
#!/usr/bin/env python3
s = str(eval(input()))

mod = 2019

div_memo = [0 for _ in range(mod)]
for i in range(1, len(s)+1):
    # print(s[len(s)-i:])
    div = (int(s[len(s)-i:]) % mod)
    div_memo[div] += 1

ans = 0
for i in range(len(div_memo)):
    ans += div_memo[i]*(div_memo[i]-1)//2

ans += div_memo[0]
print((int(ans)))


# Optimized solution
#!/usr/bin/env python3
s = str(eval(input()))

mod = 2019

div_memo = [0 for _ in range(mod)]

num = 0
d = 1
for n in reversed(s):
    num += int(n)*d
    num %= 2019
    div_memo[num] += 1
    d *= 10
    d %= 2019

ans = 0
for i in range(len(div_memo)):
    ans += div_memo[i]*(div_memo[i]-1)//2

ans += div_memo[0]
print((int(ans)))
# Original solution
s = input()[::-1] # 入力文字列を逆順でsに格納

counts = [0] * 2019 # mod 2019での結果を入れる箱（0 ~ 2018）
counts[0] = 1 # T_n = 0　のとき

num, d = 0, 1

for char in s:
    num += int(char) * d # 一の位から順に足していく
    d *= 10
    counts[num % 2019] += 1
    
ans = 0
for cnt in counts:
    ans += cnt * (cnt-1) //2 # n_C_2 
    
print(ans)

# Optimized solution
s = input()[::-1] # 入力文字列を逆順でsに格納

counts = [0] * 2019
counts[0] = 1

num, d = 0, 1

for char in s:
    num += int(char) * d
    num %= 2019
    d *= 10
    d%= 2019
    counts[num] += 1

ans = 0
for cnt in counts:
    ans += cnt * (cnt - 1) // 2

print(ans) # 答えの出力
# Original solution
s = str(eval(input()))
L = len(s)
dict = [0] * 2019
dict[0] += 1
num = 0
for i in range(L-1, (-1), (-1)):
    num += (int(s[i]) * pow(10,(L-i-1)))%2019
    amari = num % 2019
    dict[amari] += 1
ans = 0
for j in range(2019):
    ans += (dict[j]*(dict[j]-1))/2
print((int(ans)))

# Optimized solution
s = str(eval(input()))
L = len(s)
dict = [0] * 2019
dict[0] += 1
num = 0
for i in range(L-1, (-1), (-1)):
    num += (int(s[i]) * pow(10,(L-i-1), 2019))%2019
    amari = num % 2019
    dict[amari] += 1
ans = 0
for j in range(2019):
    ans += (dict[j]*(dict[j]-1))/2
print((int(ans)))
# Original solution
from collections import Counter

# forを逆から回して下から素直にmodを取るとTLEだった
# 累積和的な計算で高速化、やりやすくするためにreverse
S = input()[::-1]
# ex. 1817181712114 → 4112171817181
# print(S)

# 0桁目までのMODを0とすることで、
# 1桁目を含む数が2019の倍数の時に都合が良くなる
X = [0]

# 4,14,114,2114,12114,...のmod2019を計算

for i, s in enumerate(S):
    X.append((X[-1] + int(s) * pow(10, i, 2019)) % 2019)
# print(X)


C = Counter(X)
# print(C)

ans = 0
# Xが同じになったところを2つ選べば題意を満たす
# v_C_2の計算
for v in list(C.values()):
    ans += v * (v - 1) // 2

print(ans)


# Optimized solution
from collections import Counter

# forを逆から回して下から素直にmodを取るとTLEだった
# 累積和的な計算で高速化、やりやすくするためにreverse
S = input()[::-1]
# ex. 1817181712114 → 4112171817181
# print(S)

# 0桁目までのMODを0とすることで、
# 1桁目を含む数が2019の倍数の時に都合が良くなる
X = [0]

# 4,14,114,2114,12114,...のmod2019を計算

# pow(a,b,c)は普通にMODするより速い
# 普通にやったらTLEだった
for i, s in enumerate(S):
    X.append((X[-1] + int(s) * pow(10, i, 2019)) % 2019)
# print(X)


C = Counter(X)
# print(C)

ans = 0
# Xが同じになったところを2つ選べば題意を満たす
# v_C_2の計算
for v in list(C.values()):
    ans += v * (v - 1) // 2

print(ans)
# Original solution
from collections import Counter

# forを逆から回して下から素直にmodを取るとTLEだった
# 累積和的な計算で高速化、やりやすくするためにreverse
S = input()[::-1]
# ex. 1817181712114 → 4112171817181
# print(S)

# 0桁目までのMODを0とすることで、
# 1桁目を含む数が2019の倍数の時に都合が良くなる
X = [0]

# 4,14,114,2114,12114,...のmod2019を計算

for i, s in enumerate(S):
    X.append((X[-1] + int(s) * 10 ** i) % 2019)
# print(X)


C = Counter(X)
# print(C)

ans = 0
# Xが同じになったところを2つ選べば題意を満たす
# v_C_2の計算
for v in list(C.values()):
    ans += v * (v - 1) // 2

print(ans)


# Optimized solution
from collections import Counter

# forを逆から回して下から素直にmodを取るとTLEだった
# 累積和的な計算で高速化、やりやすくするためにreverse
S = input()[::-1]
# ex. 1817181712114 → 4112171817181
# print(S)

# 0桁目までのMODを0とすることで、
# 1桁目を含む数が2019の倍数の時に都合が良くなる
X = [0]

# 4,14,114,2114,12114,...のmod2019を計算

# pow(a,b,c)は普通にMODするより速い
# 普通にやったらTLEだった
for i, s in enumerate(S):
    X.append((X[-1] + int(s) * pow(10, i, 2019)) % 2019)
# print(X)


C = Counter(X)
# print(C)

ans = 0
# Xが同じになったところを2つ選べば題意を満たす
# v_C_2の計算
for v in list(C.values()):
    ans += v * (v - 1) // 2

print(ans)
# Original solution
# import itertools
S = input()[::-1]
# l = len(S)
# nums = range(1, l+1)
count = [0]*2019
count[0] = 1
num = 0
d = 1
for i in S:
    num += int(i)*d
    count[num % 2019] += 1
    d *= 10
    d %= 2019

ans = 0
for i in count:
    ans += i*(i-1)//2
print(ans)


# Optimized solution
# import itertools
S = input()[::-1]
# l = len(S)
# nums = range(1, l+1)
count = [0]*2019
count[0] = 1
num = 0
d = 1
for i in S:
    num += int(i)*d
    num %= 2019
    count[num] += 1
    d *= 10
    d %= 2019

ans = 0
for i in count:
    ans += i*(i-1)//2
print(ans)
# Original solution
import itertools
N = int(eval(input()))
f_can = list(itertools.combinations(list(range(len(str(N))+1)),2))
s_can = [[int(f), int(b)] for f,b in f_can if int(b)-int(f)>3]
t_can = [str(N)[int(f): int(b)] for f,b in s_can if int(b)-int(f)>3]
print((len([i for i in t_can if int(i)%2019==0])))

# Optimized solution
import itertools
N = int(eval(input()))
f_can = itertools.combinations(list(range(len(str(N))+1)),2)
s_can = [str(N)[int(f):int(b)] for f,b in f_can if int(b)-int(f)>3]
print((len([i for i in s_can if int(i)%2019==0])))
# Original solution
# -*- coding: utf-8 -*-
import sys
import math
import os
import itertools
import string
import heapq
import _collections
from collections import Counter
from collections import defaultdict
from collections import deque
from functools import lru_cache
import bisect
import re
import queue
import decimal


class Scanner():
    @staticmethod
    def int():
        return int(sys.stdin.readline().rstrip())

    @staticmethod
    def string():
        return sys.stdin.readline().rstrip()

    @staticmethod
    def map_int():
        return [int(x) for x in Scanner.string().split()]

    @staticmethod
    def string_list(n):
        return [Scanner.string() for i in range(n)]

    @staticmethod
    def int_list_list(n):
        return [Scanner.map_int() for i in range(n)]

    @staticmethod
    def int_cols_list(n):
        return [Scanner.int() for i in range(n)]


# MOD = int(1e09) + 7
MOD = 2019
INF = int(1e15)


def solve():
    S = Scanner.string()
    N = len(S)
    S = S[::-1]
    p = 1
    total = 0
    cnt = [0 for _ in range(MOD)]
    ans = 0
    for i in range(N):
        cnt[total] += 1
        total += int(S[i]) * p
        total %= MOD
        ans += cnt[total]
        p = p * 10 % MOD
    print(ans)


def main():
    # sys.setrecursionlimit(1000000)
    # sys.stdin = open("sample.txt")
    # T = Scanner.int()
    # for _ in range(T):
    #     solve()
    # print('YNeos'[not solve()::2])
    solve()


if __name__ == "__main__":
    main()


# Optimized solution
# -*- coding: utf-8 -*-
import sys
import math
import os
import itertools
import string
import heapq
import _collections
from collections import Counter
from collections import defaultdict
from collections import deque
from functools import lru_cache
import bisect
import re
import queue
import decimal


class Scanner():
    @staticmethod
    def int():
        return int(sys.stdin.readline().rstrip())

    @staticmethod
    def string():
        return sys.stdin.readline().rstrip()

    @staticmethod
    def map_int():
        return [int(x) for x in Scanner.string().split()]

    @staticmethod
    def string_list(n):
        return [Scanner.string() for i in range(n)]

    @staticmethod
    def int_list_list(n):
        return [Scanner.map_int() for i in range(n)]

    @staticmethod
    def int_cols_list(n):
        return [Scanner.int() for i in range(n)]


MOD = 2019
# INF = int(1e15)


def solve():
    S = Scanner.string()
    S = S[::-1]
    cnt = [0 for _ in range(MOD)]
    tmp = 0
    ans = 0
    x = 1
    for s in S:
        cnt[tmp] += 1
        tmp += int(s) * x
        tmp %= MOD
        x *= 10
        x %= MOD
        ans += cnt[tmp]
    print(ans)


def main():
    # sys.setrecursionlimit(1000000)
    # sys.stdin = open("sample.txt")
    # T = Scanner.int()
    # for _ in range(T):
    #     solve()
    # print('YNeos'[not solve()::2])
    solve()


if __name__ == "__main__":
    main()
# Original solution
s = input()[::-1]

sum_of_digits = 0

cnts = [0] * 2019

cnts[0] = 1

d = 1

for c in s:
    sum_of_digits += int(c) * d
    sum_of_digits %= 2019
    d *= 10
#    d %= 2019
    cnts[sum_of_digits] += 1

ans = 0
    
for cnt in cnts:
    ans += cnt * (cnt - 1) // 2

print(ans)

# Optimized solution
s = input()[::-1]

sum_of_digits = 0

cnts = [0] * 2019

cnts[0] = 1

d = 1

for c in s:
    sum_of_digits += int(c) * d
    sum_of_digits %= 2019
    d *= 10
    d %= 2019
    cnts[sum_of_digits] += 1

ans = 0
    
for cnt in cnts:
    ans += cnt * (cnt - 1) // 2

print(ans)
# Original solution
#!/usr/bin/env python3
import sys
from collections import Counter

def solve(S: str):
    # S[i, j) % 2019 == 0となる(i, j)の数
    # S[i..n) - S[j, n) === 0 (mod 2019)
    # 累積mod c[i] = S[i:]
    n = len(S)
    c = [0] * (n + 1)
    for i in range(n):
        c[i] = int(S[i:]) % 2019
    print((sum(v * (v - 1) // 2 for v in list(Counter(c).values()))))


# Generated by 1.1.6 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word

    tokens = iterate_tokens()
    S = next(tokens)  # type: str
    solve(S)


if __name__ == "__main__":
    main()


# Optimized solution
#!/usr/bin/env python3
import sys
from collections import Counter


def solve(S: str):
    # S[i, j) % 2019 == 0となる(i, j)の数
    # S[i..n) - S[j, n) === 0 (mod 2019)
    # 累積mod c[i] = S[i:]
    n = len(S)
    c = [0] * (n + 1)  # c[i] = int(S[i:]) % 2019
    for i in reversed(list(range(n))):
        c[i] = (c[i + 1] + int(S[i]) * pow(10, n - 1 - i, 2019)) % 2019
    print((sum(v * (v - 1) // 2 for v in list(Counter(c).values()))))


# Generated by 1.1.6 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word

    tokens = iterate_tokens()
    S = next(tokens)  # type: str
    solve(S)


if __name__ == "__main__":
    main()
# Original solution
import collections
S=str(eval(input()))

T=[0 for i in range(len(S))]
T[0]=int(S[-1])

for i in range(1,len(S)):
    T[i]=((10**i)*int(S[len(S)-1-i])+T[i-1])%2019
    
cnt=0
T_di=collections.Counter(T)

for key in list(T_di.keys()):
    x=T_di[key]
    cnt+=x*(x-1)/2
    if key==0:
        cnt+=x

print((int(cnt)))

# Optimized solution
import collections
S=str(eval(input()))

T=[0 for i in range(len(S))]
T[0]=int(S[-1])

for i in range(1,len(S)):
    T[i]=(pow(10,i,2019)*int(S[len(S)-1-i])+T[i-1])%2019
    
cnt=0
T_di=collections.Counter(T)

for key in list(T_di.keys()):
    x=T_di[key]
    cnt+=x*(x-1)/2
    if key==0:
        cnt+=x

print((int(cnt)))
# Original solution
from collections import Counter
s = input()[::-1]
T = [0]*(len(s)+1)
digit = 1

for i in range(1,len(s)+1):
    T[i] = (T[i-1]+digit*int(s[i-1])) % 2019
    digit = digit * 10

S = Counter(T)
ans=0
for i in list(S.values()):
    ans+=(i*(i-1))//2

print(ans)

# Optimized solution
from collections import Counter
s = input()[::-1]
T = [0]*(len(s)+1)
digit = 1

for i in range(1,len(s)+1):
    T[i] = (T[i-1]+digit*int(s[i-1]))
    T[i] = T[i] % 2019
    digit = digit * 10
    digit = digit % 2019

S = Counter(T)
ans = 0
for i in list(S.values()):
    ans+=(i*(i-1))//2

print(ans)
# Original solution
from sys import stderr
from functools import reduce

def debug(*args):
    print(*args, file=stderr)

s = input()

checked = {}

for left_i in range(len(s)):
    for right_i in range(left_i + 1, len(s) + 1):
        now_checking_str = s[left_i:right_i]

        if not now_checking_str in checked:
            checked[now_checking_str] = 0

        debug(left_i, right_i, now_checking_str)

        now_checking_int = int(now_checking_str)
        checked[now_checking_str] += 1 if now_checking_int % 2019 == 0 else 0

debug(checked)

result = reduce(lambda x, y: x+y, checked.values(), 0)
print(result)


# Optimized solution
# from sys import stderr
from functools import reduce

def debug(*args):
    print(*args, file=stderr)

s = input()

checked = {}

for left_i in range(len(s)):
    for right_i in range(left_i + 1, len(s) + 1):
        now_checking_str = s[left_i:right_i]

        if not now_checking_str in checked:
            checked[now_checking_str] = 0

        # debug(left_i, right_i, now_checking_str)

        now_checking_int = int(now_checking_str)
        checked[now_checking_str] += 1 if now_checking_int % 2019 == 0 else 0

# debug(checked)

result = reduce(lambda x, y: x+y, checked.values(), 0)
print(result)
# Original solution
from sys import stderr
from functools import reduce

def debug(*args):
    print(*args, file=stderr)

s = input()

checked = {}

for left_i in range(len(s)):
    for right_i in range(left_i + 1, len(s) + 1):
        now_checking_str = s[left_i:right_i]

        if not now_checking_str in checked:
            checked[now_checking_str] = 0

        debug(left_i, right_i, now_checking_str)

        now_checking_int = int(now_checking_str)
        checked[now_checking_str] += 1 if now_checking_int % 2019 == 0 else 0

debug(checked)

result = reduce(lambda x, y: x+y, checked.values(), 0)
print(result)


# Optimized solution
# from sys import stderr
from functools import reduce

def debug(*args):
    print(*args, file=stderr)

s = input()

checked = {}

for left_i in range(len(s)):
    for right_i in range(left_i + 1, len(s) + 1):
        now_checking_str = s[left_i:right_i]

        if not now_checking_str in checked:
            checked[now_checking_str] = 0

        elif checked[now_checking_str] > 0:
            checked[now_checking_str] += 1
            continue

        # debug(left_i, right_i, now_checking_str)

        now_checking_int = int(now_checking_str)
        checked[now_checking_str] += 1 if now_checking_int % 2019 == 0 else 0

# debug(checked)

result = reduce(lambda x, y: x+y, checked.values(), 0)
print(result)


# echo "1817181712114" | python3 d.py && echo "14282668646" | python3 d.py && echo "2119" | python3 d.py
# Original solution
def main():
    s = input()[::-1]

    sum_of_digits = 0

    cnts = [0] * 2019

    cnts[0] = 1

    for i in range(len(s)):
        sum_of_digits += int(s[i]) * pow(10, i) % 2019
        sum_of_digits %= 2019
        cnts[sum_of_digits] += 1


    ans = 0

    for cnt in cnts:
        ans += cnt * (cnt - 1) // 2

    print(ans)

if __name__ == '__main__':
    main()


# Optimized solution
def main():
    s = input()[::-1]

    sum_of_digits = 0

    cnts = [0] * 2019

    cnts[0] = 1

    d = 1

    for i in range(len(s)):
        sum_of_digits += int(s[i]) * d
        d *= 10
        d %= 2019
        sum_of_digits %= 2019
        cnts[sum_of_digits] += 1


    ans = 0

    for cnt in cnts:
        ans += cnt * (cnt - 1) // 2

    print(ans)

if __name__ == '__main__':
    main()
# Original solution
S=str(eval(input()))
N=len(S)
counter=[0]*2019
counter[0]=1
ans=0
for i in range(1,N+1):
    s=S[-i:]
    r=int(s)%2019
    counter[r]+=1
for i in counter:
    ans += i*(i-1)//2
print(ans)

# Optimized solution
#https://mirucacule.hatenablog.com/entry/2020/04/27/090908
#https://drken1215.hatenablog.com/entry/2020/04/29/171300

S=str(eval(input()))[::-1]#逆順で格納
N=len(S)
counter=[0]*2019
counter[0]=1
ans=0
num,d=0,1
for c in S:
    num += int(c) * d
    num %= 2019
    d *= 10
    d %= 2019
    counter[num]+=1
for i in counter:
    ans += i*(i-1)//2
print(ans)
# Original solution
import sys
input = sys.stdin.readline
s = int(eval(input()))
n = len(str(s))
d = 1
cnt = [0]*2019
for i in range(n+1):
    cnt[(s%d)%2019] += 1
    d *= 10


#slist = [(s%(10**i))%2019 for i in range(n+1)]
#print(slist)


ans = 0
for i in range(2019):
    ans += cnt[i]*(cnt[i]-1)//2

print(ans)


# Optimized solution
s = input()[::-1]
a = 0
cnt = [0]*2019
cnt[0] = 1
d = 1
for c in s:
    a += int(c) * d
    a %= 2019
    d *= 10
    d %= 2019
    cnt[a] += 1

#slist = [(s%(10**i))%2019 for i in range(n+1)]
#print(slist)


ans = 0
for i in range(2019):
    ans += cnt[i]*(cnt[i]-1)//2

print(ans)
# Original solution
# https://atcoder.jp/contests/abc164/tasks/abc164_d

import sys
input = sys.stdin.readline


S = input().rstrip()

res = 0

x = 0
p = 1
L = len(S)
MOD = 2019
reminder = [0]*2019
reminder[0] = 1
for s in reversed(S):
    """ 累積和 """
    x = (int(s)*p + x)%MOD
    p = p*10%MOD
    reminder[x] += 1

for c in reminder:
    res += c*(c-1)//2

print(res)

# Optimized solution
# https://atcoder.jp/contests/abc164/tasks/abc164_d

import sys
input = sys.stdin.readline


S = input().rstrip()

res = 0

x = 0
p = 1
L = len(S)
MOD = 2019
reminder = [0]*2019
reminder[0] = 1
for s in reversed(S):
    """ 累積和 """
    x = (int(s)*p + x)%MOD
    p = p*10%MOD
    res += reminder[x]
    reminder[x] += 1

print(res)
# Original solution
def main(): #なんか早くなるおまじない
    import sys
    from collections import defaultdict
    dic = defaultdict(int)

    input = sys.stdin.readline #早くなるおまじない

    s = str(input().rstrip())
    m = 0

    for i in range(1, len(s) + 1):
        m_1 = pow(10, i-1) % 2019
        m_add = (int(s[-i]) * m_1) % 2019
        m = (m_add + m) % 2019
        dic[m] += 1

    ans1 = 0

    for x in list(dic.values()):
        if x > 1:
            ans1 += x * (x - 1) // 2
    ans2 = dic[0]

    print((ans1 + ans2))

if __name__ == "__main__":
    main()

# Optimized solution
def main(): #なんか早くなるおまじない
    import sys
    from collections import defaultdict
    dic = defaultdict(int)

    input = sys.stdin.readline #早くなるおまじない

    s = str(input().rstrip())
    m = 0

    for i in range(1, len(s) + 1):
        m_1 = pow(10, i-1,2019)
        m_add = (int(s[-i]) * m_1) % 2019
        m = (m_add + m) % 2019
        dic[m] += 1

    ans1 = 0

    for x in list(dic.values()):
        if x > 1:
            ans1 += x * (x - 1) // 2
    ans2 = dic[0]

    print((ans1 + ans2))

if __name__ == "__main__":
    main()
# Original solution
# coding: utf-8
# Your code here!
def main():
    from functools import reduce
    import collections
     
    S = list(map(int,input().rstrip()))
    N=len(S)
    mod_list = [0]
    for i in range(N):
        new = (mod_list[-1]+S[N-1-i]*10**i)%2019
        mod_list.append(new)
        
    count = collections.Counter(mod_list)
    ans =0
    for j in range(2019):
        n = count[j]
        ans+= n*(n-1)/2
    print((int(ans)))
if __name__ == "__main__":
    main()

# Optimized solution
# coding: utf-8
# Your code here!
def main():
    from functools import reduce
    import collections
     
    S = list(map(int,input().rstrip()))
    N=len(S)
    mod_list = [0]
    for i in range(1,N+1):
        new1 =pow(10,i-1,2019)
        new = (new1*S[-i]+mod_list[-1])%2019
        #print(new)
        mod_list.append(new)
        
    count = collections.Counter(mod_list)
    ans =0
    for j in range(2019):
        n = count[j]
        ans+= n*(n-1)/2
    print((int(ans)))
if __name__ == "__main__":
    main()
# Original solution
from sys import stdin, setrecursionlimit


def main():
    input = stdin.readline
    s = list(input()[:-1])[::-1]
    N = len(s)
    p10 = [1]
    tmp = 1
    for _ in range(N - 1):
        tmp = tmp * 10 % 2019
        p10.append(tmp)
    mod = []
    tmp = 0
    for num, p in zip(s, p10):
        tmp = (tmp + int(num) * p) % 2019
        mod.append(tmp)

    mod.sort()
    mod.insert(0, 0)

    ans = 0
    count = 1
    for i in range(1, N + 1):
        if mod[i] == mod[i - 1]:
            count += 1
        else:
            ans += count * (count - 1) // 2
            count = 1
    ans += count * (count - 1) // 2
    print(ans)


if __name__ == "__main__":
    setrecursionlimit(10000)
    main()


# Optimized solution
from sys import stdin, setrecursionlimit


def main():
    mod = 2019
    input = stdin.buffer.readline
    s = list(map(int, list(input()[:-1].decode())))
    n = len(s)
    s.reverse()

    tmp_p10 = 1
    p10 = [tmp_p10]
    for _ in range(1, n + 1):
        tmp_p10 *= 10
        tmp_p10 %= mod
        p10.append(tmp_p10)

    tmp_mod = s[0] % mod
    mods = [0, tmp_mod]
    for i in range(1, n):
        tmp_mod = (s[i] * p10[i] + tmp_mod) % mod
        mods.append(tmp_mod)
    m2019 = [0] * 2019
    for mi in mods:
        m2019[mi] += 1
    ans = 0
    for mi in m2019:
        ans += mi * (mi - 1) // 2

    print(ans)


if __name__ == "__main__":
    setrecursionlimit(10000)
    main()