CodeEff/ECCO huggingface dataset:
# Original solution
import sys
input = sys.stdin.readline
from collections import Counter
from collections import defaultdict
def main():
    S = list(map(int, input().rstrip("\r\n")))
    N = len(S)
    P = 2019
    S.reverse()
    ans = 0
    if P == 2 or P == 5:
        for i in range(N):
            if S[i] % P == 0:ans += N-i
    else:
        D = [0] * (N+1)
        tenpow = 1
        d = defaultdict(int)
        d[0] += 1
        for i in range(N):
            S[i] = S[i] * tenpow % P
            tenpow *= 10 % P
            D[i+1] = (S[i] + D[i]) % P
            d[D[i+1]] += 1
        for v in list(d.values()):
            ans += v*(v-1)//2
    print(ans)
if __name__ == "__main__":
    main()

# Optimized solution
import sys
input = sys.stdin.readline
from collections import Counter
def main():
    S = list(map(int, input().rstrip("\r\n")))
    N = len(S)
    P = 2019
    S.reverse()
    ans = 0
    if P == 2 or P == 5:
        for i in range(N):
            if S[i] % P == 0:ans += N-i
    else:
        D = [0] * (N+1)
        tenpow = 1
        for i in range(N):
            S[i] = S[i] * tenpow % P
            tenpow *= 10
            tenpow %= P
            D[i+1] = (S[i] + D[i]) % P
        c = Counter(D)
        for v in list(c.values()):
            ans += v*(v-1)//2
    print(ans)
if __name__ == "__main__":
    main()
# Original solution
from collections import defaultdict
S = input()[::-1]
mod = 2019
d = defaultdict(int)
s = ""
for i in range(len(S)):
    s = S[i] + s
    d[int(s) % mod] += 1
ans = 0
for k, v in list(d.items()):
    ans += v * (v - 1) // 2
    if k == 0:
        ans += v
print(ans)

# Optimized solution
from collections import defaultdict
S = input()[::-1]
mod = 2019
d = defaultdict(int)
ruijo = 1
tmp = 0
for i in range(len(S)):
    tmp += int(S[i]) * ruijo % mod
    d[tmp % mod] += 1
    ruijo *= 10
    ruijo %= mod
ans = 0
for k, v in list(d.items()):
    ans += v * (v - 1) // 2
    if k == 0:
        ans += v
print(ans)
# Original solution
from collections import Counter, defaultdict
a = defaultdict(int)
a[0] += 1
s = input()[::-1]
for i in range(1, len(s)+1):
    a[int(s[:i][::-1])%2019] += 1

def comb(a):
    return a*(a-1)//2

ans = 0
for x in list(a.values()):
    if x >= 2:
        ans += comb(x)
print(ans)

# Optimized solution
from collections import Counter, defaultdict
a = defaultdict(int)
a[0] += 1
s = input()[::-1]
cur = 0
for i, x in enumerate(s):
    cur += (int(x)*pow(10, i, 2019))%2019
    cur %= 2019
    a[cur] += 1

def comb(a):
    return a*(a-1)//2

ans = 0
for x in list(a.values()):
    if x >= 2:
        ans += comb(x)
print(ans)
# Original solution
import sys
from pprint import pprint

S = sys.stdin.readline().strip()
S = S[::-1]

n = len(S)
r = [0] * 2019
acum = [0] * (len(S)+1)
r[0] += 1
for i, s_i in enumerate(S):
    acum[i+1] = int(s_i) * 10 ** (i) + acum[i]
    acum[i+1] %= 2019
    r[acum[i+1]] += 1
# print(acum)

ans = 0
for r_i in r:
    ans += r_i * (r_i - 1) // 2
print(ans)

# Optimized solution
import sys
from pprint import pprint

S = sys.stdin.readline().strip()
S = S[::-1]

n = len(S)
r = [0] * 2019
acum = [0] * (len(S)+1)
r[0] += 1
for i, s_i in enumerate(S):
    acum[i+1] = int(s_i) * pow(10, i, 2019) + acum[i]
    acum[i+1] %= 2019
    r[acum[i+1]] += 1
# print(acum)

ans = 0
for r_i in r:
    ans += r_i * (r_i - 1) // 2
print(ans)
# Original solution
import sys
from collections import defaultdict

