//#pragma GCC target ("avx2") //#pragma GCC optimize ("O3") //#pragma GCC optimize ("unroll-loops") //#pragma GCC optimize ("O2") //#pragma GCC optimize ("Os") #include //Kam using namespace std; #define TASK "recover" #define fio ios_base::sync_with_stdio(0);cin.tie(0); #define fi first #define se second #define vi vector #define pll pair #define vt vector #define pb push_back #define er erase #define lcm(a,b) a/__gcd(a,b)*b #define bg begin() #define ed end() #define endl '\n' #define all(x) (x).begin(), (x).end() #define sz(x) int((x).size()) #define FOR(i,a,b) for (int i = (a); i <= (b); ++i) #define FORR(i,a,b) for (int i = (a); i >= (b); --i) #define MOD 2017 #define MOD1 100000007 #define MOD2 10000019 #define ll long long #define ull unsigned long long #define ld long double const int maxn = 5e3 + 1; const int base = 11; string s; int n; int f[maxn]{1}; int l[maxn]{1}; ll hs[maxn]; int m[maxn]{1}; bool check2(string &a, string &b) { if(a.length() != b.length()) return a.length() > b.length(); return a > b; } void sub12() { FOR(i, 0, n) { string tar = s.substr(l[i], (i - l[i] + 1)); if(i == n || s[i + 1] != '0') FOR(j, i + 1, n) { string tmp = s.substr(i + 1, j - i); if(check2(tmp, tar)) { l[j] = i + 1; f[j] = (f[j] + f[i]) % MOD; } } } // FOR(i, 1, n) cout << f[i] << ' '; cout << f[n]; } void build() { FOR(i, 1, n) { m[i] = (m[i - 1] * base) % MOD; hs[i] = (hs[i - 1] * base + (s[i] - '0' + 1)) % MOD; } } ll geths(int l, int r) { ll tmp = (hs[r] - hs[l - 1] * m[r - l + 1]) % MOD; return (tmp < 0 ? tmp + MOD : tmp); } bool check(int l1, int len1, int l2, int len2) { if(len1 != len2) return len2 > len1; if(len1 == 1) return s[l2] > s[l1]; int ln = 0, r = len1; while(ln < r) { int mid = (ln + r)/2; ll tmp = geths(l1, l1 + mid); ll tmp1 = geths(l2, l2 + mid); if(tmp == tmp1) r = mid - 1; else ln = mid + 1; } if(r == len1)return 0; return s[l2 + r] > s[l1 + r]; } void subac() { build(); FOR(i, 0, n) { if(i == n || s[i + 1] != '0') FOR(j, i + 1, n) { if(check(l[i], i - l[i] + 1, i + 1, j - i)) { l[j] = i + 1; f[j] = (f[j] + f[i]) % MOD; } } // FOR(i, 1, n) cout << f[i] <<' '; // cout << endl; } cout << f[n]; } signed main() { fio if(fopen(TASK".inp", "r")) { freopen(TASK".inp", "r", stdin); freopen(TASK".out", "w", stdout); } cin >> s; n = s.length(); s = "0" + s; if(n <= 20) sub12(); else subac(); return 0; }