jiahuimbzuai/CoQuIR huggingface dataset:
//  [cpp]
#include <cstdio>
#include <algorithm>

char s[100001];

int count(char d)
{
  const char digit[] = "010";
  const char* check = digit + d;
  int r = 0;
  for (int i = 0; s[i]; ++i)
  {
    if (s[i] != check[i & 1]) ++r;
  }
  return r;
}

int main()
{
  scanf("%s", s);
  printf("%d\n", std::min(count(0), count(1)));
  return 0;
}
//  [cpp]
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <bitset>
#include <string>
#include <cmath>
#include <complex>
#include <numeric>
#include <cassert>

#include <vector>
#include <array>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <deque>
#include <utility>

#define int64 long long
#define uint64 unsigned long long
#define PI 3.1415926535897932384626433832795
#define coutfix(i) cout << fixed << setprecision(i)
using namespace std;

int main()
{
	string ss;
	cin >> ss;
	int64 aa = 0;
	for(int64 ii = 0;ii < ss.length();ii++)
	{
		if((ss[ii] - '0') == ii % 2)
		{
			aa++;
		}
	}
	cout << min(aa, ss.length() - aa) << endl;
}
//  [cpp]
#include <bits/stdc++.h>
using namespace std;

int chColor(string S) {
    int l = 0, r = 0;
    for (int i = 0; i < (int)S.size(); i++) {
        if (i % 2 != 0 && S.at(i) != '1') {
            S.at(i) = 1; l++;
        } 
    }
    for (int i = 0; i < (int)S.size(); i++) {
        if (i % 2 == 0 && S.at(i) != '0') {
            S.at(i) = 0; r++;
        }
    }
    return max(l, r);
}

int main() {
    string S; cin >> S;
    cout << chColor(S) << endl;
}
//  [cpp]
#include <bits/stdc++.h>
using namespace std;
int main(){
  string S;
  cin>>S;
  long long N=S.size();
  long long zero_even=0,zero_odd=0;
  for(int i=0;i<N;i++){
    if(i%2==0 && S.at(i)=='0){
      zero_even++;
    }
    else if(i%2==1 && S.at(i)=='0){
      zero_odd++;
    }
  }
  long long a_1,a_2;
  a_1=(N+1)/2-zero_even+zero_odd;//010...
  a_2=zero_even+N/2-zero_odd;//101...
  cout<<min(a_1,a_2)<<endl;
}
//  [c]
#include "stdio.h"

int main(void)
{
    char S[100000];
    int count_1 = 0;
    int count_2 = 0;
    int ans;
    
    
    scanf("%s", S);
    for(int i = 0 ; i< 50000; ++i){

        
        /* 左端が１で始まるパターン */

        if(S[2*i] ==  '0'){
            count_1 = count_1 + 1;            
        }
        if(S[2*i+1] == '1'){
            count_1 = count_1 + 1;            
        }


        /* 左端が０で始まるパターン */
        if(S[2*i] ==  '1'){
            count_2 = count_2 + 1;            
        }
        if(S[2*i+1] == '0'){
            count_2 = count_2 + 1;            
        }
        
        if(S[2*i+1] == NULL){
            break;            
        }
    }
    if(count_1 < count_2){
        ans = count_1;
    }
    else{
        ans = count_2;
    }
    
    printf("%d", ans);
    
    
    
    return 0;
}
//  [c]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
	char s[100000];
	scanf("%s", s);
	int i;
	int n = strlen(s);
	char t[n], u[n];
	int countA = 0, countB = 0;
	for (i = 0;i < n; i++) {
		if (i % 2 == 0) {
			t[i] = '1';
			u[i] = '0';
		} else {
			t[i] = '0';
			u[i] = '1';
		}
		if (s[i] != t[i]) {
			countA++;
		}
		if (s[i] != u[i]) {
			countB++;
		}
	}
	/*
	for (i = 0; s[i] != '\0'; i++) {
		if (s[i] == '0' && s[i+1] == '0') {
			s[i+1] = '1';
			count++;
		} else if (s[i] == '1' && s[i+1] == '1'){
			s[i+1] = '0';
			count++;
		}
	}
	*/
	int ans = 0;
	printf("%d\n", ans = ( (countA >= countB) ? countB : countA));
	return 0;
}
//  [c]
#include<stdio.h>
#include<string.h>

int main(){
  int i,j,k;
  char S[1000000];
  j = k = 0;
  scanf("%s",S);
  
  for(i=0;i<strlen(S);i++){
    if(i%2==0){
      if(S[i]=='0')
        j++;
    }
    else
      if(S[i]=='1')
        j++;
  }
  
  for(i=0;i<strlen(S);i++){
    if(i%2==0){
      if(S[i]=='1')
        k++;
    }
    else
      if(S[i]=='0')
        k++;
  }
  
  
  if(j > k)
    printf("%d\n",k);
  else
    printf("%d\n",j);
  return 0;
}
//  [c]
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef long long ll;
typedef char keytype;

int gcd(int a, int b){ return (a % b) ? gcd(b, a % b) : b;}
int lcm(int a, int b){ return (a / gcd(a, b)) * b;}

/* a[0], ..., a[n-1] の数の最大公約数 */
int ngcd(int n, int a[])
{
    int i, d;

    d = a[0];
    for (i = 1; i < n && d != 1; i++)
        d = gcd(a[i], d);
    return d;
}

void quicksort(keytype a[], int first, int last)
{
    int i, j;
    keytype x, t;

    x = a[(first + last) / 2];
    i = first;  j = last;
    for ( ; ; ) {
        while (a[i] < x) i++;
        while (x < a[j]) j--;
        if (i >= j) break;
        t = a[i];  a[i] = a[j];  a[j] = t;
        i++;  j--;
    }
    if (first  < i - 1) quicksort(a, first , i - 1);
    if (j + 1 < last) quicksort(a, j + 1, last);
}

int is_prime(int x){
    if(x <= 1) return 0;
    for(int i = 2; i * i <= x; i++){
        if(x % i == 0) return 0;
    }
    return 1;
}

int is_substr(char s[], char t[], int i){
    int flag = 1;

    if(s[i] == '\0') flag = 0;

    for(int j = 0; j < strlen(t); ++j, ++i){
        if(s[i] != t[j]){
            flag = 0;
            break;
        }
    }
    return flag;
}

// factor list, number of factors, natural number
void factorize(int ftr[], int *num, int n){
    int a = 2, cnt = 0;

    while(n >= a){
        if(n % a == 0){
            n = n / a;
            ftr[cnt++] = a;
        }else{
            a++;
        }
    }
    *num = cnt;
}

//#define N 5
//int p[N + 1];
int nextperm(int p[], int N)  /* 辞書式順序で次の順列 */
{
    int i, j, t;

    i = N - 1;
    p[0] = 0;  /* 番人 */
    while (p[i] >= p[i + 1]) i--;
    if (i == 0) return 0;  /* 完了 */
    j = N;
    while (p[i] >= p[j]) j--;
    t = p[i];  p[i] = p[j];  p[j] = t;
    i++;  j = N;
    while (i < j) {
        t = p[i];  p[i] = p[j];  p[j] = t;  i++;  j--;
    }
    return 1;  /* 未了 */
}

