stablegradients/pie-gem5-pairs huggingface dataset:
// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;

using ll = long long;

const int N = 2e5 + 100;



int n, q, x[N];

ll sum[N], f[N], fen[2][N];



void update(int id, int p, ll val) {

  if (p <= 0) return;

  for (; p; p -= p & -p) fen[id][p] = min(fen[id][p], val);

}



ll query(int id, int p) {

  ll res = 1e18;

  if (p <= 0) return res;

  for (; p <= n; p += p & -p) res = min(res, fen[id][p]);

  return res;

}



int main() {

  ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);

  cin >> n >> q; q += 2;

  for (int i = 1; i <= q; ++i) {

    cin >> x[i];

    if (i > 1) sum[i] = sum[i - 1] + abs(x[i] - x[i - 1]);

  }

  memset(fen, 0x3f, sizeof(fen));

  for (int i = q - 1; i; --i) {

    f[i] = 1e18;

    f[i] = min(f[i], sum[q] - sum[i + 1] + f[q]);

    f[i] = min(f[i], query(0, x[i]) - x[i] - sum[i + 1]);

    f[i] = min(f[i], query(1, n + 1 - x[i]) + x[i] - sum[i + 1]);

    update(0, x[i + 1], f[i] + sum[i] + x[i + 1]);

    update(1, n + 1 - x[i + 1], f[i] + sum[i] - x[i + 1]);

  }

  cout << f[1];

  return 0;

}

// Faster C++ solution for the same problem (measured speedup: 21.681278179790347x):
#include <cstdio>

#include <algorithm>

using namespace std;

typedef long long LL;

const int mod = 1e9 + 7;

const int MAXN = 200050;

int n, q, A, lst;

LL tag, mn[MAXN<<2][2];

void build(int i, int l, int r) {

	if(l == r) {

		mn[i][0] = abs(l-A) - l;

		mn[i][1] = abs(l-A) + l;

		return;

	}

	int mid = (l + r) >> 1;

	build(i<<1, l, mid);

	build(i<<1|1, mid+1, r);

	mn[i][0] = min(mn[i<<1][0], mn[i<<1|1][0]);

	mn[i][1] = min(mn[i<<1][1], mn[i<<1|1][1]);

}

LL qry(int i, int l, int r, int x, int y, int o) {

	if(x <= l && r <= y) return mn[i][o];

	int mid = (l + r) >> 1; LL re = 1ll<<60;

	if(x <= mid) re = min(re, qry(i<<1, l, mid, x, y, o));

	if(y > mid) re = min(re, qry(i<<1|1, mid+1, r, x, y, o));

	return re;

}

void upd(int i, int l, int r, int x, LL val) {

	if(l == r) {

		if(val < mn[i][0]+l+tag) {

			mn[i][0] = val-tag-l;

			mn[i][1] = val-tag+l;

		}

		return;

	}

	int mid = (l + r) >> 1;

	if(x <= mid) upd(i<<1, l, mid, x, val);

	else upd(i<<1|1, mid+1, r, x, val);

	mn[i][0] = min(mn[i<<1][0], mn[i<<1|1][0]);

	mn[i][1] = min(mn[i<<1][1], mn[i<<1|1][1]);

}

LL ans;

void dfs(int i, int l, int r) {

	if(l == r) {

		ans = min(ans, mn[i][0]+l+tag);

		return;

	}

	int mid = (l + r) >> 1;

	dfs(i<<1, l, mid);

	dfs(i<<1|1, mid+1, r);

}

int main () {

	scanf("%d%d%d%d", &n, &q, &lst, &A);

	build(1, 1, n);

	for(int i = 1, x; i <= q; lst = x, ++i) {

		scanf("%d", &x);

		LL val = qry(1, 1, n, 1, x, 0) + tag + x;

		if(x < n) val = min(val, qry(1, 1, n, x+1, n, 1) + tag - x);

		tag += abs(x-lst);

		upd(1, 1, n, lst, val);

	}

	ans = 1ll<<60;

	dfs(1, 1, n);

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

}
// Slower C++ solution:
#include<bits/stdc++.h>