lines = 1
inp = list()

for _ in range(lines):
    inp.append(sys.stdin.readline().strip())


s = inp[0]
n = len(s)

tmp = defaultdict(int)
tmp[0] = 1

b = 0

for i in range(1, n + 1):
    a = int(s[n - i])
    b = ((10 ** (i-1)) * a + b) % 2019
    tmp[b] += 1

result = 0

for v in list(tmp.values()):
    result += int(v * (v - 1) / 2)

print(result)


# Optimized solution
import sys
from collections import defaultdict

lines = 1
inp = list()

for _ in range(lines):
    inp.append(sys.stdin.readline().strip())


s = inp[0]
n = len(s)

tmp = defaultdict(int)
tmp[0] = 1

b = 0
d = 1

for i in range(1, n + 1):
    a = int(s[n - i])
    b = ((d * a) + b) % 2019
    tmp[b] += 1
    d = (d * 10) % 2019

result = 0

for v in list(tmp.values()):
    result += int(v * (v - 1) / 2)

print(result)
# Original solution
import sys,os
from collections import defaultdict, deque
from math import ceil, floor
if sys.version_info[1] >= 5:
    from math import gcd
else:
    from fractions import gcd
sys.setrecursionlimit(10**6)
write = sys.stdout.write
dbg = (lambda *something: print(*something)) if 'TERM_PROGRAM' in os.environ else lambda *x: 0
def main(given=sys.stdin.readline):
    input = lambda: given().rstrip()
    LMIIS = lambda: list(map(int,input().split()))
    II = lambda: int(input())
    MOD = 2019

    S = input()[::-1]
    N = len(S)

    if N < 4:
        print(0)
        return

    R = [0] * 2019
    R[0] = 1 # '' の分
    t = 0
    b = 1
    for c in S:
        t += int(c) * b
        t %= 2019
        R[t] += 1
        b *= 10
    ans = 0
    for r in R:
        ans += r*(r-1)//2
    print(ans)
    




    

if __name__ == '__main__':
    main()


# Optimized solution
import sys,os
from collections import defaultdict, deque
from math import ceil, floor
if sys.version_info[1] >= 5:
    from math import gcd
else:
    from fractions import gcd
sys.setrecursionlimit(10**6)
write = sys.stdout.write
dbg = (lambda *something: print(*something)) if 'TERM_PROGRAM' in os.environ else lambda *x: 0
def main(given=sys.stdin.readline):
    input = lambda: given().rstrip()
    LMIIS = lambda: list(map(int,input().split()))
    II = lambda: int(input())
    MOD = 2019

    S = input()[::-1]
    N = len(S)

    if N < 4:
        print(0)
        return

    R = [0] * 2019
    R[0] = 1 # '' の分
    t = 0
    b = 1
    for c in S:
        t += int(c) * b
        t %= 2019
        R[t] += 1
        b *= 10
        b %= 2019
    ans = 0
    for r in R:
        ans += r*(r-1)//2
    print(ans)
    




    

if __name__ == '__main__':
    main()
# Original solution
#D
S = str(eval(input()))
dict = {}
cnt = 0
tot = 0

sum = {}
sum[0] = 0
for i in range(len(S)):
    tot += int(S[i])
    sum[i+1] = tot
#print(sum)


for i in range(len(S)-3):
    for j in range(i+3, len(S)):
        if (sum[j+1]-sum[i])%3 == 0:
            if S[i:j+1] in dict:
                dict[S[i:j+1]] += 1
            else:
                dict[S[i:j+1]] = 1

for ele in dict:
    if int(ele)%2019 == 0:
        cnt += dict[ele]
#print(arr)
print(cnt)
'''
for i in range(len(S)-3):
    for j in range(i+3, len(S)):
        if int(S[i:j+1])%2019 == 0:
            print(S[i:j+1])

'''

# Optimized solution
S = input()[::-1]
dp = [0]*2019
dp[0] = 1

tmp = 0
for i in range(len(S)):
    #modの世界
    tmp += int(S[i])*pow(10, i)
    tmp %= 2019
    dp[tmp] += 1
ans = 0
for i in dp:
    if i >= 2:
        #数列の和の公式
        ans += i*(i-1)//2