void comb(int size1, int size2, int v[size1][size2]){
  for(int i = 0; i < size1; i++){
    v[i][0] = 1;
    v[i][i] = 1;
  }
  for(int k = 1; k < size1; k++){
    for(int j = 1; j < k; j++){
      v[k][j] = (v[k-1][j-1] + v[k-1][j]);
    }
  }
}

int abs_val(int a, int b){
    if(a > b) return a - b;
    else return b - a;
}

const int inf = 1012345678;
int main(){
    char s[100005], t[100005];

    scanf("%s", s);

    //int i = 0;
    int size = (int)strlen(s);
    //printf("%lu\n", strlen(s));
    for(int i = 0; i < size; ++i){
        s[i] = s[i] - '0';
        t[i] = s[i];
        //printf("%d\n", i);
    }

    if(size == 1){
        puts("0");
        return 0;
    }
    int cnt_w = 0;
    for(int j = 0; j < size; ++j){
        if((s[j] ^ s[j+1]) == 0){
            s[j+1] = ~s[j+1];
            cnt_w++;
            //printf("%d\n", s[i]);
        }
    }
    t[0] = ~t[0];
    int cnt_b = 0;
    for(int j = 0; j < size; ++j){
        if((t[j] ^ t[j+1]) == 0){
            t[j+1] = ~t[j+1];
            cnt_b++;
            //printf("%d\n", s[i]);
        }
    }

    if(cnt_b < cnt_w) printf("%d\n", cnt_b);
    else printf("%d\n", cnt_w);

    return 0;
}
//  [c]
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef long long ll;
typedef char keytype;

int gcd(int a, int b){ return (a % b) ? gcd(b, a % b) : b;}
int lcm(int a, int b){ return (a / gcd(a, b)) * b;}

/* a[0], ..., a[n-1] の数の最大公約数 */
int ngcd(int n, int a[])
{
    int i, d;

    d = a[0];
    for (i = 1; i < n && d != 1; i++)
        d = gcd(a[i], d);
    return d;
}

void quicksort(keytype a[], int first, int last)
{
    int i, j;
    keytype x, t;

    x = a[(first + last) / 2];
    i = first;  j = last;
    for ( ; ; ) {
        while (a[i] < x) i++;
        while (x < a[j]) j--;
        if (i >= j) break;
        t = a[i];  a[i] = a[j];  a[j] = t;
        i++;  j--;
    }
    if (first  < i - 1) quicksort(a, first , i - 1);
    if (j + 1 < last) quicksort(a, j + 1, last);
}

int is_prime(int x){
    if(x <= 1) return 0;
    for(int i = 2; i * i <= x; i++){
        if(x % i == 0) return 0;
    }
    return 1;
}

int is_substr(char s[], char t[], int i){
    int flag = 1;

    if(s[i] == '\0') flag = 0;

    for(int j = 0; j < strlen(t); ++j, ++i){
        if(s[i] != t[j]){
            flag = 0;
            break;
        }
    }
    return flag;
}

// factor list, number of factors, natural number
void factorize(int ftr[], int *num, int n){
    int a = 2, cnt = 0;

    while(n >= a){
        if(n % a == 0){
            n = n / a;
            ftr[cnt++] = a;
        }else{
            a++;
        }
    }
    *num = cnt;
}

//#define N 5
//int p[N + 1];
int nextperm(int p[], int N)  /* 辞書式順序で次の順列 */
{
    int i, j, t;

    i = N - 1;
    p[0] = 0;  /* 番人 */
    while (p[i] >= p[i + 1]) i--;
    if (i == 0) return 0;  /* 完了 */
    j = N;
    while (p[i] >= p[j]) j--;
    t = p[i];  p[i] = p[j];  p[j] = t;
    i++;  j = N;
    while (i < j) {
        t = p[i];  p[i] = p[j];  p[j] = t;  i++;  j--;
    }
    return 1;  /* 未了 */
}

void comb(int size1, int size2, int v[size1][size2]){
  for(int i = 0; i < size1; i++){
    v[i][0] = 1;
    v[i][i] = 1;
  }
  for(int k = 1; k < size1; k++){
    for(int j = 1; j < k; j++){
      v[k][j] = (v[k-1][j-1] + v[k-1][j]);
    }
  }
}

int abs_val(int a, int b){
    if(a > b) return a - b;
    else return b - a;
}

const int inf = 1012345678;
int main(){
    char s[100005];

    scanf("%s", s);

    //int i = 0;
    int size = (int)strlen(s);
    //printf("%lu\n", strlen(s));
    for(int i = 0; i < size; ++i){
        s[i] = s[i] - '0';
        //printf("%d\n", i);
    }

    if(size == 1){
        puts("0");
        return 0;
    }
    int cnt = 0;
    for(int j = 0; j < size; ++j){
        if((s[j] ^ s[j+1]) == 0){
            s[j+1] = ~s[j+1];
            cnt++;
            //printf("%d\n", s[i]);
        }
    }

    printf("%d\n", cnt);

    return 0;
}
//  [javascript]
input = require('fs').readFileSync('/dev/stdin', 'utf8')
lines = input.split('\n')
S = lines.shift()

a = 0
b = 0
for (i=0; i<S.length; i++) {
    if (S[i] != (i % 2 == 0 ? '0' : '1')) {
        a++
    }
    if (S[i] != (i % 2 == 1 ? '0' : '1')) {
        b++
    }
}

console.log(Math.min(a, b))
//  [javascript]
// inputに入力データ全体が入る
function Main(input) {
	// 1行目がinput[0], 2行目がinput[1], …に入る
	input = input.split("");
	//文字列から10進数に変換するときはparseIntを使います
  	var count = 0;
  	if (input.length !== 1) {
      for (var i=0; i<input.length; i++) {
        if (i === input.length - 1) break;
        if (input[i] === input[i + 1]) {
          count++;
          input[i + 1] = (input[i] === "0") ? "1" : "0";
        }
      }
    }
	
  	//出力
	console.log(count);
}

//*この行以降は編集しないでください（標準入出力から一度に読み込み、Mainを呼び出します）
Main(require("fs").readFileSync("/dev/stdin", "utf8"));
//  [javascript]
// inputに入力データ全体が入る
function Main(input) {
	// 1行目がinput[0], 2行目がinput[1], …に入る
    input = input.split("\n");
    // 数値の配列を作る
//    const numList1 = input[0].split(' ').map(x => parseInt(x, 10));
    const strList = input[0].split(' ');
    const SCharList = strList[0];
    const length = SCharList.length;

    var cnt = 0;
    for (var i = 0; i < length; i++) {
        var c = SCharList[i];
        // 010101...の方基準で考える
        if (i % 2 === 0 && c === '0') {
            cnt++;
        } else if (i % 2 === 1 && c === '1') {
            cnt++;
        }
    }

    // 0101010...と10101010...どちらに近いか
    cnt = Math.min(cnt, length - cnt);
    console.log(cnt);
}
 
Main(require("fs").readFileSync("/dev/stdin", "utf8"));
//  [javascript]
function Main(input) {
  input = input.split("");
  var a=0;
  for(var i=0;i<input.length;i++){
    if(i%2==0){
      if(input[i]==0){
        a++;
      }
    }else{
      if(input[i]==1){
        a++;
      }
    }
  }
  if(input.length-a<a){
    console.log(input.length-a);
  }else{
    console.log(a);
  }
}Main(require("fs").readFileSync("/dev/stdin", "utf8"));
//  [javascript]
"use strict"