#define oo ll(1e16)

#define maxn 200005

#define block 400



using namespace std;

typedef long long ll;



int n, q, a, b;

ll d[maxn];

ll L[maxn], R[maxn];



ll ret = 0;



ll get(int st, int en, int ok) {

  ll ret = oo;



  for (int i = st; i <= en;)

    if (i % block == 1 && i + block <= en + 1) {

      ret = min(ret, (ok ? L[(i - 1) / block] : R[(i - 1) / block]));

      i += block;

    }

    else {

      ret = min(ret, d[i] + (ok ? -i : i));

      ++i;

    }



  return ret;

}



int main(){

  ios_base::sync_with_stdio(0);



  cin >> n >> q >> a >> b;



  fill(d + 1, d + n + 1, oo);

  fill(L, L + n + 1, oo);

  fill(R, R + n + 1, oo);



  d[b] = 0;

  L[(b - 1) / block] = -b;

  R[(b - 1) / block] = b;



  while (q--) {

    int x;

    cin >> x;



    ll tem = min(get(1, x, 1) + x, get(x, n, 0) - x);



    d[a] = min(d[a], tem - abs(x - a));



    int bl = (a - 1) / block;



    L[bl] = oo;

    R[bl] = oo;



    for (int i = max(bl * block + 1, 1); i <= bl * block + block && i <= n; ++i) {

      L[bl] = min(L[bl], d[i] - i);

      R[bl] = min(R[bl], d[i] + i);

    }



    ret += abs(x - a);



   // for (int i = 1; i <= n; ++i) cerr << d[i] + ret << ' '; cerr << "\n\n";



    a = x;

  }



  ll ma = 0;

  for (int i = 1; i <= n; ++i)

    ma = min(ma, d[i]);



  cout << ma + ret;



  return 0;



}


// Faster C++ solution for the same problem (measured speedup: 5.188840499986176x):
#include <cstdio>

#include <algorithm>

using namespace std;

typedef long long LL;

const int mod = 1e9 + 7;

const int MAXN = 200050;

int n, q, A, lst;

LL tag, mn[MAXN<<2][2];

void build(int i, int l, int r) {

	if(l == r) {

		mn[i][0] = abs(l-A) - l;

		mn[i][1] = abs(l-A) + l;

		return;

	}

	int mid = (l + r) >> 1;

	build(i<<1, l, mid);

	build(i<<1|1, mid+1, r);

	mn[i][0] = min(mn[i<<1][0], mn[i<<1|1][0]);

	mn[i][1] = min(mn[i<<1][1], mn[i<<1|1][1]);

}

LL qry(int i, int l, int r, int x, int y, int o) {

	if(x <= l && r <= y) return mn[i][o];

	int mid = (l + r) >> 1; LL re = 1ll<<60;

	if(x <= mid) re = min(re, qry(i<<1, l, mid, x, y, o));

	if(y > mid) re = min(re, qry(i<<1|1, mid+1, r, x, y, o));

	return re;

}

void upd(int i, int l, int r, int x, LL val) {

	if(l == r) {

		if(val < mn[i][0]+l+tag) {

			mn[i][0] = val-tag-l;

			mn[i][1] = val-tag+l;

		}

		return;

	}

	int mid = (l + r) >> 1;

	if(x <= mid) upd(i<<1, l, mid, x, val);

	else upd(i<<1|1, mid+1, r, x, val);

	mn[i][0] = min(mn[i<<1][0], mn[i<<1|1][0]);

	mn[i][1] = min(mn[i<<1][1], mn[i<<1|1][1]);

}

LL ans;

