Given is a string S consisting of digits from 1 through 9.
Find the number of pairs of integers (i,j) (1 ≤ i ≤ j ≤ |S|) that satisfy the following condition:
Condition: In base ten, the i-th through j-th characters of S form an integer that is a multiple of 2019.

-----Constraints-----
 - 1 ≤ |S| ≤ 200000
 - S is a string consisting of digits from 1 through 9.

-----Input-----
Input is given from Standard Input in the following format:
S

-----Output-----
Print the number of pairs of integers (i,j) (1 ≤ i ≤ j ≤ |S|) that satisfy the condition.

-----Sample Input-----
1817181712114

-----Sample Output-----
3

Three pairs - (1,5), (5,9), and (9,13) - satisfy the condition.

Difficulty: interview

Starter code:

Solutions:
s=input()[::-1]
alist=[0]*2019
num1=0
num2=1/10
lens=len(s)
for i in range(lens):
  num2=int(((num2)*10)%2019)
  num1=(num1+int(s[i])*(num2))%2019
  alist[num1]+=1
alist[0]+=1
ans=0
for i in range(2019):
  ans+=alist[i]*(alist[i]-1)//2
print(ans)

ans=0
S=input()
a=len(S)
k=0
c=dict()
mod=2019
s=1
c[0]=1
for i in range(a):
  k+=(s*int(S[a-i-1]))
  k%=mod
  s*=10
  s%=mod
  if k in c:
    c[k]+=1
  else:
    c[k]=1
for i in c:
  ans+=c[i]*(c[i]-1)//2
print(ans)

S = input()
N = len(S)
A = [int(S[i]) for i in range(N)]
A = A[::-1]

MOD = 2019

p10 = [1] * N
for i in range(1, N):
	p10[i] = (p10[i - 1] * 10) % MOD

for i in range(N):
	A[i] = (A[i] * p10[i]) % MOD

cumsum = [A[0]] * N
for i in range(1, N):
	cumsum[i] = (cumsum[i - 1] + A[i]) % MOD

cnt = [0] * MOD
cnt[0] = 1
for i in range(N):
	cnt[cumsum[i]] += 1

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

print(ans)


S = input()
N = len(S)
q = [0]
count = [0 for i in range(2019)]
ans = 0
count[0] = 1
m10 = 1

for i in range(1,N+1):
  a = int(S[-i])
  #print(a, a*(10**(N-i-1)), q)
  q.append((a*m10+q[i-1])%2019)
  m10 *= 10
  m10 %= 2019
  count[q[-1]] += 1

#print(q)

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

print(ans)


import sys;      from decimal import Decimal
import math;     from itertools import combinations, product
import bisect;   from collections import Counter, deque, defaultdict

# sys.setrecursionlimit(10 ** 6)
MOD = 10 ** 9 + 7
INF = 10 ** 9
PI = 3.14159265358979323846

def read_str():      return sys.stdin.readline().strip()
def read_int():      return int(sys.stdin.readline().strip())
def read_ints():     return map(int, sys.stdin.readline().strip().split())
def read_str_list(): return list(sys.stdin.readline().strip().split())
def read_int_list(): return list(map(int, sys.stdin.readline().strip().split()))
def lcm(a: int, b: int) -> int: return (a * b) // math.gcd(a, b)

import numpy as np