function Main(input) {
  //input = input.split('\n');
  let odd = 0;
  let even = 0;
  for (let i=0;i<input.length;i++){
    if(i%2){
      if(input.charCodeAt(i) == 0x30){
        even++;
      } else {
        odd++;
      }
    } else {
      if(input.charCodeAt(i) == 0x30){
        odd++;
      } else {
        even++;
      }
    }
  }
  console.log(Math.min(odd, even))
}
Main(require("fs").readFileSync("/dev/stdin", "utf8"));
//  [javascript]
"use strict"

function Main(input) {
  //input = input.split('\n');
  let odd = 0;
  let even = 0;
  for (let i=0;i<input.length;i++){
    if(i%2){
      if(input.charAt(i) == '0'){
        even++;
      } else {
        odd++;
      }
    } else {
      if(input.charAt(i) == '0'){
        odd++;
      } else {
        even++;
      }
    }
  }
  console.log(Math.min(odd, even))
}
Main(require("fs").readFileSync("/dev/stdin", "utf8"));
//  [go]
package main

import (
  "fmt"
  "bufio"
  "os"
)

func main() {
  count := [2] int{0, 0}

  rd := bufio.NewReaderSize(os.Stdin, 100000)
  s := make([]byte, 0, 100000)
  for {
    l, p, _ := rd.ReadLine()
    s = append(s, l...)
    if !p {
      break
    }
  }

  n := len(s)

  for i := 0; i < n; i++ {
    if i % 2 == 0 {
      if s[i] == 48 {
        count[0]++
      } else {
        count[1]++
      }
    } else {
      if s[i] == 48 {
        count[1]++
      } else {
        count[0]++
      }
    }
  }

  if count[0] < count[1] {
    fmt.Println(count[0])
  } else {
    fmt.Println(count[1])
  }
}
//  [go]
package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

var sc = bufio.NewScanner(os.Stdin)
var rdr = bufio.NewReaderSize(os.Stdin, 1000000)

func readLine() string {
	buf := make([]byte, 0, 1000000)
	for {
		l, p, e := rdr.ReadLine()
		if e != nil {
			panic(e)
		}
		buf = append(buf, l...)
		if !p {
			break
		}
	}
	return string(buf)
}

func nextWord() string {
	sc.Scan()
	return sc.Text()
}

func nextInt() int {
	i, e := strconv.Atoi(nextWord())
	if e != nil {
		panic(e)
	}
	return i
}

func min(lhs, rhs int64) int64 {
	if lhs < rhs {
		return lhs
	}
	return rhs
}

func main() {
	sc.Split(bufio.ScanWords)
	s := readLine()

	var ans int64

	// count 0
	var cnt0 [2]int64
	var cnt1 [2]int64
	for i := 0; i < len(s); i++ {
		if s[i] == '0' {
			cnt0[i%2]++
		} else {
			cnt1[i%2]++
		}
	}
	// 01010...
	ans0 := cnt0[1] + cnt1[0]
	// 10101...
	ans1 := cnt0[0] + cnt1[1]
	ans = min(ans0, ans1)
	fmt.Println(ans)
}
//  [go]
package main
import (
	"fmt"
	"os"
	"bufio"
	"strings"
)

var stdin = bufio.NewScanner(os.Stdin)
var rdr = bufio.NewReaderSize(os.Stdin,1000000)
func readLine() string{
	//長いトークンを読み込みたい場合
	buf := make([]byte,0,1000000)
	for {
		read,isPrefix,error := rdr.ReadLine()
		if error!= nil{
			panic(error)
		}
		buf = append(buf,read...)
		if !isPrefix{
			break
		}
	}
	return string(buf)
}

func Input_Str() string {
	//かんたんに読み込みたい場合
	stdin.Scan()
	stringInput := stdin.Text()
	out := strings.TrimSpace(stringInput)
	return out
}

func main(){
	stdin.Split(bufio.ScanWords)
	s := readLine()
	count_W:=0
	count_B:=0

	for i:=0;i<len(s);i++{
		if i%2==0{
			if s[i]=='0'{
				count_W++
			}else{
				count_B++
			}
		}else{
			if s[i]=='1'{
				count_W++
			}else{
				count_B++
			}
		}
	}
	
	if count_W < count_B{
		fmt.Println(count_W)
	}else{
		fmt.Println(count_B)
	}
}
//  [go]
package main

import (
	"bufio"
	"fmt"
	"math"
	"os"
)

func nextStr() string {
	sc.Scan()
	return sc.Text()
}

var sc = bufio.NewScanner(os.Stdin)

func main() {
	// Code for C - Coloring Colorfully
	S := nextStr()

	var A string
	for i := 0; i < len(S); i++ {
		if i%2 == 0 {
			A += string('0')
		} else {
			A += string('1')
		}
	}

	var countA, countB int
	for i := 0; i < len(S); i++ {
		if A[i] != S[i] {
			countB++
		} else {
			countA++
		}
	}

	fmt.Println(math.Min(float64(countA), float64(countB)))
}
//  [go]
package main

import (
	"bufio"
	"fmt"
	"math"
	"os"
)

func nextStr() string {
	sc.Scan()
	return sc.Text()
}

var sc = bufio.NewScanner(os.Stdin)

func main() {
	// Code for C - Coloring Colorfully
	S := nextStr()
	/*
		var A string
		for i := 0; i < len(S); i++ {
			if i%2 == 0 {
				A += string('0')
			} else {
				A += string('1')
			}
		}
	*/

	var A string
	var countA, countB int
	for i := 0; i < len(S); i++ {

		if i%2 == 0 {
			A = string('0')
		} else {
			A = string('1')
		}

		if A[0] != S[i] {
			countB++
		} else {
			countA++
		}
	}

	fmt.Println(math.Min(float64(countA), float64(countB)))
}
//  [go]
package main

import (
	"bufio"
	"fmt"
	"math"
	"os"
)

func nextStr() string {
	sc.Scan()
	return sc.Text()
}

var sc = bufio.NewScanner(os.Stdin)

func main() {
	// Code for C - Coloring Colorfully
	S := nextStr()

	var A string
	var countA, countB int
	for i := 0; i < len(S); i++ {
		if i%2 == 0 {
			A = string('0')
		} else {
			A = string('1')
		}

		if A[0] != S[i] {
			countB++
		} else {
			countA++
		}
	}

	fmt.Println(math.Min(float64(countA), float64(countB)))
}
//  [ruby]
S = gets.chomp
N = S.size

s = S.to_i(2)

a = "#{ '01' * (N / 2) }#{ '0' if N.odd? }".to_i(2)
b = "#{ '10' * (N / 2) }#{ '1' if N.odd? }".to_i(2)

puts [a, b].map {|i| (i ^ s).to_s(2).count('1') }.min
//  [ruby]
s = gets.chomp!
n = s.size
q, r = n.divmod(2)
ans = "10" * q + "1" * r
cnt = (ans.to_i(2)^s.to_i(2)).to_s(2).count("1")
puts cnt > (n-cnt) ? n-cnt : cnt
//  [ruby]
io = STDIN

s=io.gets.chomp
len=s.size
x='01'*(len/2)
y='10'*(len/2)
if len.odd?
  x=x+"0"
  y=y+"1"
end
bins=s.to_i(2)
binx=x.to_i(2)
biny=y.to_i(2)
def popcount(x)
  x.to_s(2).count("1")