void dfs(int i, int l, int r) {

	if(l == r) {

		ans = min(ans, mn[i][0]+l+tag);

		return;

	}

	int mid = (l + r) >> 1;

	dfs(i<<1, l, mid);

	dfs(i<<1|1, mid+1, r);

}

int main () {

	scanf("%d%d%d%d", &n, &q, &lst, &A);

	build(1, 1, n);

	for(int i = 1, x; i <= q; lst = x, ++i) {

		scanf("%d", &x);

		LL val = qry(1, 1, n, 1, x, 0) + tag + x;

		if(x < n) val = min(val, qry(1, 1, n, x+1, n, 1) + tag - x);

		tag += abs(x-lst);

		upd(1, 1, n, lst, val);

	}

	ans = 1ll<<60;

	dfs(1, 1, n);

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

}
// Slower C++ solution:
#include "bits/stdc++.h"



#define REP(i,num) for(int i=0;i<(num);++i)

#define LOOP(i) while(i--)

#define ALL(c) c.begin(),c.end()

#define PRINTALL(c) for(auto pitr=c.begin();pitr!=c.end();++pitr){cout<<*pitr;if(next(pitr,1)!=c.end())cout<<' ';}cout<<endl;

#define PAIRCOMP(c,comp) [](const pair<ll,ll>& lhs,const pair<ll,ll>& rhs){return lhs.c comp rhs.c;}



using namespace std;

using ll = long long;



constexpr ll atcoder_mod = 1e9+7;



template<typename T=int>

T in(){T x; cin >> x; return (x);}

template<typename T=int,typename C=vector<T>>

C vecin(int N){C x(N);REP(i,N){x[i]=in<T>();}return move(x);}



void vout(){cout << endl;}

template<typename Head,typename... Tail>

void vout(Head&& h,Tail&&... t){cout << ' ' << h;vout(forward<Tail>(t)...);}

void out(){cout << endl;}

template<typename Head,typename... Tail>

void out(Head&& h,Tail&&... t){cout << h;vout(forward<Tail>(t)...);}



int main(){

	cin.tie(0);

	ios::sync_with_stdio(false);

	cout<<fixed<<setprecision(10);

	

	string S=in<string>();

	int N=S.size();



	vector<vector<short>> dp(N+1,vector<short>(2019,0));

	dp[0][0] = 0;

	REP(i,N){

		int M=S[i]-'0';

		dp[i+1][M] += 1;

		REP(j,2019){

			int V=j*10+(S[i]-'0');

			M=V%2019;

			dp[i+1][M] += dp[i][j];

		}

	}

	

	int sum=0;

	REP(i,N+1){

		sum+=dp[i][0];

	}

	out(sum);

	return 0;

}


// Faster C++ solution for the same problem (measured speedup: 1.1193465857587481x):
#include "bits/stdc++.h"



#define REP(i,num) for(ll i=0;i<(num);++i)

#define LOOP(i) while(i--)

#define ALL(c) c.begin(),c.end()

#define PRINTALL(c) for(auto pitr=c.begin();pitr!=c.end();++pitr){cout<<*pitr;if(next(pitr,1)!=c.end())cout<<' ';}cout<<endl;

#define PAIRCOMP(c,comp) [](const pair<ll,ll>& lhs,const pair<ll,ll>& rhs){return lhs.c comp rhs.c;}



using namespace std;

using ll = long long;

using vll = vector<ll>;

using vvll = vector<vector<ll>>;



constexpr ll atcoder_mod = 1e9+7;



template<typename T=ll>

T in(){T x; cin >> x; return (x);}

template<typename T=ll,typename C=vector<T>>

C vecin(int N){C x(N);REP(i,N){x[i]=in<T>();}return move(x);}



void vout(){cout << endl;}

template<typename Head,typename... Tail>

void vout(Head&& h,Tail&&... t){cout << ' ' << h;vout(forward<Tail>(t)...);}

void out(){cout << endl;}

template<typename Head,typename... Tail>