def Main():
    s = read_str()
    dp = np.zeros(2019, dtype=np.int64)
    dp[0] = 1

    cur = 0
    digit = 1

    for i in reversed(s):
        cur = (cur + int(i) * digit) % 2019
        dp[cur] += 1
        digit = digit * 10 % 2019
    
    print(np.sum([x * (x - 1) // 2 for x in dp]))

if __name__ ==  '__main__':
    Main()

import copy

s = list(input())

s.reverse()
n = len(s)
MOD = 2019
m = [0] * n
msum = [0] * (n+1)
cnt = [0] * (MOD)
cnt[0] = 1
t = 1
for i in range(n):
    m[i] = int(s[i]) * t % MOD
    msum[i+1] = (msum[i] + m[i]) % MOD
    cnt[msum[i+1]] += 1
    t = t * 10 % MOD

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

N = str(input())
n,mods = 0,[1]+[0]*2018
d = 1
for i in reversed(N):
  n = (n+int(i)*d)%2019
  mods[n] += 1
  d = (d*10)%2019

print(sum([i*(i-1)//2 for i in mods]))

import sys, re
from collections import deque, defaultdict, Counter
from math import ceil, sqrt, hypot, factorial, pi, sin, cos, tan, asin, acos, atan, radians, degrees, log2, gcd
from itertools import accumulate, permutations, combinations, combinations_with_replacement, product, groupby
from operator import itemgetter, mul
from copy import deepcopy
from string import ascii_lowercase, ascii_uppercase, digits
from bisect import bisect, bisect_left, insort, insort_left
from heapq import heappush, heappop
from functools import reduce
def input(): return sys.stdin.readline().strip()
def INT(): return int(input())
def MAP(): return map(int, input().split())
def LIST(): return list(map(int, input().split()))
def ZIP(n): return zip(*(MAP() for _ in range(n)))
sys.setrecursionlimit(10 ** 9)
INF = float('inf')
mod = 10 ** 9 + 7 
#mod = 998244353
from decimal import *
#import numpy as np
#decimal.getcontext().prec = 10

S = list(map(int, list(input())))[::-1]

l = [0]*2019
l[0] = 1

tmp = 0
z = 1

for i, s in enumerate(S):
	tmp += s*z
	z = z*10%2019
	l[tmp%2019] += 1

ans = 0
for v in l:
	ans += v*(v-1)//2

print(ans)


def solve():
    s=input().split()[0]
    cnt=[0]*2020
    cnt[0]=1
    m=0
    t=1
    for d in map(int,s[-1::-1]) :
        m=(m+d*t)%2019
        t=(t*10)%2019
        cnt[m]+=1
    return sum([ k*(k-1)//2 for k in cnt])

print((solve()))


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)


import sys
read = sys.stdin.read
readlines = sys.stdin.readlines
from collections import Counter
def main():
    s = input()
    n = len(s)

    amari = [0] * n
    ketaamari = 1
    t = 0
    for i1 in range(n):
        t = (t + ketaamari * int(s[-i1 -1])) % 2019
        amari[-i1-1] = t
        ketaamari = (ketaamari * 10) % 2019
    amari.append(0)
    ac = Counter(amari)
    r = 0
    for v in ac.values():
        r += v * (v - 1) // 2
    print(r)

def __starting_point():
    main()
__starting_point()

from collections import Counter

S=input()

rlist=[0]
for i in range(len(S)):
  rlist.append((rlist[-1]+int(S[-i-1])*pow(10,i,2019))%2019)
  
c = Counter(rlist)
c[0] -= 1

def nC2(n):
  return n*(n-1)//2
  
ans = c[0]
for k in c.keys():
  if c[k] >= 2:
    ans += nC2(c[k])
    
print(ans)

from collections import Counter

S = input()
# S = "12345"*40000
N = len(S)

l = [0]*(N+1)
for i in range(N-1, -1, -1):
    l[i] = (l[i+1] + pow(10, N-i, 2019) * int(S[i])) % 2019
    # if i%10000 == 0:
    #     print(i)

# print(list(Counter(l).values()))

r = sum(m*(m-1)//2 for m in Counter(l).values())
print(r)

s = input()
t = s[::-1]
n = len(s)
resid = [0] * 2019
resid[0] = 1
csum = 0
powoften = 1
for i in range(n):
    csum = (csum + int(t[i]) * powoften) % 2019
    powoften = (10 * powoften) % 2019
    resid[csum] += 1
ans = 0
for i in range(2019):
    ans += resid[i] * (resid[i] - 1) // 2
print(ans)

s = input()
mod = 2019
dic = [0] * mod
dic[0] += 1

tmp = 0
d = 1
for i in reversed(range(len(s))):
    tmp += int(s[i]) * d
    tmp %= mod
    d *= 10
    d %= mod
    dic[tmp] += 1

ans = [i * (i-1) / 2 for i in dic]
print(int(sum(ans)))

s = input()

l = len(s)
num = 0
count = 0
dic = {0: 1}
for i in range(l - 1, -1, -1):
  num = (num + int(s[i]) * pow(10, l - i - 1, 2019)) % 2019
  #print(num)
  #print(r)
  if num not in dic:
    dic[num] = 1
  else:
    dic[num] += 1
for ele in list(dic.values()):
  count += ele * (ele - 1) // 2
print(count)


from math import ceil,floor,factorial,gcd,sqrt,log2,cos,sin,tan,acos,asin,atan,degrees,radians,pi,inf
from itertools import accumulate,groupby,permutations,combinations,product,combinations_with_replacement
from collections import deque,defaultdict,Counter
from bisect import bisect_left,bisect_right
from operator import itemgetter
from heapq import heapify,heappop,heappush
from queue import Queue,LifoQueue,PriorityQueue
from copy import deepcopy
from time import time
from functools import reduce, lru_cache
import string
import sys
sys.setrecursionlimit(10 ** 7)
def input() : return sys.stdin.readline().strip()
def INT()   : return int(input())
def MAP()   : return map(int,input().split())
def MAP1()  : return map(lambda x:int(x)-1,input().split())
def LIST()  : return list(MAP())
def LIST1() : return list(MAP1())

s = input()

@lru_cache(None)
def F(s, k):
    # sの左からk文字目以降を整数と見なしたとき、
    # 2019で割った余りを返す
    if k == len(s)-1:
        return int(s[k])
    ret = F(s, k+1) + int(s[k])*pow(10, len(s)-1-k, 2019)
    ret %= 2019
    return ret

a = [0]*2020
for i in range(len(s)):
    a[F(s, i)] += 1

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

print(ans)

S=input()
MOD=2019
dp=[0]*MOD
dp[0]=1
r=0
t=1
for c in reversed(S):
    r+=int(c)*t
    r%=MOD
    t*=10
    t%=MOD
    dp[r]+=1
print(sum(i*(i-1)//2 for i in dp))

S = input()
dp = [0]*(len(S)+1)
cur = int(S[len(S)-1])
mod_10 = 1
count_num = [0]*2019
count_num[0] += 1
for i in range(len(S)):
    dp[len(S)-i-1] = cur
    count_num[cur] += 1
    mod_10 = (mod_10*10)%2019
    if i <= len(S)-2:
        cur = (cur+int(S[len(S)-i-2])*(mod_10))%2019
ans = 0
for i in range(2019):
    ans += (count_num[i]*(count_num[i]-1))//2
print(ans)


S=input()
ans,n=0,len(S)
dp=[0]*(2019)
s,dp[0],k=0,1,1
for i in S[::-1]:
  s=(s+int(i)*k)%2019
  k=(k*10)%2019
  ans+=dp[s]
  dp[s]+=1
print(ans)

#!/usr/bin/env python3

import numpy as np
from collections import Counter

YEAR = 2019


def solve(S: str):
    # S の各桁を modYear 計に修正する
    mod_year = np.arange(1, 10)
    mod_s = []
    for Si in map(int, reversed(S)):
        mod_s.append(mod_year[Si - 1])
        mod_year = (mod_year * 10) % YEAR
    # print(mod_s)
    # mod_s を累積和にする
    cum_sum = 0
    cum_sums = [cum_sum]
    for x in mod_s:
        cum_sum = (cum_sum + x) % YEAR
        cum_sums.append(cum_sum)

    # 場合分けの数を足し合わせる
    answer = 0
    for _, num in list(Counter(cum_sums).items()):
        answer += (num * (num - 1)) // 2  # 1 の時0なので場合分けはいらない
    return answer


def main():
    S = input().strip()
    answer = solve(S)
    print(answer)


def __starting_point():
    main()

__starting_point()

import collections

s=list(input())
a=[0]

s.reverse()

mod=2019

mod10=1

for i in range(len(s)):
  x=int(s[i])
  y=a[-1]
  ans=(x*mod10+y)%mod
  a.append(ans)
  mod10=(mod10*10)%mod
  
ans1=0

c = collections.Counter(a)
d=list(c.values())

for r in d:
  if r>=2:
    ans1+=(r*(r-1))//2
    
print(ans1)

s = input()
s = s[::-1]

L = [0]
cnt = 1
for i in range(len(s)):
    L.append((L[-1]+(int(s[i])*cnt))%2019)
    cnt *= 10
    cnt %= 2019

D = dict()
for j in L:
    if j in D:
        D[j] += 1
    else:
        D[j] = 1
ans = 0
for k in D.values():
    ans += k * (k-1) //2

print(ans)

s=input()[::-1]
n=len(s)
cnts=[0]*2019
cnts[0]=1
num=0
for i in range(n):
  num+=int(s[i])*pow(10,i,2019)
  num%=2019
  cnts[num]+=1

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


s = list(input())

MOD = 2019

temp = 0
d = 1

m = [0] * MOD
m[0] = 1

for x in reversed(s):
    temp += int(x) * d
    temp %= MOD
    m[temp] += 1
    d = (d * 10) % MOD

ans = 0
for x in m:
    ans += x * (x-1) // 2

print(ans)

s=input()[::-1]
n=len(s)
p=2019
S=[0 for i in range(n+1)]
ans=[0]*p

x10=1
for j, i in enumerate(s):
  S[j+1]=(S[j]+(x10*int(i)))%p
  x10*=10
  x10%=p
  ans[S[j+1]]+=1

cnt=ans[0]
for a in ans:
  cnt+=(a*(a-1))//2
  
print(cnt)


S = input()

mod = 2019
cnt = [0] * 2019
cur = 0  # 現在検討中の部分文字列
cnt[cur] = 1
d = 1   # 桁

for s in S[::-1]:
    cur += int(s) * d
    cur %= mod
    cnt[cur] += 1
    d *= 10
    d %= mod

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

print(ans)

#!/usr/bin/env python3
def main():
    S = input()[::-1]

    counts = [0] * 2019
    counts[0] = 1
    res, digit = 0, 1
    for i in S:
        res += int(i) * digit
        res %= 2019
        digit *= 10
        digit %= 2019
        counts[res] += 1

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


def __starting_point():
    main()

__starting_point()

s = input()
n = len(s)
mod = 2019

t = [0]*n
dp = [0]*2020
t[0] = int(s[-1])
dp[t[0]] += 1
for i in range(n-1):
    t[i+1] = t[i] + int(s[-2-i])*pow(10, i+1, mod)
    t[i+1] %= mod
    dp[t[i+1]] += 1
ans = 0
for D in dp[1:]:
    ans += D*(D-1)//2
print((ans+(dp[0]+1)*(dp[0])//2))




#!/usr/bin/env python3
import sys
import numpy as np

input = sys.stdin.readline


def ST():
    return input().rstrip()


def I():
    return int(input())


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


def LI():
    return list(MI())


S = ST()

cnt = np.zeros(2019)
cnt[0] = 1
res = 0
tmp = 1
for s in S[::-1]:
    res += int(s) * tmp
    res %= 2019
    cnt[res] += 1
    tmp *= 10
    tmp %= 2019

ans = 0
for c in cnt[cnt >= 2]:
    ans += c * (c - 1) // 2

print((int(ans)))


def main():
    import collections

    S = input()

    mod_list = [0]

    for i in range(len(S)):
        index = len(S) - i - 1
        num = int(S[index])

        mod_list.append((mod_list[-1] + num * pow(10, i, 2019)) % 2019)

    CTR_mod_list = collections.Counter(mod_list).most_common()
    cnt = 0

    for i in range(len(CTR_mod_list)):
        n = CTR_mod_list[i][1]

        if (n == 1):
            break

        cnt += n * (n - 1) // 2

    print(cnt)

def __starting_point():
    main()
__starting_point()

import math,itertools,fractions,heapq,collections,bisect,sys,queue,copy

sys.setrecursionlimit(10**7)
inf=10**20
mod=10**9+7
dd=[(-1,0),(0,1),(1,0),(0,-1)]
ddn=[(-1,0),(-1,1),(0,1),(1,1),(1,0),(1,-1),(0,-1),(-1,-1)]

def LI(): return [int(x) for x in sys.stdin.readline().split()]
# def LF(): return [float(x) for x in sys.stdin.readline().split()]
def I(): return int(sys.stdin.readline())
def F(): return float(sys.stdin.readline())
def LS(): return sys.stdin.readline().split()
def S(): return input()

# Summarize count of factor within list -- START --
def summarizeList(l):
  sl=sorted(l)

  a=sl[0]
  c=1
  res=[]

  for x in sl[1:]:
    if x==a:
      c+=1
    else:
      res.append([a,c])
      a=x
      c=1
  res.append([a,c])

  return res
# Summarize count of factor within list --- END ---

# 累積和の書き方がよくないやつ
def main():
  s=S()
  n=len(s)

  l=[]
  mul=1
  for x in s[::-1]:
    l.append(mul*int(x)%2019)
    mul*=10
    mul%=2019

  for i in range(n-1):
    l[i+1]+=l[i]
    l[i+1]%=2019

  sl=summarizeList(l)
  # print(sl)

  ans=0
  for x,c in sl:
    if x==0:
      ans+=c
    if c>1:
      ans+=c*(c-1)//2

  return ans

# main()
print((main()))


# -*- coding: utf-8 -*-
"""
Created on Mon Sep  7 00:38:11 2020

@author: liang
"""

"""
＜D - Multiple of 2019>
【方針】
a = b(mod2019) => a - b は　2019の倍数
余りが等しいグループの組み合わせの総数が解になる。
既に2019の倍数であるものは単体で成立するため、[0]のカウントを一つあげておく


＜累積和＞
【計算量削減】
大きな数を使わない　⇒　mod を使う
tmp += 7 * 100000000  => 7 * ( 2019*N + α) => 7 * α　と同じ
　　⇒　累乗(10**N) に  mod をかけると良い

100000000 + γ => (2019*N + β) + γ => β + γ と同じ
　⇒　累積和　に　mod をかけると良い
 
 for文で１文字ずつ足し算していくことで実装可能
 
 reversed() : 逆順に並べ替え
 reversed(input()) : 入力を逆順に取り出す
 
"""
S = input()

MOD = 2019 

counter = [0] * 2019
counter[0] = 1
t = 1
tmp = 0
for i in reversed(S):
    tmp += int(i)*t
    tmp %= MOD #累積和を効率化
    t *= 10
    t %= MOD   #累乗を効率化 
    #print(tmp)
    counter[tmp] += 1

ans = sum( i*(i-1)//2 for i in counter)
print(ans)

s = list(input())
# s = list(str(10**200000))
n = len(s)
ans = 0
s.reverse()
# print(s)
x = 1
tot = 0
count = [0]*2019
for i in range(n):
    count[tot]+=1
    tot += int(s[i])*x
    # print(tot)
    tot %= 2019
    ans += count[tot]
    x = x*10%2019
print(ans)

S = input()[::-1]
ans = 0
mods = [0] * 2019
mods[0] = 1
current = 0
x = 1
for s in S:
  current = (current + x * int(s)) % 2019
  ans += mods[current % 2019]
  mods[current % 2019] += 1
  x = x * 10 % 2019
print(ans)

s = list(map(int,input()))
s.reverse()
t = len(s)
mod = 2019

arr = [0] * (t+1)
arr[-2] = s[0]
for i in range(1,t):
    arr[t-i-1] = (arr[t-i] + s[i]*pow(10,i,mod)) % mod

from collections import Counter
arr = Counter(arr)

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

print(ans)

import sys
import heapq
import math
import fractions
import bisect
import itertools
from collections import Counter
from collections import deque
from operator import itemgetter
def input(): return sys.stdin.readline().strip()
def mp(): return map(int,input().split())
def lmp(): return list(map(int,input().split()))

s=input()[::-1]
n=len(s)
a=[0]*2019
a[0]=1
c,d=0,1
for i in s:
    c+=int(i)*d
    c%=2019
    d*=10
    d%=2019
    a[c]+=1
ans=0
for i in a:
    ans+=i*(i-1)//2
print(ans)

from collections import Counter
S = input()[::-1]
MOD = 2019
X = [0]
for i,s in enumerate(S):
    X.append((X[-1]+int(s)*pow(10,i,MOD))%MOD)
C = Counter(X)
print(sum([v*(v-1)//2 for v in C.values()]))

S=input()
ans,n=0,len(S)
dp=[0]*(2019)
s,dp[0],k=0,1,1
for i in range(1,n+1):
  s=(s+int(S[-i])*k)%2019
  k=(k*10)%2019
  ans+=dp[s]
  dp[s]+=1
print(ans)

n = input()
p = 2019
t = 1
y = 0
c = p*[0]

for x in map(int,n[::-1]):
  y+=t*x
  y%=p
  c[y]+=1
  t*=10
  t%=p

print(sum(i*(i-1)//2 for i in c)+c[0])

def main():
    def modpow(x, n, mod):
        res = 1
        while n:
            if n % 2:
                res *= x % mod
            x *= x % mod
            n >>= 1
        return res

    s = input()
    s = s[::-1]
    s_len = len(s)
    mod = 2019
    d = [0] * mod
    d[0] = 1
    rev_num = 0
    # 2以上なら共通するmodがあったということになる
    for i in range(s_len):
        rev_num += int(s[i]) * int(modpow(10, i, mod))
        rev_num %= mod
        d[rev_num] += 1
    # 2以上同じmodがあったらそこから2つ選ぶ選び方
    # それを全てのmodで
    print(sum(i*(i-1)//2 for i in d))
 
def __starting_point():
    main()
__starting_point()

S = input()
s_rev = S[::-1]

r_list = [0] * 2019
r_list[0] = 1
num, d = 0, 1
for i in range(len(S)):
    num += d*int(s_rev[i])
    num %= 2019
    r_list[num] += 1
    d *= 10
    d %= 2019

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

print(ans)


s=input()
p=2019
ans=0
M=[0]*p
M[0]=1
tmp=0
for i in range(len(s)):
    tmp+=(int(s[-i-1])*pow(10,i,p))
    tmp%=p
    ans+=M[tmp]
    M[tmp]+=1
print(ans)

from collections import Counter
S = input()
S = S + '0'
mod = 2019
p = [0] * mod
r = 0
d = 1
for s in S[::-1]:
  t = int(s)%mod
  r += t*d
  r %= mod
  d = d*10%mod
  p[r] += 1

#ans = 0
#c = Counter(p)
#for k,n in c.most_common()[::-1]:
#  if k > 1 and k%2 == 0:
#    ans += n
#  else:break
#print(ans)
print(sum([i*(i-1)//2 for i in p]))

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

S=str(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)

from collections import defaultdict

S = input()

d = defaultdict(int)

d[0] += 1

mod = 0
R = 1
for i in range(len(S)):
    mod = (mod + R * int(S[len(S) - i - 1])) % 2019
    R = R * 10 % 2019
    d[mod] += 1
ans = 0
for i in list(d.values()):
    if i > 1:
        ans += i * (i - 1) / 2

print((int(ans)))


from collections import Counter
S = input()
S = S + '0'
mod = 2019
p = [0] * mod
r = 0
d = 1
for s in S[::-1]:
  t = int(s)%mod
  r += t*d
  r %= mod
  d = d*10%mod
  p[r] += 1

#p.append(0)
#ans = 0
#c = Counter(p)
#for k,n in c.most_common():
#  if n > 1:
#    ans += 1
#  else:break
  
print(sum([i*(i-1)//2 for i in p]))

S = input()
mod = 2019

array = []
for i in range(len(S)):
    x = (int(S[len(S)-1-i])*pow(10,i,mod))%mod
    array.append(x)
array2 = [0]
y = 0
for i in range(len(S)):
    y = (y+array[i])%mod
    array2.append(y)
array3 = [0] * 2019
ans = 0
for i in range(len(array2)):
    z = array2[i]
    ans += array3[z]
    array3[z] += 1
print(ans)
#3*673


s=input()
n=len(s)
rui=[0]
juu=[1]
for i in range(n+5):
  juu.append(juu[-1]*10%2019)  
for i in range(n):
  rui.append((rui[-1]+int(s[n-1-i])*juu[i])%2019)
ama=[0]*2019
for i in range(len(rui)):
  ama[rui[i]]+=1
ans=0
def ui(n):
  return max(0,n*(n-1)//2)
for i in range(2019):
  ans+=ui(ama[i])
print(ans)  

def MultipleOf2019():
    S = input()
    s = int(S)
    num, mod, ans = len(S), 2019, 0
    c = [0 for _ in range(num+1)]
    d = [0 for _ in range(mod)]
    d[0] = 1
    s = int(S)
    
    for i in range(num):
        c[i+1] = (c[i]+int(S[-i-1])*pow(10, i, mod))%mod
        d[c[i+1]] += 1

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


def __starting_point():
    MultipleOf2019()
    

__starting_point()

S = input()
N = len(S)
 
counter = [0] * 2019
counter[0] = 1
T = 0
R = 1
for i in range(N):
    T = (T + R * int(S[N - i - 1])) % 2019
    R = 10 * R % 2019
    counter[T] += 1
 
ans = 0
for i in range(2019):
    m = counter[i]
    ans += m * (m - 1) // 2
 
print(ans)

def inN():
    return int(input())
def inL():
    return list(map(int,input().split()))
def inNL(n):
    return [list(map(int,input().split())) for i in range(n)]

s = input()
n = int(s)
l = len(s)
cnt = 0
mod = [0]*2019
m = 0
for i in range(l):
    m = (int(s[l-1-i])*pow(10,i,2019) + m)%2019
    mod[m] += 1

cnt += mod[0]

for i in range(2019):
    if mod[i] > 1:
        cnt += (mod[i]*(mod[i]-1))/2
        #print(i)
print((int(cnt)))


from collections import Counter
S = list(map(int, list(input())))
A = [0]
for i, s in enumerate(S[::-1]):
    A.append((A[-1] + s * pow(10, i, 2019)) % 2019)
print((sum([v * (v - 1) // 2 for v in list(Counter(A).values())])))


S = reversed(input())
residuelist = [0]
power = 1
residue = 0
for i in S:
    digit = int(i)
    residue = (residue+power*digit)%2019
    residuelist.append(residue)
    power = (power*10)%2019
from collections import Counter
val = Counter(residuelist).values()
ans = 0
for j in val:
    ans += j*(j-1)//2
print(ans)

# coding: utf-8
# Your code here!

S=list(input())
S=list(map(int,S))[::-1]


mod=[0]*2019
mod[0]+=1

ans=0
temp=0
p=1
for i in range(len(S)):
    temp+=S[i]*p
    p=p*10%2019
    temp%=2019
    ans+=mod[temp]
    mod[temp]+=1

print(ans)


s=input()

s=s[::-1]

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

num=0
d = 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) # 答えの出力   



from collections import Counter
s = input()

ls = len(s)
t = [0]
j = 1
for i in range(ls):
    u = (int(s[ls-1-i])*j + t[-1]) % 2019
    t.append(u)
    j = (j * 10) % 2019
c = Counter(t)
k = list(c.keys())
ans = 0
for i in k:
    ans += c[i]*(c[i]-1)/2
print(int(ans))

from collections import Counter
import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines
mod = 2019


s = readline().decode().rstrip()
s = s[::-1]
n = len(s)
d = [0] * (n)
d[0] = int(s[0]) % mod

for i in range(1, n):
    d[i] = (d[i - 1] + int(s[i]) * pow(10, i, mod)) % mod

d = [0] + d

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

def main():
  n, mods = 0, [1]+[0]*2019
  d = 1
  for i in reversed(input()):
    n = (n+int(i)*d)%2019
    d = d*10%2019
    mods[n] += 1
  print(sum([i*(i-1)//2 for i in mods]))
main()

S=input()
s=int(S)
mod=2019
c=[0]*(len(S)+1)
d=[0]*2019


c[0]=0
d[0]=1
for i in range(len(S)):
  c[i+1]=(c[i]+int(S[-i-1])*pow(10,i,mod))%mod
  d[c[i+1]]+=1
  
m=0
for i in range(2019):
  m+=d[i]*(d[i]-1)//2

print(m)

# -*- coding: utf-8 -*-

S = input().strip()
#-----
num = 0
cnt_mod = {0:1}  # type {int: int} , contents {remainder : count}
mod = 2019
base_pow = 1

for i in range(len(S)):
    digit = int( S[len(S)-1-i] )
    
    num += (digit * base_pow) % mod
    num %= mod
    
    base_pow = (base_pow * 10) % mod
    
    cnt_mod.setdefault(num, 0)
    cnt_mod[num] += 1


ans = 0

for r,c in list(cnt_mod.items()):
    # r: remainder
    # c: count
    if c >= 2:
        ans += c*(c-1)//2

print(ans)


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)


from collections import Counter
N = list(input())
M = [0]
S = 0
K = 1
ans = 0

for i in range(len(N)):
    S += int(N[-i-1])*K
    S %= 2019

    K *= 10
    K %= 2019
    M.append(S)

P = Counter(M)
for i in range(2020):ans+=P[i]*(P[i]-1)//2
print(ans)


import sys
import collections


def resolve(in_):
    s = next(in_).strip()
    mod = 2019
    dp = [0] * (len(s) + 1)
    ch0 = ord(b'0')
    for i, b in enumerate(reversed(s), 1):
        dp[i] = (dp[i - 1] + (b - ch0) * pow(10, i, mod)) % mod

    return sum(v * (v - 1) // 2 for v in list(collections.Counter(dp).values()))


def main():
    answer = resolve(sys.stdin.buffer)
    print(answer)


def __starting_point():
    main()

__starting_point()

#import numpy as np
#import math
#from decimal import *
#from numba import njit
from collections import Counter

#@njit
def main():
    S = input()
    A = list(map(int, S))[::-1]
    mod = []
    ten = 10
    for i in range(len(A)):
        if i == 0:
            mod += A[i],
        else:
            mod += (mod[i-1]+ten*A[i])%2019,
            ten = (ten*10)%2019
    mod += 0,

    C = Counter(mod)
    print(sum([c*(c-1)//2 for c in C.values()]))

main()

S = input()

cs = [0]
r = 1
for c in S[::-1]:
    cs.append((cs[-1] + r*int(c)) % 2019)
    r *= 10
    r %= 2019

from collections import Counter
ctr = Counter(cs)
ans = 0
for v in ctr.values():
    ans += v*(v-1)//2
print(ans)

from collections import Counter
S = input()
S = S + '0'
mod = 2019
p = [-1] * len(S)
r = 0
d = 1
for i,s in enumerate(S[::-1]):
  t = int(s)%mod
  r += t*d
  r %= mod
  d = d*10%mod
  p[i] = r

ans = 0
c = Counter(p)
for k,n in c.most_common():
  if n > 1:
    ans += n*(n-1)//2
  else:break
print(ans)

N = str(input())
n,mods = 0,[1]+[0]*2018
d = 1
for i in reversed(N):
  n = (n+int(i)*d)%2019
  mods[n] += 1
  d = (d*10)%2019

print(sum([i*(i-1)//2 for i in mods]))

def main():
    s = input()
    s_len = len(s)
    mod = 2019
    d = [0] * mod
    d[0] = 1
    rev_num = 0
    t = 1
    # 2以上なら共通するmodがあったということになる
    for i in reversed(s):
        rev_num += int(i) * t
        rev_num %= mod
        d[rev_num] += 1
        t *= 10
        t %= mod
    # 2以上同じmodがあったらそこから2つ選ぶ選び方
    # それを全てのmodで
    print(sum(i*(i-1)//2 for i in d))
 
def __starting_point():
    main()
__starting_point()

from collections import Counter
s=input()
n=len(s)
ans=0
arr=[0]*(n+1)
if s=='0':
    print(1)
    return
elif n==1:
    print(0)
    return
for i in reversed(range(n)):
    arr[i]=(arr[i+1]+int(s[i])*pow(10,n-i-1,2019))%2019
m=Counter(arr)
for j in m.keys():
    ans+=m[j]*(m[j]-1)//2
print(ans)

from collections import Counter
S = input()
S = S + '0'
mod = 2019
p = [0] * mod
r = 0
d = 1
for s in reversed(S):
  t = int(s)%mod
  r += t*d
  r %= mod
  d = d*10%mod
  p[r] += 1

#p.append(0)
#ans = 0
#c = Counter(p)
#for k,n in c.most_common():
#  if n > 1:
#    ans += 1
#  else:break
  
print(sum([i*(i-1)//2 for i in p]))

s = input()

len_s = len(s)

current = 0
mod_dict = dict()
mod_dict[0] = 1
for i in range(len_s-1,-1,-1):
    c = s[i]
    current = (current+pow(10,len_s-i-1,2019)*int(c)) % 2019
    if current in mod_dict:
        mod_dict[current] += 1
    else:
        mod_dict[current] = 1

count = 0
for key in mod_dict:
    count+= (mod_dict[key]*(mod_dict[key]-1))//2

print(count)

import sys
import math
import itertools
import collections
from collections import deque
from collections import defaultdict

sys.setrecursionlimit(1000000)
MOD = 10 ** 9 + 7
MOD2 = 998244353
INF = float('inf')
input = lambda: sys.stdin.readline().strip()

NI = lambda: int(input())
NMI = lambda: map(int, input().split())
NLI = lambda: list(NMI())
SI = lambda: input()

def combinations_count(n, r):
    if n == 1:
        return 0
    else:
        return math.factorial(n) // (math.factorial(n - r) * math.factorial(r))

def main():
    S = SI()
    
    ls = []
    len_S = len(S)
    rem = 0

    for s in range(len_S-1,-1,-1):
        rem = (rem+int(S[s])* pow(10, len_S-s-1, 2019))%2019
        ls.append(rem)
    
    import collections

    cls = collections.Counter(ls)
    clsv= list(cls.values())

    ans = 0

    for p in clsv:
        ans += combinations_count(p,2)
    ans += cls[0]
    print(ans)



def __starting_point():
    main()
__starting_point()

from collections import Counter
def main():
    S = input()
    A = [0] * ((n := len(S)) + 1)
    A[1] = (a := int(S[-1])) % 2019
    for i in range(2, n + 1):
        a += pow(10, i - 1, 2019) * int(S[-i])
        A[i] = a % 2019
    c = Counter(A)
    ans = 0
    for v in list(c.values()):
        ans += v * (v - 1) // 2
    print(ans)

def __starting_point():
    main()

__starting_point()

s = str(input())
MOD = 2019
m = 0
digit = 1
mods = [1] + [0] * 2018
for a in s[::-1]:
    m = (m + digit * int(a)) % MOD
    mods[m] += 1
    digit = digit * 10 % MOD
ans = 0
for x in mods:
    ans += x * (x - 1) // 2
print(ans)

from collections import Counter

s = input()
n = len(s)
digits = [int(c) for c in s[::-1]]
a = [0] * (n + 1)
p = 2019

for i, digit in enumerate(digits):
    a[i + 1] = (digit * pow(10, i, p) + a[i]) % p

counter = Counter(a)
ans = 0
for count in counter.values():
    ans += count * (count - 1) // 2

print(ans)

# -*- coding: utf-8 -*-
"""
Created on Sun Sep  6 23:39:24 2020

@author: liang
"""
#from scipy.special import comb

counter = [0]*2019
counter[0] = 1 # 0 = 0 (mod 2019)

S = input()
tmp = 0
"""
#大きい数を一気に掛けない
for i in range(1,len(S)+1):
    tmp += int(S[-i])*10**(i-1)    #スライスの方が早い（けど、漸化式的に累積和を出せ）
    #print(tmp%2019)
    tmp %= 2019                    #大きい数を割るな
    counter[tmp%2019] += 1

ans = 0
for i in range(2019):
    if counter[i] >= 2:
        #ans += comb(counter[i], 2, exact=True)
        ans += counter[i]*(counter[i]-1)//2
print(ans)
"""
MOD = 2019
#reversed(s) ?
t = 1
for i in range(1,len(S)+1):
    tmp += int(S[-i])*t
    #print("A", tmp)
    tmp %= MOD 
    t *= 10
    #print("B", tmp)
    t %= MOD
    #print(tmp)
    counter[tmp] += 1
    
print((sum(i*(i-1)//2 for i in counter)))


S = list(map(int, list(input())))

pops = 0
digi = 1
cnt = [0] * 2019
cnt[0] = 1

while S:
    s = S.pop()

    pops = (pops + s * digi) % 2019
    digi = (10 * digi) % 2019

    cnt[pops] += 1

ans = 0

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

print(ans)

S = str(input())
N = len(S)
b = [0] * 2019
count = 0
b[0] = 1
t = 0
k = 1

if len(S) < 4:
    print(0)
else:
    t = int(S[-1])
    b[t] += 1
    for i in range(1,N):
        k = k * 10 % 2019
        t = (k * int(S[-i-1]) + t) % 2019 
        b[t] += 1

    for i in b:
        count += i*(i-1)//2

    print(count)

import sys, re
from collections import deque, defaultdict, Counter
from math import ceil, sqrt, hypot, factorial, pi, sin, cos, tan, asin, acos, atan, radians, degrees, log2, gcd
from itertools import accumulate, permutations, combinations, combinations_with_replacement, product, groupby
from operator import itemgetter, mul
from copy import deepcopy
from string import ascii_lowercase, ascii_uppercase, digits
from bisect import bisect, bisect_left, insort, insort_left
from heapq import heappush, heappop
from functools import reduce
def input(): return sys.stdin.readline().strip()
def INT(): return int(input())
def MAP(): return map(int, input().split())
def LIST(): return list(map(int, input().split()))
def ZIP(n): return zip(*(MAP() for _ in range(n)))
sys.setrecursionlimit(10 ** 9)
INF = float('inf')
mod = 10 ** 9 + 7 
#mod = 998244353
from decimal import *
#import numpy as np
#decimal.getcontext().prec = 10

S = list(map(int, list(input())))[::-1]

l = [0]*2019
z = 1
tmp = 0
for i, s in enumerate(S):
	tmp += s*z
	l[tmp%2019] += 1
	z = z*10%2019

ans = 0
for v in l:
	ans += v*(v-1)//2
ans += l[0]

print(ans)

from collections import Counter
S = input()
C = Counter()
MOD = 2019

n = 0
for i, s in enumerate(S[::-1]):
    s = int(s)
    n += pow(10, i, MOD) * s % MOD
    C[n % MOD] += 1

C[0] += 1
ans = 0
for v in list(C.values()):
    ans += v * (v - 1) // 2
print(ans)


s=[int(x) for x in reversed(list(input()))]
n=len(s)
x=[0]*2019
dp = 0
dim = 1
for si in s:
  dp = (dp + si*dim) % 2019
  x[dp] += 1
  dim = dim * 10 % 2019
ans = x[0]
for i in range(2019):
  ans += x[i]*(x[i]-1)//2
print(ans)

S = input()
S = S + '0'
mod = 2019
p = [0] * mod
r = 0
d = 1
for s in reversed(S):
  t = int(s)%mod
  r += t*d
  r %= mod
  d = d*10%mod
  p[r] += 1

print(sum([i*(i-1)//2 for i in p]))

#!/usr/bin/env python3

import numpy as np
from collections import Counter

YEAR = 2019


def solve(S: str):
    # S の各桁を modYear 計に修正する
    mod_year = np.arange(1, 10)
    mod_s = []
    for Si in map(int, reversed(S)):
        mod_s.append(mod_year[Si - 1])
        mod_year = (mod_year * 10) % YEAR
    #print(mod_s)
    # mod_s を累積和にする
    cum_sum = 0
    cum_sums = [cum_sum]
    for x in mod_s:
        cum_sum = (cum_sum+x) % YEAR
        cum_sums.append(cum_sum)

    answer = 0
    for _, num in list(Counter(cum_sums).items()):
        answer += (num * (num-1)) // 2   # 1 の時0なので場合分けはいらない
    return answer


def main():
    S = input().strip()
    answer = solve(S)
    print(answer)


def __starting_point():
    main()

__starting_point()

import sys
read = sys.stdin.read
readlines = sys.stdin.readlines
from collections import defaultdict
def main():
    s = tuple(map(int, input()))
    lens = len(s)

    d1 = defaultdict(int)
    ss = 0
    num10 = 1
    for i1 in range(1, lens+1):
        ss += (int(s[-i1]) * num10) % 2019
        ss = ss % 2019
        d1[ss] += 1
        num10 = (num10 * 10) % 2019
    r = d1[0]
    for v in d1.values():
        r += v * (v - 1) // 2
    print(r)

def __starting_point():
    main()
__starting_point()

s=input()[::-1]
p=2019
ans=[0]*p

x10, S=1, 0
for i in s:
  S+=x10*int(i)
  S%=p
  x10*=10
  x10%=p
  ans[S]+=1

cnt=ans[0]
for a in ans:
  cnt+=(a*(a-1))//2
  
print(cnt)


S = input()
mod = 2019

t = len(S)
l = [0] * (t + 1)
for i in range(t-1, -1, -1):
    l[i] = (l[i+1] + int(S[i]) * pow(10, t-i-1, mod)) % mod

from collections import Counter

def nC2(n):
    return n * (n - 1) // 2

l = list(Counter(l).values())

ans = 0
for i in l:
    ans += nC2(i)

print(ans)

from collections import Counter
S = input()
P = [0] * (len(S)+1)
mod = 2019
d = 1
for i in range(len(S), 0, -1):
    P[i-1] = int(S[i-1])*d + P[i]
    P[i-1] = P[i-1] % mod
    d *= 10
    d = d % mod

P = Counter(P)
ans = 0
for p in P.values():
    ans += p*(p-1)//2
print(ans)

import sys
read = sys.stdin.read
readlines = sys.stdin.readlines
from collections import defaultdict
def main():
    s = tuple(map(int, input()))
    lens = len(s)

    d1 = defaultdict(int)
    ss = 0
    num10 = 1
    for se in s[::-1]:
        ss += (int(se) * num10) % 2019
        ss = ss % 2019
        d1[ss] += 1
        num10 = (num10 * 10) % 2019
    r = d1[0]
    for v in d1.values():
        r += v * (v - 1) // 2
    print(r)

def __starting_point():
    main()
__starting_point()

S=input()
N=len(S)

T=[0]
for i in range(N):
    p = int(S[-1-i])
    T.append( (T[-1]+ pow(10,i,2019)*p)%2019 )
    
from collections import Counter
ans=0
U=dict(Counter(T))
for num in U:
    ans += U[num]*(U[num]-1)//2
print(ans)

from collections import Counter
S = list(map(int, list(input())))
MOD = 2019

acc_mod = [0]
for i, s in enumerate(S[::-1]):
    acc_mod.append((acc_mod[-1] + s * pow(10, i, MOD)) % MOD)

ans = 0
for v in list(Counter(acc_mod).values()):
    ans += v * (v - 1) // 2
print(ans)


from itertools import accumulate
from collections import Counter


def solve(n):
    return n * (n - 1) // 2


s = input()[::-1]
MOD = 2019

# 事前計算
rest = []
for i, x in enumerate(s):
    # 1, 10, 100, 1000...の剰余を順に計算し、各桁までの剰余を計算
    if i == 0:
        tmp = 1
    else:
        tmp = tmp * 10 % MOD
    rest.append(int(x) * tmp % MOD)

result = [x % MOD for x in list(accumulate(rest))]

# 0は単独で2019の倍数
zero = result.count(0)

# 他はコンビネーションの結果
c = Counter(result)
c = list(c.values())

# 足して出力
print(sum([solve(x) for x in c if x >= 2]) + zero)

import sys, re
from collections import deque, defaultdict, Counter
from math import ceil, sqrt, hypot, factorial, pi, sin, cos, tan, asin, acos, atan, radians, degrees, log2, gcd
from itertools import accumulate, permutations, combinations, combinations_with_replacement, product, groupby
from operator import itemgetter, mul
from copy import deepcopy
from string import ascii_lowercase, ascii_uppercase, digits
from bisect import bisect, bisect_left, insort, insort_left
from heapq import heappush, heappop
from functools import reduce
def input(): return sys.stdin.readline().strip()
def INT(): return int(input())
def MAP(): return map(int, input().split())
def LIST(): return list(map(int, input().split()))
def ZIP(n): return zip(*(MAP() for _ in range(n)))
sys.setrecursionlimit(10 ** 9)
INF = float('inf')
mod = 10 ** 9 + 7 
#mod = 998244353
from decimal import *
#import numpy as np
#decimal.getcontext().prec = 10

S = input()
n = len(S)
s = [0]
for i, x in enumerate(S):
	s.append(int(S[i])*pow(10, n-i-1, 2019)%2019)

tmp = 0
t = []
for x in s:
	tmp = (tmp+x)%2019
	t.append(tmp)

ans = 0
for v in Counter(t).values():
	ans += v*(v-1)//2
print(ans)

MOD = 2019
"""
def part_count(S):
  B = [0 for _ in range(MOD)]
  C = [0 for _ in range(MOD)]
  L = [0 for _ in range(MOD)]
  R = [0 for _ in range(MOD)]
  
  if len(S) == 1:
    s = S[0]
    B[s] = 1 
    return (B, L, R, C)
  S_L = S[:len(S)//2]
  S_R = S[len(S)//2:]
  
  B1, L1, R1, C1 = part_count(S_L)
  B2, L2, R2, C2 = part_count(S_R)
    
  for j in range(MOD):
    C[j] += C1[j] + C2[j]
    L[j] += L1[j]
    R[j] += R2[j]
    for i in range(MOD):
      B[j] += B1[i] * B2[(-i + j)%MOD]
      L[j] += B1[i] * L2[(-i + j)%MOD]
      R[j] += B2[i] * R1[(-i + j)%MOD]
      C[j] += R1[i] * L2[(-i + j)%MOD]
  
  return (B, L, R, C) #両側隣接、左隣接、右隣接、隣接なしの個数
"""

S = list(input())
S.reverse()
N = len(S)
S = [int(S[i]) for i in range(N)]
MOD = 2019

a = 1
for i in range(N): 
  S[i] *= a
  S[i] %= MOD
  a *= 10 
  a %= MOD
  
#B, L, R, C = part_count(S)
#print(B[0] + L[0] + R[0] + C[0])
T = [0 for _ in range(N+1)]
for i in range(1,N+1):
  T[i] += S[i-1] + T[i-1]
  T[i] %= MOD

#print(T)

C = [0 for i in range(MOD)]  
for i in range(N+1):
  C[T[i]] += 1

#print(C)

ans = 0
for i in range(MOD):
  ans += C[i]*(C[i]-1)//2
  
print(ans)


s=input()
ls=len(s)
m=[0]*(2019)
m[0]+=1

cnt = 0
b = 0
for i in range(ls):
  a = (b + pow(10,cnt,2019)*int(s[ls - i -1])) % 2019
  m[a] += 1
  b = a
  cnt += 1

ans = 0
for i in m:
  if i <= 1:
    continue
  ans += i*(i-1)//2

print(ans)


import math,itertools,fractions,heapq,collections,bisect,sys,queue,copy

sys.setrecursionlimit(10**7)
inf=10**20
mod=10**9+7
dd=[(-1,0),(0,1),(1,0),(0,-1)]
ddn=[(-1,0),(-1,1),(0,1),(1,1),(1,0),(1,-1),(0,-1),(-1,-1)]

def LI(): return [int(x) for x in sys.stdin.readline().split()]
# def LF(): return [float(x) for x in sys.stdin.readline().split()]
def I(): return int(sys.stdin.readline())
def F(): return float(sys.stdin.readline())
def LS(): return sys.stdin.readline().split()
def S(): return input()

# Summarize count of factor within list -- START --
def summarizeList(l):
  sl=sorted(l)

  a=sl[0]
  c=1
  res=[]

  for x in sl[1:]:
    if x==a:
      c+=1
    else:
      res.append([a,c])
      a=x
      c=1
  res.append([a,c])

  return res
# Summarize count of factor within list --- END ---

def main():
  s=S()
  n=len(s)
  s=s[::-1]

  rl=[0]*(n+1)
  for i,x in enumerate(s):
    rl[i+1]=(int(x)*pow(10,i,2019))%2019

  for i in range(n):
    rl[i+1]+=rl[i]
    rl[i+1]%=2019


  sl=summarizeList(rl)
  # print(sl)

  ans=0
  for x,c in sl:
    ans+=(c*(c-1))//2

  return ans

# main()
print((main()))


from itertools import accumulate

S = input()

R = [1]
for _ in range(len(S)-1):
    R.append(R[-1]*10%2019)

L = [int(s)*r for s, r in zip(reversed(S), R)]
Z = list(accumulate(L, func=lambda a, b: (a+b)%2019))

T = [1]+[0]*2018
for z in Z:
    T[z] += 1

f = lambda n: n*(n-1)//2
print(sum(f(t) for t in T))

import sys
readline = sys.stdin.readline

S = readline().rstrip()
DIV = 2019

cur = 0
from collections import defaultdict
dic = defaultdict(int)
for i in range(len(S) - 1, -1, -1):
  cur += ((int(S[i]) % DIV) * pow(10, (len(S) - 1 - i), DIV)) % DIV
  cur %= DIV
  dic[cur] += 1

ans = 0
# 0は単独でもよい
for key, val in dic.items():
  if key == 0:
    ans += val
  ans += (val * (val - 1)) // 2

print(ans)

# 解説AC
import math,string,itertools,fractions,heapq,collections,re,array,bisect,sys,random,time, copy,bisect
#from operator import itemgetter
#from heapq import heappush, heappop
#import numpy as np
#from scipy.sparse.csgraph import shortest_path, floyd_warshall, dijkstra, bellman_ford, johnson
#from scipy.sparse import csr_matrix
#from decimal import Decimal, ROUND_HALF_UP, ROUND_HALF_EVEN
import sys

sys.setrecursionlimit(10**7)
inf = 10**20
mod = 10**9 + 7

stdin = sys.stdin

ni = lambda: int(ns())
nf = lambda: float(ns())
na = lambda: list(map(int, stdin.readline().split()))
nb = lambda: list(map(float, stdin.readline().split()))
ns = lambda: stdin.readline().rstrip()  # ignore trailing spaces

S = ns()
n = len(S)
T = [0] * (n+1)
d = {0: 1}
for k in range(n-1, -1, -1):
    tmp = (T[k+1] + pow(10, n - k - 1, 2019) * int(S[k])) % 2019
    T[k] = tmp
    if tmp not in list(d.keys()):
        d[tmp] = 1
    else:
        d[tmp] += 1
ans = 0
for k, v in list(d.items()):
    ans += v * (v - 1) // 2
print(ans)


S=input()
S=list(reversed(S))

m=2019
cnt=[0 for i in range(m)]

len_S=len(S)
x=1
tot=0
ans=0

for i in range(len(S)):
    cnt[tot]+=1
    tot+=(ord(S[i])-ord('0'))*x
    tot %= m
    ans+=cnt[tot]
    x=x*10%m

print(ans)