end
puts [popcount(bins^binx),popcount(bins^biny)].min
//  [ruby]
p`dd`.chop.bytes.map{1.&_1^$.+=1}.tally.values.min
//  [ruby]
s = gets.chomp.map(&:to_i)
ans = [0,0]
s.each.with_index{|c,i|ans[i%2^s[i]] += 1}
p ans.min
//  [ruby]
package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

func main() {
	sc.Split(bufio.ScanWords)
	s := nextMega()
	col := []int{0, 1}
	cnt := []int{0, 0}
	for i := range s {
		for j := 0; j < 2; j++ {
			if col[j] != int(s[i]-'0') {
				cnt[j]++
			}
		}
		col[0], col[1] = col[1], col[0]
	}

	puts(min(cnt[0], cnt[1]))
	wt.Flush()
}

var (
	sc  = bufio.NewScanner(os.Stdin)
	rdr = bufio.NewReaderSize(os.Stdin, 1000000)
	wt  = bufio.NewWriter(os.Stdout)
)

func next() string {
	sc.Scan()
	return sc.Text()
}

func nextInt() int {
	i, _ := strconv.Atoi(next())
	return i
}

func nextFloat64() float64 {
	f, _ := strconv.ParseFloat(next(), 64)
	return f
}

func nextInts(n int) []int {
	slice := make([]int, n)
	for i := 0; i < n; i++ {
		slice[i] = nextInt()
	}
	return slice
}

func nextFloat64s(n int) []float64 {
	slice := make([]float64, n)
	for i := 0; i < n; i++ {
		slice[i] = nextFloat64()
	}
	return slice
}

func nextMega() string {
	buf := make([]byte, 0, 1000000)
	for {
		l, p, _ := rdr.ReadLine()
		buf = append(buf, l...)
		if !p {
			break
		}
	}
	return string(buf)
}

func putf(format string, a ...interface{}) {
	fmt.Fprintf(wt, format, a...)
}

func puts(a ...interface{}) {
	fmt.Fprintln(wt, a...)
}

func min(nums ...int) int {
	ret := nums[0]
	for _, v := range nums {
		if v < ret {
			ret = v
		}
	}
	return ret
}
//  [rust]
use std::cmp::min;

fn main() {
    let mut buf = String::new();
    std::io::stdin().read_line(&mut buf).ok();
    let s = buf.trim().chars().collect::<Vec<char>>();
    let n = s.len();
    let s1 = (0..n).map(|x| if x % 2 == 0 {'1'} else {'0'}).collect::<Vec<_>>();
    let s2 = (0..n).map(|x| if x % 2 == 0 {'0'} else {'1'}).collect::<Vec<_>>();
    let (mut c1, mut c2) = (0, 0);
    for i in 0..n {
        if s1[i] != s[i] {c1 += 1}
        if s2[i] != s[i] {c2 += 1}
    }
    let ans = min(c1, c2);
    println!("{}", ans);
}
//  [rust]
fn read<T: std::str::FromStr>() -> T {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).ok();
    s.trim().parse().ok().unwrap()
}

fn main() {
    let s = read::<String>();
    let cs = s.chars().collect::<Vec<_>>();
    let mut count_a = 0;
    let mut count_b = 0;
    for (i, c) in cs.iter().map(|&c| ((c as u8) - b'0') as usize).enumerate() {
        if i % 2 != c {
            count_a += 1;
        }
        if (i + 1) % 2 != c {
            count_b += 1;
        }
    }

    let ans = std::cmp::min(count_a, count_b);
    println!("{}", ans);
}
//  [rust]
use std::io;
use std::str::FromStr;
use std::cmp::min;

fn input_char_vec() -> Vec<char> {
    let mut line: String = String::new();
    io::stdin().read_line(&mut line);
    line.trim().chars().collect()
}

fn main() {
    let s = input_char_vec();
    let mut s1 = vec!['0'; s.len()];
    let mut s2 = vec!['0'; s.len()];
    for i in 0..s.len() {
        if i % 2 == 0 {
            s1[i] = '1';
        } else {
            s2[i] = '1';
        }
    }
    let mut c1 = 0;
    let mut c2 = 0;
    for i in 0..s.len() {
        if s[i] != s1[i] {
            c1 += 1;
        }
        if s[i] != s2[i] {
            c2 += 1;
        }
    }
    // println!("{}, {}", c1, c2);
    println!("{}", min(c1, c2));
}
//  [swift]
// 🐋💭
import Foundation

func readInts() -> [Int] {
    return readLine()!.split(separator: " ").map { Int($0)! }
}

func readInt() -> Int {
    return Int(readLine()!)!
}

func readDoubles () -> [Double] {
    return readLine()!.split(separator: " ").map { Double($0)! }
}

func readDouble() -> Double{
    return Double(readLine()!)!
}
///最大公約数を返す
func gcd(_ m:Int, _ n:Int) -> Int {
    if n == 0 {return m}
    return gcd(n, m % n)
}
///最小公倍数を返す
func lcm(_ m:Int, _ n:Int) -> Int {
    return m * n / gcd(m, n)
}

///素数判定(試し割り)
func isPrime(_ x:Int) -> Bool {
    if x <= 1 || x % 2 == 0 { return false }
    if x == 2 { return true }
    for i in stride(from: 3, to: Int(ceil(sqrt(Double(x)))), by: 2){
        if x % i == 0 {
            return false
        }
    }
    return true
}

//https://program-life.com/669
///実行速度の計測
func exectionTime(action: () -> Void) {
    let startDate = Date()
    action()
    let endDate = Date()
    print(endDate.timeIntervalSince(startDate))
}

// https://melheaven.hatenadiary.jp/entry/atcoder144
///約数の配列を返す
func makeDivisors(_ n:Int) -> [Int] {
    var divisors = [Int]()
    for i in 1..<Int(pow(Double(n), 0.5)) + 1 {
        if n % i == 0{
            divisors.append(i + n / i)
        }
    }
    
    return divisors
}

//https://riptutorial.com/ja/swift/example/14738/インデックスを知らずに配列から要素を削除する
extension Array where Element: Equatable {
    
    mutating func remove(_ element: Element) {
        _ = index(of: element).flatMap {
            self.remove(at: $0)
        }
    }
}

func binarySearch(rifgt:Int, key:Int, ary:[String]) -> Int{
    var left = 0
    var right = rifgt
    
    while abs(right - left) > 1 {
        let mid = left + (right - left) / 2
        
        if Int(ary[mid])! < key {
            left = mid
            
        } else {
            right = mid
        }
    }
    return left
}

func arrangement (prev:String, ary:[String], returnVal:[String]) -> [String] {
    var returnVal = returnVal
    if ary.count == 0 {
        returnVal.append(prev)
        return returnVal
    }
    
    for s in ary {
        let wprev = prev + s
        var wary = ary
        wary.remove(s)
        returnVal = arrangement(prev: wprev, ary: wary, returnVal: returnVal)
    }
    return returnVal
}