void out(Head&& h,Tail&&... t){cout << h;vout(forward<Tail>(t)...);}



template<typename T>

bool chmax(T& a,T b){if(a<b){a=b;return true;}return false;}

template<typename T>

bool chmin(T& a,T b){if(a>b){a=b;return true;}return false;}



ll powermod(ll a,ll b,ll m){

	if(b==0){

		return 1LL;

	}

	if(b%2){

		return (a*powermod(a,b-1LL,m))%m;

	}

	return powermod((a*a)%m,b/2LL,m);

}



int main(){

	cin.tie(0);

	ios::sync_with_stdio(false);

	cout<<fixed<<setprecision(10);



	string S=in<string>();

	int N=S.size();

	vector<int> M(N+1,0);

	reverse(ALL(S));

	REP(i,N){

		int V=M[i];

		int X=(S[i]-'0')*powermod(10,i,2019);

		M[i+1] = (X+V)%2019;

	}

	map<int,ll> C;

	REP(i,N+1){

		C[M[i]]++;

	}

	ll A=0;

	for(auto& x:C){

		A += x.second*(x.second-1LL)/2LL;

	}

	out(A);

	return 0;

}
// Slower C++ solution:
#include <iostream>

#include <vector>

#include <algorithm>

#include <cmath>

#include <queue>

#include <string>

#include <map>

#include <set>

#include <stack>

#include <tuple>

#include <deque>

#include <numeric>

#include <bitset>

#include <iomanip>

#include <cassert>

#include <chrono>

#include <random>

#include <limits>

#include <iterator>

#include <functional>

#include <sstream>

#include <complex>

using namespace std;



typedef long long ll;

typedef uint64_t ull;

typedef pair<int, int> P;

constexpr double PI = 3.1415926535897932;   // acos(-1)

constexpr double EPS = 1e-9;

constexpr int INF = 1001001001;

constexpr int mod = 1000000007;

// constexpr int mod = 998244353;



#define chmax(x, y) x = max(x, y)

#define chmin(x, y) x = min(x, y)



constexpr int m = 2019;



int main(){

    ios::sync_with_stdio(false);

    cin.tie(nullptr);



    string s;

    cin >> s;

    int n = s.length();

    

    vector<ll> dp(m, 0);

    dp[0] = 1;

    ll ans = 0;

    for(int i = 0; i < n; ++i){

        int num = s[i] - '0';

        vector<ll> nextdp(m, 0);

        for(int j = 0; j < m; ++j){

            if(!dp[j])  continue;

            int nj = (j * 10 + num) % m;

            nextdp[nj] += dp[j];

        }

        dp = nextdp;

        ans += dp[0]++;

    }

    cout << ans << endl;

}

// Faster C++ solution for the same problem (measured speedup: 1.1838683039771294x):
#include <iostream>

#include <vector>

#include <algorithm>

#include <cmath>

#include <queue>

#include <string>

#include <map>

#include <set>

#include <stack>

#include <tuple>

#include <deque>

#include <numeric>

#include <bitset>

#include <iomanip>

#include <cassert>

#include <chrono>

#include <random>

#include <limits>

#include <iterator>

#include <functional>

#include <sstream>

#include <complex>

using namespace std;



typedef long long ll;

typedef uint64_t ull;

typedef pair<int, int> P;

constexpr double PI = 3.1415926535897932;   // acos(-1)

constexpr double EPS = 1e-9;

constexpr int INF = 1001001001;

constexpr int mod = 1000000007;

// constexpr int mod = 998244353;



#define chmax(x, y) x = max(x, y)

#define chmin(x, y) x = min(x, y)



constexpr int m = 2019;