print(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
    
    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
S = input()[::-1]
digits = 1
num, ans = 0, 0
mod_list = [0] * 2019
mod_list[0] = 1

for c in S:
  num += int(c) * digits
  mod_list[num % 2019] += 1
  digits *= 10

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

# Optimized solution
S = input()[::-1]
digits = 1
num, ans = 0, 0
mod_list = [0] * 2019
mod_list[0] = 1

for c in S:
  num += int(c) * digits
  mod_list[num % 2019] += 1
  digits *= 10
  digits %= 2019

for i in range(2019):
  ans += mod_list[i] * (mod_list[i] - 1) // 2
  
print(ans)
# Original solution
from sys import stdin
def main():
    #入力
    readline=stdin.readline
    S=readline().strip()
    li=[0]*2019
    n=int(S)
    for i in range(len(S)):
        if i==0:
            pass
        else:
            n-=int(S[i-1])*pow(10,(len(S)-i))
        li[n%2019]+=1

    res=li[0]
    for i in range(2019):
        res+=li[i]*(li[i]-1)//2
    print(res)
    
if __name__=="__main__":
    main()

# Optimized solution
from sys import stdin
def main():
    #入力
    readline=stdin.readline
    S=readline().strip()
    li=[0]*2019
    n=int(S[-1])%2019
    m=1
    for i in range(len(S)):
        if i==0:
            pass
        else:
            m*=10
            m%=2019
            l=int(S[len(S)-i-1])
            n+=m*l
            n%=2019
        li[n]+=1

    res=li[0]
    for i in range(2019):
        res+=li[i]*(li[i]-1)//2
    print(res)
    
if __name__=="__main__":
    main()
# Original solution
from sys import stdin
def main():
    #入力
    readline=stdin.readline
    S=readline().strip()
    li=[0]*2019
    n=int(S[-1])%2019
    m=1
    for i in range(len(S)):
        if i==0:
            pass
        else:
            m*=10
            m%=2019
            l=int(S[len(S)-i-1])
            n+=m*l
            n%=2019
        li[n]+=1

    res=li[0]
    for i in range(2019):
        res+=li[i]*(li[i]-1)//2
    print(res)
    
if __name__=="__main__":
    main()

# Optimized solution
from sys import stdin
def nC2(n):
    return n*(n-1)//2

def main():
    #入力
    readline=stdin.readline
    s=readline().strip()

    d=dict()
    p=1
    t=0
    for i in range(len(s)-1,-1,-1):
        n=int(s[i])
        m=(n*p+t)%2019
        t=m
        p*=10
        p%=2019
        if m not in d:
            d[m]=1
        else:
            d[m]+=1
        
    if 0 in d:
        ans=d[0]
    else:
        ans=0
    for v in list(d.values()):
        ans+=nC2(v)
    print(ans)
    
if __name__=="__main__":
    main()
# Original solution
import sys
from collections import Counter
input = sys.stdin.readline
sys.setrecursionlimit(2 * 10**6)


def inpl():
    return list(map(int, input().split()))


def main():
    S = input().strip()[::-1]
    MOD = 2019
    T = [0, int(S[0])]
    for d, s in enumerate(S):
        if d == 0:
            continue
        tmp = int(s) * (10**d)
        T.append((T[-1] + tmp) % MOD)

    # print(T)

    cT = Counter(T)
    # print(cT)
    ans = 0
    for k in T:
        cT[k] -= 1
        ans += cT[k]
    print(ans)


if __name__ == '__main__':
    main()


# Optimized solution
import sys
from collections import Counter
input = sys.stdin.readline
sys.setrecursionlimit(2 * 10**6)


def inpl():
    return list(map(int, input().split()))


def main():
    S = input().strip()[::-1]
    MOD = 2019
    T = [0, int(S[0])]
    t10 = 1
    for s in S[1:]:
        t10 *= 10
        t10 %= MOD
        T.append((T[-1] + int(s) * t10) % MOD)

    # print(T)

    cT = Counter(T)
    # print(cT)
    ans = 0
    for k in T:
        cT[k] -= 1
        ans += cT[k]
    print(ans)


if __name__ == '__main__':
    main()
# Original solution
# coding: utf-8

import sys
import math
import collections
import itertools
INF = 10 ** 13
MOD = 10 ** 9 + 7
def input() : return sys.stdin.readline().strip()
def lcm(x, y) : return (x * y) // math.gcd(x, y)
def I() : return int(input())
def LI() : return [int(x) for x in input().split()]
def RI(N) : return [int(input()) for _ in range(N)]
def LRI(N) : return [[int(x) for x in input().split()] for _ in range(N)]
def LS() : return input().split()
def RS(N) : return [input() for _ in range(N)]
def LRS(N) : return [input().split() for _ in range(N)]
def PL(L) : print(*L, sep="\n")
def YesNo(B) : print("Yes" if B else "No")
def YESNO(B) : print("YES" if B else "NO")

S = input()
N = len(S)
P = 2019

A = [0] * (N+1)
for i in range(N):
    A[i+1] = (A[i] + int(S[N-1 - i]) * (10**i)) % P

c = collections.Counter(A)
ans = 0
for k, v in c.items():
    ans += v * (v-1) // 2

print(ans)


# Optimized solution
# coding: utf-8

import sys
import math
import collections
import itertools
INF = 10 ** 13
MOD = 10 ** 9 + 7
def input() : return sys.stdin.readline().strip()
def lcm(x, y) : return (x * y) // math.gcd(x, y)
def I() : return int(input())
def LI() : return [int(x) for x in input().split()]
def RI(N) : return [int(input()) for _ in range(N)]
def LRI(N) : return [[int(x) for x in input().split()] for _ in range(N)]
def LS() : return input().split()
def RS(N) : return [input() for _ in range(N)]
def LRS(N) : return [input().split() for _ in range(N)]
def PL(L) : print(*L, sep="\n")
def YesNo(B) : print("Yes" if B else "No")
def YESNO(B) : print("YES" if B else "NO")

S = input()
N = len(S)
P = 2019

A = [0] * (N+1)
for i in range(N):
    A[i+1] = (A[i] + int(S[N-1 - i]) * pow(10, i, P)) % P

c = collections.Counter(A)
ans = 0
for v in c.values():
    ans += v * (v-1) // 2

print(ans)
# Original solution
S=str(eval(input()))
l=len(S)
ans=0

mod=[0]*2019
mod[0]+=1
for i in range(l):
    mod[int(S[i:l+1])%2019]+=1
    
for j in range(len(mod)):
    m=mod[j]
    ans=ans+m*(m-1)//2
print(ans)

# Optimized solution
S=str(eval(input()))
l=len(S)
ans=0
dig=1
mod=[0]*2019
mod[0]=1
t=0
for i in range(l):
    t=(t+int(S[-i-1])*dig)%2019
    mod[t]+=1
    dig=(dig*10)%2019
    
for j in mod:
    ans=ans+(j*(j-1))//2
print(ans)
# Original solution
#!/usr/bin python3
# -*- coding: utf-8 -*-

def main():
    S = input()[::-1]
    L = len(S)
    dp = [0] * 2019
    wk = 0
    r = 1
    for i in range(L):
        wk += int(S[i])*r
        wk %= 2019
        r *= 10
        dp[wk] += 1
    ret = dp[0]
    for i in range(2019):
        ret += dp[i]*(dp[i]-1)//2
    print(ret)


if __name__ == '__main__':
    main()

# Optimized solution
#!/usr/bin python3
# -*- coding: utf-8 -*-

def main():
    S = input()[::-1]
    L = len(S)
    dp = [0] * 2019
    wk = 0
    r = 1
    for i in range(L):
        wk += int(S[i])*r
        wk %= 2019
        r *= 10
        r %= 2019
        dp[wk] += 1
    ret = dp[0]
    for i in range(2019):
        ret += dp[i]*(dp[i]-1)//2
    print(ret)


if __name__ == '__main__':
    main()
# Original solution
# from math import factorial,sqrt,ceil,gcd
# from itertools import permutations as permus
# from collections import deque,Counter
# import re
from functools import lru_cache # 簡単メモ化 @lru_cache(maxsize=1000)
# from decimal import Decimal, getcontext
# # getcontext().prec = 1000
# # eps = Decimal(10) ** (-100)

# import numpy as np
# import networkx as nx
# from scipy.sparse.csgraph import shortest_path, dijkstra, floyd_warshall, bellman_ford, johnson
# from scipy.sparse import csr_matrix
# from scipy.special import comb

# slist = "abcdefghijklmnopqrstuvwxyz"
S = input()[::-1]

MOD = 2019
tmp = [0]*MOD
tmp[0] += 1
tens = 1
num = 0
for s in S:
    num += int(s) * tens
    key = num % MOD
    tmp[key] += 1
    tens *= 10

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

print(ans)
# print(*ans)   # unpackして出力。間にスペースが入る
# for row in board:
#     print(*row,sep="")    #unpackして間にスペース入れずに出力する
# print("{:.10f}".format(ans))
# print("{:0=10d}".format(ans))


# Optimized solution
# from math import factorial,sqrt,ceil,gcd
# from itertools import permutations as permus
# from collections import deque,Counter
# import re
from functools import lru_cache # 簡単メモ化 @lru_cache(maxsize=1000)
# from decimal import Decimal, getcontext
# # getcontext().prec = 1000
# # eps = Decimal(10) ** (-100)

# import numpy as np
# import networkx as nx
# from scipy.sparse.csgraph import shortest_path, dijkstra, floyd_warshall, bellman_ford, johnson
# from scipy.sparse import csr_matrix
# from scipy.special import comb

# slist = "abcdefghijklmnopqrstuvwxyz"
S = input()[::-1]

MOD = 2019
tmp = [0]*MOD
tmp[0] += 1
tens = 1
num = 0
for s in S:
    num += int(s) * tens
    num = num % MOD
    tmp[num] += 1
    tens *= 10
    tens %= MOD

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

print(ans)
# print(*ans)   # unpackして出力。間にスペースが入る
# for row in board:
#     print(*row,sep="")    #unpackして間にスペース入れずに出力する
# print("{:.10f}".format(ans))
# print("{:0=10d}".format(ans))
# Original solution
M,a,t,p=2019,0,0,1;l=[0]*M
for i in input()[::-1]:l[t]+=1;t=(t+int(i)*p)%M;a+=l[t];p*=10
print(a)

# Optimized solution
M,a,t,p=2019,0,0,1;l=[0]*M
for i in input()[::-1]:l[t%M]+=1;t+=int(i)*p;a+=l[t%M];p=p*10%M
print(a)
# Original solution
s = input()[::-1]
counts = [0] * 2019
counts[0] = 1
digit = 1
sum = 0
for c in s:
  sum += int(c) * digit
  digit = digit * 10 
  amari = sum % 2019
  counts[amari] += 1

result = 0
for c in counts:
  result += c * (c - 1) // 2

print(result)

# Optimized solution
s = input()[::-1]
counts = [0] * 2019
counts[0] = 1
digit = 1
sum = 0
for c in s:
  sum = (sum + int(c) * digit) % 2019
  digit = digit * 10 % 2019
  counts[sum] += 1

result = 0
for c in counts:
  result += c * (c - 1) // 2

print(result)
# Original solution
s = str(eval(input()))
N = len(s)
array = [0]*2019
array[0] += 1
count = 0
for i in reversed(list(range(0, N))):
    x = s[i:N]
    y = int(x)
    array[y%2019] += 1

for i in array:
    count += i*(i-1)/2
print((int(count)))


# Optimized solution
s = str(eval(input()))
N = len(s)
array = [0]*2019
array[0] += 1
count = 0
d = 1
r = 0
for i in reversed(list(range(0, N))):
    r = ( r + int( s[i] ) * d ) % 2019
    d = d * 10 % 2019
    array[r] += 1
for i in array:
    count += i*(i-1)/2
print((int(count)))
# Original solution
number = str(eval(input()))[::-1]
remainderDictionary = {0: 1}
    
sum = 0
x = 1
for i in number:
  x = (x * 10) % 2019
  sum += int(i) * x
  sum %= 2019
  remainderValue = remainderDictionary.get(sum,0) + 1
  remainderDictionary[sum] = remainderValue
     
ans = 0
for i in remainderDictionary:
  value = remainderDictionary[i]
  ans += value * (value - 1) // 2 # N C 2
print(ans)

# Optimized solution
number = str(eval(input()))[::-1]
remainderDictionary = {0: 1}
    
sum = 0
x = 1
for i in number:
  x = (x * 10) % 2019
  sum = (sum + int(i) * x) % 2019 
  remainderValue = remainderDictionary.get(sum,0) + 1
  remainderDictionary[sum] = remainderValue
     
ans = 0
for i in remainderDictionary:
  value = remainderDictionary[i]
  ans += value * (value - 1) // 2 # N C 2
print(ans)
# Original solution
number = str(eval(input()))[::-1]
remainderDictionary = {0: 1}

digitDictionary = {'0':0, '1':1, '2':2, '3':3, '4':4, '5':5, '6':6, '7':7, '8':8, '9':9}

sum = 0
x = 1
for i in number:
  x = (x * 10) % 2019
  sum = (sum + digitDictionary[i] * x) % 2019 
  remainderValue = remainderDictionary.get(sum,0) + 1
  remainderDictionary[sum] = remainderValue
     
ans = 0
for i in remainderDictionary:
  value = remainderDictionary[i]
  ans += value * (value - 1) // 2 # N C 2
print(ans)

# Optimized solution
number = str(eval(input()))[::-1]
remainderDictionary = {0: 1}
digitDictionary = {'1':1, '2':2, '3':3, '4':4, '5':5, '6':6, '7':7, '8':8, '9':9}

sum = 0
x = 1
for i in number:
  x = (x * 10) % 2019
  sum = (sum + digitDictionary[i] * x) % 2019 
  remainderValue = remainderDictionary.get(sum,0) + 1
  remainderDictionary[sum] = remainderValue
     
ans = 0
for i in remainderDictionary:
  value = remainderDictionary[i]
  ans += value * (value - 1) // 2 # N C 2
print(ans)
# Original solution
number = str(eval(input()))[::-1]
remainderDictionary = {0: 1}
digitDictionary = {'1':1, '2':2, '3':3, '4':4, '5':5, '6':6, '7':7, '8':8, '9':9}

sum = 0
x = 1
for i in number:
  x = (x * 10) % 2019
  sum = (sum + digitDictionary[i] * x) % 2019 
  remainderValue = remainderDictionary.get(sum,0) + 1
  remainderDictionary[sum] = remainderValue
     
ans = 0
for i in remainderDictionary:
  value = remainderDictionary[i]
  if value > 1:
    ans += value * (value - 1) // 2 # N C 2
print(ans)

# Optimized solution
number = str(eval(input()))[::-1]
remainderDictionary = {0: 1}
digitDictionary = {'1':1, '2':2, '3':3, '4':4, '5':5, '6':6, '7':7, '8':8, '9':9}

sum = 0
x = 1
for i in number:
  x = (x * 10) % 2019
  sum = (sum + digitDictionary[i] * x) % 2019 
  remainderDictionary[sum] = remainderDictionary.get(sum,0) + 1

ans = 0
for i in remainderDictionary:
  value = remainderDictionary[i]
  if value > 1:
    ans += value * (value - 1) // 2 # N C 2
print(ans)
# Original solution
number = str(eval(input()))[::-1]
remainderDictionary = {0: 1}
digitDictionary = {'1':1, '2':2, '3':3, '4':4, '5':5, '6':6, '7':7, '8':8, '9':9}

sum = 0
x = 1
for i in number:
  x = (x * 10) % 2019
  sum = (sum + digitDictionary[i] * x) % 2019 
  remainderDictionary[sum] = remainderDictionary.get(sum,0) + 1

ans = 0
for i in remainderDictionary:
  value = remainderDictionary[i]
  if value > 1:
    ans += value * (value - 1) // 2 # N C 2
print(ans)

# Optimized solution
number = str(eval(input()))[::-1]
remainderDictionary = {0: 1}
digitDictionary = {'1':1, '2':2, '3':3, '4':4, '5':5, '6':6, '7':7, '8':8, '9':9}

sum = 0
x = 1
for i in number:
  x = (x * 10) % 2019
  sum = (sum + digitDictionary[i] * x) % 2019 
  remainderDictionary[sum] = remainderDictionary.get(sum,0) + 1

ansDictionary = {} # dictionary with the number of occurences and the corresponding N combinations of 2
ans = 0
for i in remainderDictionary:
  remainderOccurences = remainderDictionary[i]
  value = ansDictionary.get(remainderOccurences,-1)
  if value == -1:
    value = remainderOccurences * (remainderOccurences - 1) // 2 # N combinations of 2
    ansDictionary[remainderOccurences] = value
  ans += value
print(ans)
# Original solution
S = list(str(eval(input())))
S = [int(s) for s in S]
n = len(S)

S.reverse()

def power(a, n, mod):
  bi=str(format(n,"b")) #2進数
  res=1
  for i in range(len(bi)):
    res=(res*res) %mod
    if bi[i]=="1":
      res=(res*a) %mod
  return res

cum1 = [-1]*(n+1)
cum1[0] = 0
for i in range(n):
    temp = cum1[i]+S[i]*power(10, i, 673)
    cum1[i+1] = temp%673
#print(cum1)

cum2 = [-1]*(n+1)
cum2[0] = 0
for i in range(n):
    temp = cum2[i]+S[i]*power(10, i, 3)
    cum2[i+1] = temp%3
#print(cum2)

d = {}
ans = 0
for i in range(n+1):
    c1 = cum1[i]
    c2 = cum2[i]
    if (c1, c2) in d:
        ans += d[(c1, c2)]
        d[(c1, c2)] += 1
    else:
        d[(c1, c2)] = 1
print(ans)


# Optimized solution
s =list(str(eval(input())))
s = [int(c) for c in s]
s.reverse()

n = len(s)
p = 2019

def power(a, n, mod):
  bi=str(format(n,"b")) #2進数
  res=1
  for i in range(len(bi)):
    res=(res*res) %mod
    if bi[i]=="1":
      res=(res*a) %mod
  return res

temp = 0
cum = [0]*n
for i in range(n):
    temp += s[i]*power(10, i, p)
    temp = temp%p
    cum[i] = temp
cum = [0]+cum

#print(cum)

d = {}
ans = 0
for i in range(n+1):
  if cum[i] not in d:
    d[cum[i]] = 1
  else:
    ans += d[cum[i]]
    d[cum[i]] += 1
print(ans)
# Original solution
import sys
tmp=sys.stdin.readline().rstrip()
def main():
   ans=0
   cnt=[0]*2019
   cnt[0]+=1
   d=0
   for i,j in enumerate(reversed(tmp)):
      d+=int(j)%2019*10**(i)%2019
      cnt[d%2019]+=1
   for i in cnt:
      ans+=i*(i-1)//2
   print(ans)
if __name__ == "__main__":
    main()

# Optimized solution
import sys
tmp=sys.stdin.readline().rstrip()
def main():
   ans=0
   cnt=[0]*2019
   cnt[0]+=1
   t=0
   d=1
   for i in reversed(tmp):
      t=(t+int(i)*d)%2019
      cnt[t]+=1
      d=d*10%2019
   for i in cnt:
      ans+=i*(i-1)//2
   print(ans)
if __name__ == "__main__":
    main()
# Original solution
s=str(eval(input()))
n=len(s)
k=[0]*(n+1)
for i in range (1,n+1):
    k[i]=int(s[i-1])
t=[0]*(n+1)
t[0]=0  
for i in range(1,n+1):
    t[i]=(10*t[i-1]+k[i])%2019

p=1
q=[0]*448
for z in range(0,448):
    q[z]=p%2019
    p=10*q[z]

d=0    
for j in range(n+1):
    for l in range (j):
        f=(j-l)%448
        if (t[l]*q[f]-t[j])%2019==0:
            d+=1
            
print(d)

# Optimized solution
s=str(eval(input()))
n=len(s)
k=[0]*(n+1)
for i in range (1,n+1):
    k[i]=int(s[i-1])
t=[0]*(n+1)
t[0]=0  
for i in range(1,n+1):
    t[i]=(10*t[i-1]+k[i])%2019

p=1
q=[0]*448
for z in range(0,448):
    q[z]=p%2019
    p=10*q[z]

d=[0]*n   
for j in range(1,n+1):
    f=(n-j)%448
    d[j-1]=q[f]*t[j]%2019
ds=sorted(d)
ct=0
ans=0
if ds[0]==0:
    ct=1
    ans=1
for i in range(n-1):
    if ds[i+1]==ds[i]:
        ct+=1
        ans+=ct
    else:
        ct=0
print(ans)