func main() {
    let s = readLine()!.map { String($0) }
    var zeroOne = 0
    var oneZero = 0
    var nextColor = "0"
    
    for i in 0..<s.count {
        if s[i] == nextColor {
            zeroOne += 1
        } else {
            oneZero += 1
        }
        nextColor = nextColor == "0" ? "1": "0"
    }
    print(min(zeroOne, oneZero))
}
main()
//  [swift]
let S = readLine()!.characters.map{String($0)}
var (tile1, tile2) = (0, 0)
for i in 0..<S.count {
    if i % 2 > 0 {
        S[i]=="0" ? tile1++ : tile2++
    } else {
        S[i]=="1" ? tile1++ : tile2++
    }
}
print(min(tile1, tile2))
//  [swift]
var arr=readLine()!
var ba:[Bool] = arr.characters.map { if(String($0) == "0") { return false } else { return true }  }

var prev = ba[0]
var j: Int = 0
var c: Int = 0

for j = 1; j < ba.count; j+=1 {
  if( prev == ba[j] ) {
    ba[j] = !ba[j]
    c += 1
  }
  prev = ba[j]
}

print( c )
//  [swift]
var a=[0,0];for i in 0..<2{for j in 0..<(readLine()!.characters.map{String($0)}).count{if j%2^i != Int(S[j]){a[i]++}}};print(min(a[0],a[1]))
//  [swift]
var S=readLine()!.characters.map{String($0)},a=[0,0];for i in 0..<2{for j in 0..<S.count{if"\(j%2^i)"!=S[j]{a[i]++}}};print(min(a[0],a[1]))
//  [swift]
//var S=readLine()!.characters.map{String($0)},a=[0,0];for i in 0..<2{for(j,c)in S.enumerate(){if j%2^i != Int(c){a[i]++}}};print(min(a[0],a[1]))
var S=readLine()!.characters.map{String($0)},a=[0,0];for i in 0..<2{for j in S{if j%2^i != Int(S[j]){a[i]++}}};print(min(a[0],a[1]))
//  [typescript]
function main(input) {
  const s = input.trim();
  let pattern1 = 0;
  let pattern2 = 0;
  for (let i = 0; i < s.length; i++) {
    const char = s[i];
    if (i%2 === 0 && s[i] === "0") {
      pattern2++;
    } else if (i%2 === 0 && s[i] === "1") {
      pattern1++;
    } else if (i%2 === 1 && s[i] === "0") {
      pattern1++;
    } else if (i%2 === 1 && s[i] === "1") {
      pattern2++;
    }
  }
  const result = Math.min(pattern1, pattern2);
  console.log(result);
}
main(require("fs").readFileSync("/dev/stdin", "utf8"));
//  [typescript]

function Main(raw: string) {
  const input = raw.split("\n");
  const S = input[0];
  const N = S.length;
  let min = 100000;
  for (let start = 0; start < 2; start++) {
    let count = 0;
    for (let i = 0; i < N; i++) {
      let expected = (start + i) % 2 === 0 ? "0" : "1";
      if (S[i] !== expected) {
        count++;
      }
    }
    min = Math.min(min, count);
  }
  //出力
  console.log(min);
}

//DO NOT EDIT
Main(require("fs").readFileSync("/dev/stdin", "utf8"));
//  [typescript]
const input=require('fs').readFileSync('/dev/stdin','utf8').split(/[\s]/);let input_i=-1;const tn=():number=>{input_i++;return Number(input[input_i])};const tnn=(n:number):number[]=>{const a=[];for(let i=0;i<n;i++){a.push(tn())}return a};const ts=():string=>{input_i++;return String(input[input_i])};const tss=(n:number):string[]=>{const a=[];for(let i=0;i<n;i++){a.push(ts())}return a};const to=(...arg)=>{console.log(...arg)};const abs=(a)=>{return Math.abs(a)};const min=(...a)=>{return Math.min(...a)};const max=(...a)=>{return Math.max(...a)};const floor=(a)=>{return Math.floor(a)};const asc=(ar:number[])=>{const t=[...ar];return ar.sort((a,b)=>{return a-b})};const desc=(ar:number[])=>{const t=[...ar];return t.sort((a,b)=>{return b-a})};const sw=(a,arr:any[],op:'=='|'>='|'>'|'<='|'<'='==')=>{for(let i=0;i<arr.length-1;i+=2){if(eval(a+op+arr[i])){return arr[i+1]}}return arr[arr.length-1]};const near=(n:number,arr:number[]):number=>{let ne=arr[0],ni=0;for(let i=1;i<arr.length;i++){if(Math.abs(n-ne)>Math.abs(n-arr[i])){ne=arr[i];ni=i}}return ni};const deduplicate=(a:any[]):any[]=>{return Array.from(new Set(a))};const gcd=(x,y)=>{while(y){[x,y]=[y,x%y]}return x};
const main=()=>{
  let s=ts(),c=0
  for(let i=0;i<s.length;i++){
    if(i%2===0&&s[i]==='0'){
      c++
    }else if(i%2===1&&s[i]==='1'){
      c++
    }
  }
  if(c>=s.length/2){
    to(s.length-c)
  }else{
    to(c)
  }
}
main()
//  [typescript]
let inp = require('fs').readFileSync('/dev/stdin', 'utf8').replace(/\n/g, '').trim();

if (inp.length % 2 === 1) {
  const last = inp.slice(-1) === '0' ? '1' : '0';
  inp += last;
}

const grps = inp.match(/.{2}/g);

const zo = grps.filter(v => v === '01');
const oz = grps.filter(v => v === '10');
const zz = grps.filter(v => v === '00');
const oo = grps.filter(v => v === '11');

const minPtn = Math.min(zo.length, oz.length);
const lastPtn = grps[grps.length - 1];

const mnsone = (minPtn === zo.length && lastPtn === '01') || (minPtn === oz.length && lastPtn === '10')

console.log(
Math.min(zo.length, oz.length) * 2 + zz.length + oo.length + (mnsone ? -1 : 0)
)
//  [typescript]
let inp = require('fs').readFileSync('/dev/stdin', 'utf8');

if (inp.length % 2 === 1) {
	inp = inp + (inp.slice(-1) === '0' ? '1' : '0')
}

const grps = inp.match(/.{2}/g);

const zo = grps.filter(v => v === '01');
const oz = grps.filter(v => v === '10');
const zz = grps.filter(v => v === '00');
const oo = grps.filter(v => v === '11');

console.log(Math.min(zo.length, oz.length) * 2 + zz.length + oo.length)
//  [typescript]
"use strict";
function main(arg) {
  const input = String(arg);
  // 文字列 "0101・・・"　との差
  // 文字列 "1010・・・"　との差
  let unMatchCont0 = 0;
  let unMatchCont1 = 0;
  input.split("").forEach((char, index) => {
    if (index % 2 === 0) {
      if (char != "0") {
        unMatchCont0++;
      } else {
        unMatchCont1++;
      }
    } else {
      if (char != "1") {
        unMatchCont0++;
      } else {
        unMatchCont1++;
      }
    }
  });
  console.log(Math.min(unMatchCont0, unMatchCont1));
}
main(require("fs").readFileSync("/dev/stdin", "utf8"));
//  [python]

S = input()
N = len(S)

num = [0] * 2019
num[0] = 1
now, ans = 0, 0
_10 = 1

for i in range(N-1, -1, -1):
    now = (now + int(S[i]) * _10) % 2019
    _10 *= 10
    _10 %= 2019
    ans += num[now]
    num[now] += 1
print(ans)
//  [python]
s=input()
a=[0]*2019
a[0]+=1
pot=1
v=0
ans=0
for i in range(len(s)-1,-1,-1):
	digit=int(s[i])
	v=(v+digit*pot)%2019
	pot=(pot*10)%2019
	ans+=a[v]
	a[v]+=1

