import qualified Data.List as L
import qualified Data.Vector.Unboxed as V

main = do
  s <- getLine :: IO String
  let (_, decided) = L.mapAccumL (\n b -> ((n-1), (10^n) * (read [b]::Int))) ((length s) - 1) s
  let v_ruiseki = V.fromList $ (:) 0 $ snd $ L.mapAccumL (\sum b -> (sum+b, b+sum)) 0 decided
  let n = length s
  print $ length $ filter (\(_,_,n)-> n `mod` 2019==0)$ zentansaku 1 1 v_ruiseki n

  where
  zentansaku i j ruiseki max | i > max  = []
  zentansaku i j ruiseki max | j > max = zentansaku (i+1) (i+1) ruiseki max
  zentansaku i j ruiseki max = (i,j,(ruiseki V.!j - ruiseki V.!(i-1))):(zentansaku i (j+1) ruiseki max)
-- [(j-i) sigma k=0] (10^k * s_[i+k])
-- ∃n.   [(j-i) sigma k=0] (10^k * s_[i+k]) = 2019 * n
-- 全探索:  (|S|^2) / 2