Problem:
Score : 400 points

Problem Statement

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 1

1817181712114

Sample Output 1

3

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

Sample Input 2

14282668646

Sample Output 2

2

Sample Input 3

2119

Sample Output 3

0

No pairs satisfy the condition.

Solution in Kotlin (1.3.71) (judge verdict: Runtime Error)

fun main(args: Array<String>) = ABC164D.main()

object ABC164D {
    fun log(message: Any?) {
        //println(message)// TODO: ←消す
    }

    val S: String
    val N: Int

    init {
        S = readString()
        N = S.length
    }

    data class Problem(val remain: String, val current: ModLong) {
        fun getOneOrNull(): Int? = when {
            remain.isEmpty() -> if (current.isValid()) 1 else 0
            else -> null
        }
    }

    fun main() {
        val table = LazyMap<Problem, Int> { problem ->
            problem.getOneOrNull() ?: problem.let {
                val nj = "${it.remain.first()}".toInt()
                val current = it.current * 10 + nj
                val sub = Problem(remain = it.remain.drop(1), current = current)
                val ans = get(sub) + if (it.current.isValid()) 1 else 0
                log("$it->$ans")
                ans
            }
        }

        val count = S.mapIndexed { i, si ->
            val ni = "$si".toInt()
            val current = ni.toModLong(2019)
            log("i=$i, ni=$ni")
            table[Problem(remain = S.drop(i+1), current = current)]
        }.sum()
        val ans = count
        println(ans)
    }

    fun Number.isValid() = this.toLong() % 2019 == 0L


    /*####################################################################################*/

    fun readString() = readLine()!!

    class LazyMap<K, V>(capacity: Int = 65536, private val init: LazyMap<K, V>.(K) -> V) {
        private val memo = HashMap<K, V>(capacity)
        operator fun get(key: K): V {
            return memo[key] ?: init(key).memorizingAt(key)
        }

        private fun V.memorizingAt(key: K): V {
            memo[key] = this
            return this
        }
    }

    fun Number.toModLong(base: Long): ModLong = ModLong(this.toLong() % base, base)
    class ModLong(
        private val value: Long,
        val base: Long
    ) : Number(), Comparable<ModLong> {
        override fun toString(): String = value.toString()
        override fun equals(other: Any?): Boolean = value == other
        override fun hashCode(): Int = value.hashCode()
        override fun compareTo(other: ModLong): Int = value.compareTo(other.value)
        override fun toByte(): Byte = value.toByte()
        override fun toChar(): Char = value.toChar()
        override fun toDouble(): Double = value.toDouble()
        override fun toFloat(): Float = value.toFloat()
        override fun toInt(): Int = value.toInt()
        override fun toLong(): Long = value
        override fun toShort(): Short = value.toShort()
        operator fun plus(other: ModLong): ModLong = (this.value + other.value).toModLong(base)
        operator fun plus(other: Number): ModLong = (this.value + other.toLong() % base).toModLong(base)
        operator fun minus(other: Number): ModLong = (this.value + base - other.toLong() % base).toModLong(base)
        operator fun times(other: Number): ModLong = (this.value * other.toLong() % base).toModLong(base)
        fun pow(n: Int): ModLong {
            var res = 1L
            var a = value
            var l = n
            while (l > 0) {
                if ((l and 1) == 1) {
                    res = (res * a) % base
                }
                a = a * a % base
                l /= 2
            }
            return res.toModLong(base)
        }

        fun pow(n: Long): ModLong {
            var res = 1L
            var a = value
            var l = n
            while (l > 0) {
                if ((l and 1L) == 1L) {
                    res = (res * a) % base
                }
                a = a * a % base
                l /= 2L
            }
            return res.toModLong(base)
        }
    }
}