int main(){

    ios::sync_with_stdio(false);

    cin.tie(nullptr);



    string s;

    cin >> s;

    reverse(s.begin(), s.end());

    int n = s.length();

    

    vector<int> sum(n + 1);

    sum[0] = 0;

    int mul = 1;

    for(int i = 0; i < n; ++i){

        int num = s[i] - '0';

        sum[i + 1] = (sum[i] + num * mul) % m;

        mul *= 10;

        if(mul > m) mul %= m;

    }

    map<int, int> mp;

    for(int i = 0; i <= n; ++i) ++mp[sum[i]];

    ll ans = 0;

    for(auto it : mp)   ans += (ll)it.second * (it.second - 1) / 2;

    cout << ans << endl;

}
// Slower C++ solution:
#include <iostream>

#include <vector>

#include <algorithm>

#include <cmath>

#include <queue>

#include <string>

#include <map>

#include <set>

#include <stack>

#include <tuple>

#include <deque>

#include <numeric>

#include <bitset>

#include <iomanip>

#include <cassert>

#include <chrono>

#include <random>

#include <limits>

#include <iterator>

#include <functional>

#include <sstream>

#include <complex>

using namespace std;



typedef long long ll;

typedef uint64_t ull;

typedef pair<int, int> P;

constexpr double PI = 3.1415926535897932;   // acos(-1)

constexpr double EPS = 1e-9;

constexpr int INF = 1001001001;

constexpr int mod = 1000000007;

// constexpr int mod = 998244353;



#define chmax(x, y) x = max(x, y)

#define chmin(x, y) x = min(x, y)



constexpr int m = 2019;



int main(){

    ios::sync_with_stdio(false);

    cin.tie(nullptr);



    string s;

    cin >> s;

    int n = s.length();

    

    vector<ll> dp(m, 0);

    dp[0] = 1;

    ll ans = 0;

    for(int i = 0; i < n; ++i){

        int num = s[i] - '0';

        vector<ll> nextdp(m, 0);

        for(int j = 0; j < m; ++j){

            if(!dp[j])  continue;

            int nj = (j * 10 + num) % m;

            nextdp[nj] += dp[j];

        }

        dp = nextdp;

        ans += dp[0]++;

    }

    cout << ans << endl;

}

// Faster C++ solution for the same problem (measured speedup: 1.1870132677864604x):
#include <iostream>

#include <vector>

#include <algorithm>

#include <cmath>

#include <queue>

#include <string>

#include <map>

#include <set>

#include <stack>

#include <tuple>

#include <deque>

#include <numeric>

#include <bitset>

#include <iomanip>

#include <cassert>

#include <chrono>

#include <random>

#include <limits>

#include <iterator>

#include <functional>

#include <sstream>

#include <complex>

using namespace std;



typedef long long ll;

typedef uint64_t ull;

typedef pair<int, int> P;

constexpr double EPS = 1e-9;

constexpr int INF = 1001001001;

constexpr int mod = 1000000007;

// constexpr int mod = 998244353;



template<class T>

inline bool chmax(T& x, T y){

    if(x < y){

        x = y;

        return true;

    }

    return false;

}

template<class T>

inline bool chmin(T& x, T y){

    if(x > y){

        x = y;

        return true;

    }

    return false;

}



int main(){

    ios::sync_with_stdio(false);

    cin.tie(nullptr);



    string s;

    cin >> s;

    int n = s.length();

    reverse(s.begin(), s.end());

    vector<int> S(n + 1);

    S[0] = 0;

    int mul = 1;

    constexpr int m = 2019;

    for(int i = 0; i < n; ++i){

        int x = s[i] - '0';

        x = x * mul % m;

        mul = mul * 10 % m;

        S[i + 1] = (S[i] + x) % m;

    }

    vector<int> c(m, 0);

    ll ans = 0;

    for(int i = 0; i <= n; ++i){

        ans += c[S[i]]++;

    }

    cout << ans << endl;

}
// Slower C++ solution:
#include <bits/stdc++.h>



using namespace std;



const int mxn = 2e5;



char s[mxn + 11];

int cnt[mxn + 11];