print(ans)
//  [python]
S = input()
s_reverse = S[::-1]

dp = [0]*2019
now_sum = 0
ten_times = 1

for ch in s_reverse:
    now_sum = (now_sum + int(ch)*ten_times) % 2019
    ten_times = (ten_times * 10) % 2019
    dp[now_sum] += 1

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

print(ans)
//  [python]
S = input()
count = 0
for i in range(len(S)-3):
  for j in range(i+4, len(S)+1): # |2019| = 4
    s = int(S[i:j])
    if s % 2019 == 0:
      count += 1
print(count)
//  [python]
s = input()
ln = len(s)
d = [int(i) for i in s]
count = 0
for i in range(ln - 3):
    total = sum(d[i:i+3])
    for j in range(i + 3, ln):
        total += d[j]
        if total % 3 == 0 and int(s[i:j+1]) % 673 == 0:
            # print(i, j, int(s[i:j+1]))
            count += 1
print(count)
//  [python]
s = input()
ln = len(s)
d = [int(i) for i in s]
count = 0
for i in range(ln - 3):
    total = sum(d[i:i+3])
    for j in range(i + 3, ln):
        total += d[j]
        if total % 3 == 0 and int(s[i:j+1]) % 673 == 0:
            print(i, j, int(s[i:j+1]))
            count += 1
print(count)
//  [java]
import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author KharYusuf
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        FastReader in = new FastReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        DMultipleOf2019 solver = new DMultipleOf2019();
        solver.solve(1, in, out);
        out.close();
    }

    static class DMultipleOf2019 {
        public void solve(int testNumber, FastReader s, PrintWriter w) {
            char[] c = s.next().toCharArray();
            int n = c.length;
            int[] d = new int[n + 1];
            int cur = 1;
            long ans = 0;
            int[] f = new int[2019];
            f[0]++;
            for (int i = n - 1; i >= 0; i--) {
                d[i] = (c[i] - '0') * cur + d[i + 1];
                cur *= 10;
                d[i] %= 2019;
                cur %= 2019;
                ans += f[d[i]];
                f[d[i]]++;
            }
            w.println(ans);
        }

    }

    static class FastReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private FastReader.SpaceCharFilter filter;

        public FastReader(InputStream stream) {
            this.stream = stream;
        }

        public int read() {

            if (numChars == -1)
                throw new InputMismatchException();

            if (curChar >= numChars) {

                curChar = 0;

                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }

                if (numChars <= 0)
                    return -1;
            }

            return buf[curChar++];
        }

        public String next() {

            int c = read();

            while (isSpaceChar(c))
                c = read();

            StringBuilder res = new StringBuilder();

            do {
                res.appendCodePoint(c);
                c = read();
            }
            while (!isSpaceChar(c));

            return res.toString();
        }

        public boolean isSpaceChar(int c) {

            if (filter != null)
                return filter.isSpaceChar(c);

            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);

        }

    }
}
//  [java]
import java.io.*;
import java.util.*;
import static java.lang.System.out;

public class Main {
    static MyReader in = new MyReader();

    public static void main(String[] args){
        String S = in.s();
        int len = S.length();
        int[] a = new int[2019];
        a[0] = 1;
        int x = 0;
         d = int;
        for (int i = len - 1; i >= 0; i--) {
            int j = S.charAt(i) - '0';
            x = (j * d + x) % 2019;
            a[x]++;
            d = 10 * d % 2019;
        }
        long ans = 0;
        for (int i = 0; i < 2019; i++) {
            ans += (long)a[i] * (a[i] - 1) / 2;
        }
        out.println(ans);
    }
}

class MyReader extends BufferedReader {
    char[] cbuf = new char[1024];
    int head = 0;
    int tail = 0;

    MyReader() {
        super(new InputStreamReader(System.in));
    }

    char next() {
        if (head == tail) {
            try {
                tail = read(cbuf, 0, cbuf.length);
            } catch (IOException e) {}
            head = 0;
        }
        return cbuf[head++];
    }

    void back() {
        head--;
    }

    boolean minus() {
        boolean minus;
        while (true) {
            char c = next();
            if (c != ' ' && c != '\n' && c != '\r') {
                if (!(minus = c == '-')) back();
                return minus;
            }
        }
    }

    void skip() {
        while (true) {
            char c = next();
            if (c != ' ' && c != '\n' && c != '\r') {
                back();
                break;
            }
        }
    }

    char[] s(final int N) {
        skip();
        char[] s = new char[N];
        for (int i = 0; i < s.length; i++) {
            s[i] = next();
        }
        return s;
    }

    String s() {
        try {
            return readLine();
        } catch (IOException e) {
            return "";
        }
    }

    int i() {
        boolean minus = minus();
        int n = 0;
        while (true) {
            int k = next() - '0';
            if (k < 0 || 9 < k) break;
            n = 10 * n + k;
        }
        return minus ? -n : n;
    }

    int[] ii(final int N) {
        int[] a = new int[N];
        for (int j = 0; j < a.length; j++) a[j] = i();
        return a;
    }

    long l() {
        boolean minus = minus();
        long n = 0;
        while (true) {
            int k = next() - '0';
            if (k < 0 || 9 < k) break;
            n = 10 * n + k;
        }
        return minus ? -n : n;
    }
}
//  [cpp]
#pragma GCC optimize ("Ofast")
#pragma GCC target ("avx2")
//#include<bits/stdc++.h>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
#define rep(i, n) for(int i = 0; i < (n); i++)
#define rep1(i, n) for(int i = 1; i <= (n); i++)
#define co(x) cout << (x) << "\n"
#define cosp(x) cout << (x) << " "
#define ce(x) cerr << (x) << "\n"
#define cesp(x) cerr << (x) << " "
#define pb push_back
#define mp make_pair
#define chmin(x, y) x = min(x, y)
#define chmax(x, y) x = max(x, y)
#define Would
#define you
#define please

char S[200005];

int main() {
	//cin.tie(0);
	//ios::sync_with_stdio(false);


	fread(S, 1, 200005, stdin);
	int L = 0, R = 200005;
	while (L + 1 < R) {
		int M = (L + R) / 2;
		if (S[M] >= '0') L = M;
		else R = M;
	}

	int N = R;
	int a = 0;
	int A[2020] = {};
	A[0] = 1;

	ll kotae = 0;
	int tmp = 0;
	int are = 1;
	int shou = N / 5;
	int i = N - 1;
	int amari = N % 5;
	rep(j, shou) {
		tmp += (S[i--] - '0') * are;
		tmp %= 2019;
		kotae += A[tmp]++;
		are *= 10;

		tmp += (S[i--] - '0') * are;
		tmp %= 2019;
		kotae += A[tmp]++;
		are *= 10;

		tmp += (S[i--] - '0') * are;
		tmp %= 2019;
		kotae += A[tmp]++;
		are *= 10;

		tmp += (S[i--] - '0') * are;
		tmp %= 2019;
		kotae += A[tmp]++;
		are *= 10;

		tmp += (S[i--] - '0') * are;
		tmp %= 2019;
		kotae += A[tmp]++;
		are *= 10;
		are %= 2019;
	}
	rep(j, amari) {
		tmp += (S[i--] - '0') * are;
		tmp %= 2019;
		kotae += A[tmp]++;
		are *= 10;
	}

	printf("%lld\n", kotae);


	Would you please return 0;
}
//  [cpp]
#include<cstdio>
#include<cstring>

