#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#include <cmath>
#include <utility>
#include <unordered_map>
#include <unordered_set>
#include <map>
#include <cstdint>
#include <iomanip> // Required for std::fixed and std::setprecision
#include<limits>
#include <climits>
using namespace std;
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
// #define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
#define int long long
// #define setbits(x) __builtin_popcountll((int)x)
#define result(ans) cout<<(ans?"YES":"NO")<<endl;
#define debug cout<<"Chal rha hai be "<<endl;
#define vi vector<int>
#define vs vector<str>
#define vc vector<char>
#define MOD 1000000007
#define vvi vector<vector<int> >
#define pii pair<int,int>
#define vpi vector<pair<int,int> >
#define ff first
#define ss second
#define mii map<int,int>
#define printv(v) for(int i=0;i<v.size();i++) cout<<v[i]<<" \n"[i==v.size()-1];
#define scanv(v) for(auto &i:v) {cin>>i;}
#define pb push_back
// #define scantree(v) for(int i=0;i<v.size()-1;i++){int x,y;cin>>x>>y;x--;y--;v[x].pb(y);v[y].pb(x);}
#define all(v) v.begin(),v.end()
#define loop(a,b,c) for(int i=a;i<b;i+=c)
#define MAX 10000
#define max3(a,b,c) max(a,max(b,c))
#define max4(a,b,c,d) max(a,max(b,max(c,d)))
#define mp make_pair
vector<int> prefixSum(const vector<int>& arr) {
int n = arr.size();
vector<int> prefixSums(n);
if (n == 0) return prefixSums;
prefixSums[0] = arr[0];
for (int i = 1; i < n; i++) {
prefixSums[i] = prefixSums[i - 1] + arr[i];
}
return prefixSums;
}
// instead of log2
int log(long long x)
{
return 64 - __builtin_clzll(x) - 1;
}
int maxv(vi v){
int ans=INT_MIN;
for(int i=0;i<v.size();i++){
ans=max(ans,v[i]);
}
return ans;
}
int minv(vi v){
int ans=INT_MAX;
for(int i=0;i<v.size();i++){
ans=min(ans,v[i]);
}
return ans;
}
int fact(int n)
{
if(n==0) return 1;
int res = 1;
for (int i = 2; i <= n; i++)
res = res * i;
return res;
}
int ncr(int n, int r){return fact(n) / (fact(r) * fact(n - r));}
int npr(int n, int r){return fact(n) / fact(n - r);}
int isSorted(vector<int>v){
for(int i=0; i<v.size()-1; i++){
if (v[i]>v[i+1]) return 0;
}
return 1;
}
int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}
int isSubstr(string S1, string S2){
int M = S1.length();
int N = S2.length();
for (int i = 0; i <= N - M; i++) {
int j;
for (j = 0; j < M; j++) {
if (S2[i + j] != S1[j]) {
break;
}
}
if (j == M) {
return i;
}
}
return -1;
}
int freqi(vector<int>a,int b,int c){
int count =0;
for(int i=c+1; i<a.size();i++){
if(a[i]==b){count++;}
}
if(count){return count;}
else {return -1;}
}
int freqs(string a,char b){
int count =0;
for(int i=0; i<a.length();i++){
if(a[i]==b){count++;}}
if(count){return count;}
else {return -1;}
}
int lcm(int a,int b){
return (a*b)/gcd(a,b);
}
bool sortcol(const vector<int>& v1, const vector<int>& v2)
{
return v1[1] < v2[1];
}
bool c(pair<int,int>p1 , pair<int,int>p2){
if(p1.first == p2.first){
return p1.second < p2.second;
}
return p1.first > p2.first;
}
bool isPrime(int n) {
if (n <= 1) return false;
if (n <= 3) return true;
if (n % 2 == 0 || n % 3 == 0) return false;
for (int i = 5; i * i <= n; i += 6) {
if (n % i == 0 || n % (i + 2) == 0)
return false;
}
return true;
}
pair<int ,int> smallestPrimeGreaterThan(int num){
int candidate = num;
int count = 0;
while (!isPrime(candidate)){candidate++;count++;}
pair<int ,int > x;
x.first = candidate;
x.second = count;
return x;}
vector<int> getFactors(int n) {
vector<int> factors;
// Loop up to the square root of n
for (int i = 2; i <= sqrt(n); ++i) {
if (n % i == 0) {
factors.push_back(i); // Add the factor
if (i != n / i) { // Avoid adding the square root twice
factors.push_back(n / i);
}
}
}
// factors.pb(n);
// Sort factors in ascending order
// sort(factors.begin(), factors.end());
return factors;
}
vector<bool> sieveOfEratosthenes(int n) {
// Create a boolean vector initialized to true
vector<bool> is_prime(n + 1, true);
// Mark 0 and 1 as non-prime
if (n >= 0) is_prime[0] = false;
if (n >= 1) is_prime[1] = false;
// Start the Sieve of Eratosthenes algorithm
for (int i = 2; i * i <= n; i++) {
if (is_prime[i]) {
for (int j = i * i; j <= n; j += i) {
is_prime[j] = false;
}
}
}
return is_prime;
}
bool vp_desc(const pair<int, int>& p1, const pair<int, int>& p2) {
return p1.second > p2.second;
}
int findSubstring(const string& mainStr, const string& subStr) {
size_t pos = mainStr.find(subStr);
if (pos != string::npos) {return pos;}
else{return -1; }
}
int powerof2(int n) {
return __builtin_ctz(n);
}
vector<pair<int, int> > getFrequency(const vector<int>& nums) {
unordered_map<int, int> freqMap;
for (int num : nums) {
freqMap[num]++;
}
vector<pair<int, int> > freqVector;
for (const auto& entry : freqMap) {
freqVector.emplace_back(entry.first, entry.second);
}
sort(freqVector.begin(), freqVector.end());
return freqVector;
}
int findGCD(const vector<int>& nums) {
int gcd1 = nums[0];
for (size_t i = 1; i < nums.size(); ++i) {
gcd1 = gcd(gcd1, nums[i]);
if (gcd1 == 1) {
return 1;
}
}
return gcd1;
}
bool compareBySecond(const pair<int, int>& a, const pair<int, int>& b) {
return a.second < b.second; // Ascending order by second element
}
int fact_modulo(int n, int mod) {
int result = 1;
for (int i = 1; i <= n; i++) {
result = (result * i) % mod;
}
return result;
}
int sumv(vi v){
int sum=0;
for(auto e:v){
sum+=e;
}
return sum;
}
vector<pair<int, int> > PrimeFactorsfreq(int n) {
vector<pair<int, int> > primeFactors;
int count = 0;
while (n % 2 == 0) {
count++;
n /= 2;
}
if (count > 0 && 2 != n) {
primeFactors.emplace_back(2, count);
}
for (int i = 3; i * i <= n; i += 2) {
count = 0;
while (n % i == 0) {
count++;
n /= i;
}
if (count > 0 && i != n) {
primeFactors.emplace_back(i, count);
}
}
if (n > 2) {
primeFactors.emplace_back(n, 1);
}
return primeFactors;
}
vi dp;
int ans = 0;
void count(string s ,int n){
//
if(n==0) {ans++;return;};
if(n<0){return;}
if(s[n-1]!='0') {count(s,n-1);}
// if(((s[n-3]-'0')*10 + (s[n-2]-'0'))<=26 && n>=3){
// count(s,n-3);
// // cout<<((s[n-3]-'0')*10 + (s[n-2]-'0'))<<endl;
// }
if(((s[n-2]-'0')*10 + (s[n-1]-'0'))<=26 && n>=2 && s[n-2]!='0'){
count(s,n-2);
// cout<<((s[n-3]-'0')*10 + (s[n-2]-'0'))<<endl;
}
}
void solve(){
string s;
cin>>s;
// int ans = 0;
// if(s.length()==0){cout<<endl;return;}
count(s,s.length());
cout<<ans<<endl;
}
int32_t main(){
// #ifndef ONLINE_JUDGE
// freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
// #endif
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int t=1;
// cin >> t;
while (t--){
solve();
}
return 0;
}