int main(){

	scanf("%s", s);

	int slen = strlen(s);

	int carry = 1;

	memset(cnt, 0, sizeof(cnt));

	cnt[0] = 1;

	int cur = 0;

	for (int i = slen - 1; i >= 0; i--){

		int digit = s[i] - '0';

		cur += digit * carry;

		cur %= 2019;

		cnt[cur]++;

		carry = carry * 10 % 2019;

	}

	int ans = 0;

	for (int i = 0; i < 2019; i++){

		ans += (cnt[i] * (cnt[i] - 1) ) >> 1;

	}

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

	return 0;

}


// Faster C++ solution for the same problem (measured speedup: 1.7614445874516733x):
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

int main()

{

    string s;

    cin>>s;

    int len=s.size();

    ll ans=0,p=1,now=0,cnt[2020]={0};

    cnt[0]=1;

    for(int i=len;i--;)

    {

        now=(now+ll(s[i]-'0')*p)%2019;

        ans+=cnt[now]++;

        p=p*10%2019;

    }

    cout<<ans<<endl;

    return 0;

}
// Slower C++ solution:
#include <bits/stdc++.h>



using namespace std;



const int mxn = 2e5;



char s[mxn + 11];

int cnt[mxn + 11];



int main(){

	scanf("%s", s);

	int slen = strlen(s);

	int carry = 1;

	memset(cnt, 0, sizeof(cnt));

	cnt[0] = 1;

	int cur = 0;

	for (int i = slen - 1; i >= 0; i--){

		int digit = s[i] - '0';

		cur += digit * carry;

		cur %= 2019;

		cnt[cur]++;

		carry = carry * 10 % 2019;

	}

	int ans = 0;

	for (int i = 0; i < 2019; i++){

		ans += (cnt[i] * (cnt[i] - 1) ) >> 1;

	}

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

	return 0;

}


// Faster C++ solution for the same problem (measured speedup: 1.7966679469567948x):
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int N = 2e5 + 5, M = 3e3 + 5;

char s[N];

int cnt[M];

int main()

{

    int k = 1, sum = 0;

    scanf("%s", s);

    int len = strlen(s);

    for (int i = len - 1; ~i; --i)

    {

        sum = (sum + k * (s[i] - '0')) % 2019;

        ++cnt[sum];

        k = k * 10 % 2019;

    }

    ll ans = 0;

    for (int i = 0; i < 2019; ++i)

    {

        if (!i)

            ans += cnt[i];

        ans += cnt[i] * (cnt[i] - 1ll) / 2;

    }

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

    return 0;

}
// Slower C++ solution:
#include<bits/stdc++.h>

#define pi acos(-1)

#define ll long long

#define pii pair<ll,ll>

#define debug(a) cout<<a<<'\n'

#define maxn 100009 /// Still trying to be normal

#define MOD 1000000007

#define F first

#define S second

#define rep(i, a, b) for(ll i = a; i < (b); ++i)

#define per(i, b, a) for(ll i = b-1; i>=a ; i--)

#define trav(a, x) for(auto& a : x)

#define allin(a , x) for(auto a : x)

#define all(x) begin(x), end(x)

#define sz(x) (ll)(x).size()

using namespace std;

const ll INF = 1e17 + 9;

int main(){

    ios::sync_with_stdio(false);

    cin.tie(0);

    string s;

    cin>>s;

    ll mod[2019];

    ll mod2[2019];

    memset(mod,0,sizeof mod);

    memset(mod2,0,sizeof mod2);

    mod[0]=1;

    ll num1=0,num2=0;

    ll ans=0;

    rep(i,0,sz(s)){

        rep(j,0,2019){

            int ant=mod[j];

            mod2[j*10%2019]+=ant;

        }

        rep(j,0,2019){

            mod[j]=mod2[j];

            mod2[j]=0;

        }

        num1=num1*10%2019;

        num1=(num1+(s[i]-'0'))%2019;

        // cout<<num1<<endl;

        ans+=mod[num1];

        mod[num1]++;

    }

    cout<<ans<<'\n';

    return 0;   

}