typedef long long ll;
const int maxn = 2E+5 + 5;

int n;
ll S, ans, base;
int sum[2025];
char s[maxn];

int main() {
	scanf("%s", s + 1);
	n = std::strlen(s + 1);
	
	sum[0] = 1, base = 1;
	for(int i = n; i >= 1; --i) {
		S = (S + (s[i] - '0') * base) % 2019ll;
		ans += sum[S]++, base = base * 10 % 2019ll;
	}
	printf("%lld", ans);
}
//  [cpp]
#include <stdio.h>
#include <string.h>
#define maxn 200010
#define mod 2019
#define LL long long
char s[maxn];
int cnt[mod];
LL ans;
int main()
{
    int n,i,x,y;
    scanf("%s",s+1);
    n=strlen(s+1),y=1,x=0;
    for(i=n; i>=1; i--)
    {
        x=(x+(s[i]-'0')*y)%mod;
        y=y*10%mod;
        cnt[x]++;
    }
    for(i=1; i<2019; i++)
        if(cnt[i]>1)
            ans+=(LL)(cnt[i]-1+1)*(cnt[i]-1)/2;
    ans+=(LL)cnt[0]*(cnt[0]+1)/2;//特殊余数处理
    printf("%lld\n",ans);
    return 0;
}
//  [cpp]
#include<algorithm>
#include<bitset>
#include<cmath>
#include<complex>
#include<deque>
#include<functional>
#include<iomanip>
#include<iostream>
#include<iterator>
#include<map>
#include<numeric>
#include<queue>
#include<set>
#include<stack>
#include<string>
#include<unordered_map>
#include<unordered_set>
#include<utility>
#include<vector>
#include<chrono>
using namespace std;
#define rep(i,n) for(int i=0; i<(n); i++)
#define FOR(i,x,n) for(int i=x; i<(n); i++)
#define vint(a,n) vint a(n); rep(i, n) cin >> a[i];
#define vll(a,n) vll a(n); rep(i, n) cin >> a[i];
#define ALL(n) begin(n),end(n)
#define RALL(n) rbegin(n),rend(n)
#define MOD (1000000007)
// #define MOD (998244353)
#define INF (2e9)
#define INFL (2e18)

typedef long long ll;
typedef unsigned int ui;
typedef unsigned long long ull;
using vint=vector<int>;
using vll=vector<ll>;
using vbool=vector<bool>;
template<class T>using arr=vector<vector<T>>;
template<class T>int popcount(T &a){int c=0; rep(i, 8*(int)sizeof(a)){if((a>>i)&1) c++;} return c;}
template<class T>void pr(T x){cout << x << endl;}
template<class T>void prvec(vector<T>& a){rep(i, a.size()-1){cout << a[i] << " ";} pr(a[a.size()-1]);}
template<class T>void prarr(arr<T>& a){rep(i, a.size()) if(a[i].empty()) pr(""); else prvec(a[i]);}
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return 1; } return 0; }

int main()
{
    string s; cin >> s;
    int n = s.size();
    vint a(2019);
    vint md(2019);
    md[0] = 1;
    FOR(i, 1, 2019){
        md[i] = md[i-1]*10;
        md[i] %= 2019;
    }
    a[0]++;
    // prvec(md);
    reverse(ALL(s));

    ll t = 0;
    rep(i, n){
        // pr(t);
        t += (s[i]-'0') * md[i];
        t %= 2019;
        a[t]++;
    }

    ll ans = 0;
    rep(i, 2019){
        ans += a[i]*(a[i]-1)/2;
    }
    pr(ans);
    return 0;}
//  [cpp]
#include <bits/stdc++.h>
using namespace std;

int main ()
{
    string  s ;
    cin >> s;
    reverse(s.begin(),s.end()) ; 
    map <int,int> c;
    int  ss=0,ans=0,cur=1;
    c[0] = 1 ; 
    for (int i=0;i<s.size();i++){
        ss = (ss+((s[i]-'0')*cur))%2019;
        ans += c[ss] ; 
        c[ss]++ ; 
        cur = (cur*10)%2019; 
    }
    cout << ans%2019 << endl ; 
    return 0;
}
//  [cpp]
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef long double ld;
typedef vector<vector<int>> Graph;
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};
#define pi 3.14159265359
#define inf 2147483647
#define INF 9223372036854775807
#define mod 1000000007
#define mod2 998244353

int modPow(long long a, long long n, long long p) {
    if (n == 0) return 1;
    if (n == 1) return a % p;
    if (n % 2 == 1) return (a * modPow(a, n - 1, p)) % p;
    long long t = modPow(a, n / 2, p);
    return (t * t) % p;
}

int main() {
	string S; cin >> S;
	int size = S.size();
	vector<ll> right(size);
	map<int, int> m;
	for(int i = size - 1; i >= 0; i--) {
		if(i == size - 1) {
			right[size - 1] = S[size - 1] - '0';
			m[right[size - 1]] = 1;
			continue;
		}
		right[i] = (right[i + 1] + (S[i] - '0') * modPow(10, size - 1 - i, 2019)) % 2019;
		if(!m.count(right[i])) m[right[i]] = 1;
		else m[right[i]]++;
	}
	int ans = 0;
	for(auto p: m) {
		ans += (p.second * (p.second - 1)) / 2;
		if(p.first == 0) ans++;
	}
	cout << ans << endl;
	return 0;
}
//  [c]
#include <float.h>
#include <inttypes.h>
#include <limits.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <math.h>
#ifdef __cplusplus
#include <bits/stdc++.h>
#endif

uint32_t nextpint(void){ char c=getchar_unlocked(); while(c<'0'||'9'<c) c=getchar_unlocked(); uint32_t x=0; while('0'<=c && c<='9'){ x=x*10+c-'0'; c=getchar_unlocked(); } return x; }
uint32_t nextstr(char *s){ char c=getchar_unlocked(); while(c==' '||c=='\n') c=getchar_unlocked(); uint32_t len=0; while(c!=' '&&c!='\n'){ *s++=c-'0'; len++; c=getchar_unlocked(); } *s='\0'; return len; }
void printint(uint32_t x){ if(x<0){x=-x; putchar_unlocked('-');}else if(x==0){putchar_unlocked('0');} int d=0; char s[10]; while(x){ s[d]='0'+x%10; x/=10; d++; } for (int i=d-1; i>=0; i--) putchar_unlocked(s[i]); putchar_unlocked('\n'); }
void rsort_str(void *base, const int count, const int size);

char s[200001];
uint32_t m[2019]={1};

int main(void){
	uint32_t n=nextstr(s);
	uint32_t a=0, b=1;
	for(int32_t i=n-1; i>=0; i--){
		a+=b*s[i];
		a%=2019;
		m[a]++;
		b*=10;
		b%=2019;
	}
	uint64_t ans=0;
	for(uint32_t i=0; i<2019; i++){
		ans+=(uint64_t)m[i]*(m[i]-1)/2;
	}
	printf("%"PRIu64"\n", ans);
}
//  [c]
#include <float.h>
#include <inttypes.h>
#include <limits.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <math.h>
#ifdef __cplusplus
#include <bits/stdc++.h>
#endif