// Faster C++ solution for the same problem (measured speedup: 1.1933758278453135x):
#include<bits/stdc++.h>

#define pi acos(-1)

#define ll long long

#define pii pair<ll,ll>

#define debug(a) cout<<a<<'\n'

#define maxn 100009 /// Still trying to be normal

#define MOD 1000000007

#define F first

#define S second

#define rep(i, a, b) for(ll i = a; i < (b); ++i)

#define per(i, b, a) for(ll i = b-1; i>=a ; i--)

#define trav(a, x) for(auto& a : x)

#define allin(a , x) for(auto a : x)

#define all(x) begin(x), end(x)

#define sz(x) (ll)(x).size()

using namespace std;

const ll INF = 1e17 + 9;

int main(){

    ios::sync_with_stdio(false);

    cin.tie(0);

    string s;

    cin>>s;

    ll mod[2019];

    memset(mod,0,sizeof mod);

    mod[0]=1;

    ll ant=0;

    ll ans=0;

    ll n = sz(s);

    ll base = 1;

    per(i,n,0){

        ll modact = (ant+(s[i]-'0')*base)%2019;

        ant=modact;

        // cout<<modact<<" "<<mod[modact]<<endl;

        ans+=mod[modact];

        base*=10;

        base%=2019;

        mod[modact]++;

    }

    cout<<ans<<'\n';

    return 0;   

}
// Slower C++ solution:
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

typedef pair<int,int>P;

const double eps = 1e-8;

const int NINF = 0xc0c0c0c0;

const int INF  = 0x3f3f3f3f;

const ll  mod  = 2019;

const ll  maxn = 1e6 + 5;

const int N = 2e5 + 5;



char s[N];

int a[N],pre[N],suf[N],n;



ll qpow(ll a,ll b){

	ll res=1;

	while(b>0){

		if(b&1) res=res*a%mod;

		a=a*a%mod;

		b>>=1;

	}

	return res;

}



map<ll,ll>M;



int main(){

	ios::sync_with_stdio(false);

	cin.tie(0);

	cin>>s+1;

	int n=strlen(s+1);

	for(int i=1;i<=n;i++){

		a[i]=s[i]-'0';

	}

	int cnt=0;

	// for(int i=1;i<=n;i++){

	// 	pre[i]=(pre[i-1]*10+a[i])%mod;

	// 	if(pre[i]==0) cnt++;

	// }

	for(int i=n;i>=1;i--){

		suf[i]=(suf[i+1]+a[i]*qpow(10,n-i+1))%mod;

		M[suf[i]]++;

	}

	// for(int i=1;i<=n;i++){

	// 	cout<<pre[i]<<"\n";

	// }

	M[0]++;

	for(int i=0;i<2019;i++){

		if(M[i]>=2) cnt+=M[i]*(M[i]-1)/2;

	}

	// cout<<"\n\n\n";

	// for(int i=1;i<=n;i++){

		// cout<<suf[i]<<'\n';

	// }

	// for(int i=1;i)

	// for(int i=1;i<=n;i++){

	// 	if(pre[i]==0) 

	// }

	// cout<<(1+cnt)*cnt/2<<'\n';

	cout<<cnt<<'\n';

	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 1.3157762379522087x):
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

typedef pair<int,int>P;

const double eps = 1e-8;

const int NINF = 0xc0c0c0c0;

const int INF  = 0x3f3f3f3f;

const ll  mod  = 2019;

const ll  maxn = 1e6 + 5;

const int N = 2e5 + 5;



char s[N];

int a[N],suf[N],n,M[2020];



int main(){

	ios::sync_with_stdio(false);

	cin.tie(0);

	cin>>s+1;

	int n=strlen(s+1);

	int cnt=0;int base=1;

	M[0]++;

	for(int i=n;i>=1;i--){

		a[i]=s[i]-'0';

		suf[i]=(suf[i+1]+a[i]*base)%mod;

		cnt+=M[suf[i]];

		M[suf[i]]++;

		base=base*10%mod;

	}

	cout<<cnt<<'\n';

	return 0;

}
// Slower C++ solution:
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

typedef pair<int,int>P;

const double eps = 1e-8;

const int NINF = 0xc0c0c0c0;

const int INF  = 0x3f3f3f3f;

const ll  mod  = 2019;

const ll  maxn = 1e6 + 5;

const int N = 2e5 + 5;



char s[N];

int a[N],suf[N],n;

map<ll,ll>M;



int main(){

	ios::sync_with_stdio(false);

	cin.tie(0);

	cin>>s+1;

	int n=strlen(s+1);

	for(int i=1;i<=n;i++){

		a[i]=s[i]-'0';

	}

	int cnt=0;int base=1;

	M[0]++;

	for(int i=n;i>=1;i--){

		suf[i]=(suf[i+1]+a[i]*base)%mod;

		M[suf[i]]++;

		base=base*10%mod;

	}

	for(int i=0;i<2019;i++){

		if(M[i]>=2) cnt+=M[i]*(M[i]-1)/2;

	}

	cout<<cnt<<'\n';

	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 1.3304579586672343x):
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

typedef pair<int,int>P;

const double eps = 1e-8;

const int NINF = 0xc0c0c0c0;

const int INF  = 0x3f3f3f3f;

const ll  mod  = 2019;

const ll  maxn = 1e6 + 5;

const int N = 2e5 + 5;



char s[N];

int a[N],suf[N],n,M[2020];



int main(){

	ios::sync_with_stdio(false);

	cin.tie(0);

	cin>>s+1;

	int n=strlen(s+1);

	int cnt=0;int base=1;

	M[0]++;

	for(int i=n;i>=1;i--){

		a[i]=s[i]-'0';

		suf[i]=(suf[i+1]+a[i]*base)%mod;

		cnt+=M[suf[i]];

		M[suf[i]]++;

		base=base*10%mod;

	}

	cout<<cnt<<'\n';

	return 0;

}
// Slower C++ solution:
#include <stdio.h>

using namespace std;

typedef long long ll;



int main(void) {

  ll i, j, n = 2019, now[n], tmp[n], ans = 0;

  char s[200010];

  scanf("%s", s);

  for(i = 0; i < n; ++i) now[i] = 0;

  now[0] = 1;

  for(i = 0; s[i]; ++i) {

    for(j = 0; j < n; ++j) tmp[j] = 0;

    for(j = 0; j < n; ++j) if(now[j]) tmp[(10 * j + s[i] - '0') % n] += now[j];

    ans += tmp[0];

    for(j = 0; j < n; ++j) now[j] = tmp[j];

    now[0]++;

  }

  printf("%lld", ans);

  return 0;

}

// Faster C++ solution for the same problem (measured speedup: 1.8052495382266094x):
#include <stdio.h>

using namespace std;

typedef long long ll;



int main(void) {

  ll i, j, n = 2019, m, cnt[n], ans = 0, now = 0;

  char s[200010];

  scanf("%s", s);

  for(i = 0; i < n; ++i) cnt[i] = 0;

  cnt[0] = 1;

  for(i = 0; s[i]; ++i);

  m = i;

  ll p[m];

  p[0] = 1;

  for(i = 1; i < m; ++i) p[i] = p[i - 1] * 10, p[i] %= n;

  for(i = m - 1; i >= 0; --i) {

    now += p[m - 1 - i] * (s[i] - '0'), now %= n;

    cnt[now]++;

  }

  for(i = 0; i < n; ++i) ans += cnt[i] * (cnt[i] - 1) / 2;

  printf("%lld", ans);

  return 0;

}