uint32_t nextpint(void){ char c=getchar_unlocked(); while(c<'0'||'9'<c) c=getchar_unlocked(); uint32_t x=0; while('0'<=c && c<='9'){ x=x*10+c-'0'; c=getchar_unlocked(); } return x; }
uint32_t nextstr(char *s){ char c=getchar_unlocked(); while(c==' '||c=='\n') c=getchar_unlocked(); uint32_t len=0; while(c!=' '&&c!='\n'){ *s++=c-'0'; len++; c=getchar_unlocked(); } *s='\0'; return len; }
void printint(uint32_t x){ if(x<0){x=-x; putchar_unlocked('-');}else if(x==0){putchar_unlocked('0');} int d=0; char s[10]; while(x){ s[d]='0'+x%10; x/=10; d++; } for (int i=d-1; i>=0; i--) putchar_unlocked(s[i]); putchar_unlocked('\n'); }
void rsort_str(void *base, const int count, const int size);

char s[200001];
uint32_t m[2019]={1};

int main(void){
	uint32_t n=read(0, s, sizeof(s))-1;
	uint32_t a=0, b=1;
	for(int32_t i=n-1; i>=0; i--){
		a+=b*(s[i]-'0');
		a%=2019;
		m[a]++;
		b*=10;
		b%=2019;
	}
	uint64_t ans=0;
	for(uint32_t i=0; i<2019; i++){
		ans+=(uint64_t)m[i]*(m[i]-1)/2;
	}
	printf("%"PRIu64"\n", ans);
}
//  [c]
printf("%d",kind);
//  [c]
#include <vector.h>
using namespace std;

#define rep(i, n) for (int i = 0, i##_len = (n); i < i##_len; ++i)
#define xrep(i, a, b) for (int i = int(a); i < int(b); ++i)
using ll = long long;
const int INF = 1001001001;

vector<int> num;
int cnt = 0;
bool visited[300000][300000];
int N = 0;

void dfs(int i, int j) {
    if (visited[j][i]==true) return;
    if(i==N+1) {
        return;
    }
    if(j==N+1) {
        return;
    }
    visited[j][i] = true;
    int n = 0;
    for(int k=0; k<j-i; k++) {
        n += num[i+k]*pow(10, k);
    }
    if(n%2019==0 && n!=0) {
        cnt++;
    }
    dfs(i, j+1);
    dfs(i+1, j);
}

int main() {
    string S;
    cin >> S;
    for(auto s: S) {
        num.push_back(s-'0');
    }
    reverse(num.begin(), num.end());
    N = num.size();
    dfs(0, 0);
    print(cnt);

    return 0;
}
//  [c]
#include <vector>
using namespace std;

#define rep(i, n) for (int i = 0, i##_len = (n); i < i##_len; ++i)
#define xrep(i, a, b) for (int i = int(a); i < int(b); ++i)
using ll = long long;
const int INF = 1001001001;

vector<int> num;
int cnt = 0;
bool visited[300000][300000];
int N = 0;

void dfs(int i, int j) {
    if (visited[j][i]==true) return;
    if(i==N+1) {
        return;
    }
    if(j==N+1) {
        return;
    }
    visited[j][i] = true;
    int n = 0;
    for(int k=0; k<j-i; k++) {
        n += num[i+k]*pow(10, k);
    }
    if(n%2019==0 && n!=0) {
        cnt++;
    }
    dfs(i, j+1);
    dfs(i+1, j);
}

int main() {
    string S;
    cin >> S;
    for(auto s: S) {
        num.push_back(s-'0');
    }
    reverse(num.begin(), num.end());
    N = num.size();
    dfs(0, 0);
    print(cnt);

    return 0;
}
//  [javascript]
"use strict";
var input=require("fs").readFileSync("/dev/stdin","utf8");
var cin=input.split(/ |\n/),cid=0;
function next(a){return a?cin[cid++]:+cin[cid++];}
function nexts(n,a){return a?cin.slice(cid,cid+=n):cin.slice(cid,cid+=n).map(a=>+a);}
function nextm(h,w,a){var r=[],i=0;if(a)for(;i<h;i++)r.push(cin.slice(cid,cid+=w));else for(;i<h;i++)r.push(cin.slice(cid,cid+=w).map(a=>+a));return r;}
function xArray(v){var a=arguments,l=a.length,r="Array(a["+--l+"]).fill().map(x=>{return "+v+";})";while(--l)r="Array(a["+l+"]).fill().map(x=>"+r+")";return eval(r);}

var myOut = main();
if(myOut !== undefined)console.log(myOut);

function main(){
  var s = next(1);
  var map = xArray(0,2020);
  var x = 0, ans = 0, k = 1;
  map[0] = 1;
  for(var i = s.length; i--;){
    x += +s[i] * k;
    x %= 2019;
    k = k*10%2019;
    ans += map[x]++;
  }
  return ans;
}
//  [javascript]
const main = input => {
  const mod = 2019
  let s = input.trim().split('')
  let ln = s.length
  
  let ms = new Array(ln+1).fill(0)
  let cr = 1
  for(let i = ln-1; 0 <= i; i--) {
    ms[i] = (ms[i+1] + cr*Number(s[i])) % mod
    cr = (cr*10) % mod
  }
  
  let cnt = new Array(mod).fill(0)
  ms.forEach(v => cnt[v] += 1)
  let ans = 0
  cnt.forEach(v => {if(v >= 2) ans += v*(v-1)/2})
  console.log(ans.toString())
}

main(require("fs").readFileSync("/dev/stdin", "utf8"))
//  [javascript]
"use strict";
    
const main = arg => {
    arg = arg.trim().split("\n");
    const S = (arg[0].split(" ")[0]);
    const N = S.length;
    
    let answer = 0;
    let cnt = [...Array(2020)].fill(0);
    cnt[0] = 1;
    
    let total = 0;
    let p = 1;
    
    for(let i=N-1; i>=0; i--) {
        total = (total + parseInt(S[i]) * p) % 2019;
        
        // console.log("total:" + total);
        // console.log("S[i]:" + S[i]);
        
        answer += cnt[total];
        
        p = (p * 10) % 2019;
        // console.log("p:" + p);
        // console.log("------")
        cnt[total]++;
    }
    
    // console.log(cnt);
    console.log(answer);
}
main(require('fs').readFileSync('/dev/stdin', 'utf8'));
//  [javascript]
console.log((args=>{
  const S = args.trim().split``.map(v=>v|0);
  const L = S.length;
  const M = Array(2019).fill(0);
  let e = 0, d = 1;
  for ( let i = L-1; i >=0; i-- ) {
    e = (e + S[i] * d)%2019;
    M[e]++;
    d = d*10%2019;
  }
  let a = M[0];
  for ( let i = 1; i < 2019; i++ ) {
    if ( M[i] < 2 ) continue;
    a += M[i] * (M[i]-1) / 2;
  }
  return `${a}`;
})(require('fs').readFileSync('/dev/stdin', 'utf8')));
//  [javascript]
const S = require("fs").readFileSync("/dev/stdin", "utf8")
const mod = 2019
const map = Array(2020).fill(0)
map[0] = 1
let c = 0
let p = 1
let m = 0

for (let i = S.length - 1; i >= 0; i--) {
    m = (m + S[i] * p) % mod
    c += map[m]
    map[m]++
    p = p * 10 % mod
}

console.log(c)