#include <bits/stdc++.h>   using namespace std;   using ll = long long;   using ld = long double;   using P = pair<ll, ll>;   constexpr ll inf = 1000000000;   constexpr ll mod = 1000000007;   constexpr long double eps = 1e-6;   template <typename T1, typename T2>   ostream& operator<<(ostream& os, pair<T1, T2> p) {     os << to_string(p.first) <<     << to_string(p.second);     return os;   }   template <typename T>   ostream& operator<<(ostream& os, vector<T>& v) {     for (ll i = (0); i < (ll)(v.size()); i++) {       if (i) os <<    ;       os << v[i];     }     return os;   }   struct modint {     ll n;       public:     modint(const ll n = 0) : n((n % mod + mod) % mod) {}     static modint pow(modint a, int m) {       modint r = 1;       while (m > 0) {         if (m & 1) {           r *= a;         }         a = (a * a);         m /= 2;       }       return r;     }     modint& operator++() {       *this += 1;       return *this;     }     modint& operator--() {       *this -= 1;       return *this;     }     modint operator++(int) {       modint ret = *this;       *this += 1;       return ret;     }     modint operator--(int) {       modint ret = *this;       *this -= 1;       return ret;     }     modint operator~() const { return (this->pow(n, mod - 2)); }     friend bool operator==(const modint& lhs, const modint& rhs) {       return lhs.n == rhs.n;     }     friend bool operator<(const modint& lhs, const modint& rhs) {       return lhs.n < rhs.n;     }     friend bool operator>(const modint& lhs, const modint& rhs) {       return lhs.n > rhs.n;     }     friend modint& operator+=(modint& lhs, const modint& rhs) {       lhs.n += rhs.n;       if (lhs.n >= mod) lhs.n -= mod;       return lhs;     }     friend modint& operator-=(modint& lhs, const modint& rhs) {       lhs.n -= rhs.n;       if (lhs.n < 0) lhs.n += mod;       return lhs;     }     friend modint& operator*=(modint& lhs, const modint& rhs) {       lhs.n = (lhs.n * rhs.n) % mod;       return lhs;     }     friend modint& operator/=(modint& lhs, const modint& rhs) {       lhs.n = (lhs.n * (~rhs).n) % mod;       return lhs;     }     friend modint operator+(const modint& lhs, const modint& rhs) {       return modint(lhs.n + rhs.n);     }     friend modint operator-(const modint& lhs, const modint& rhs) {       return modint(lhs.n - rhs.n);     }     friend modint operator*(const modint& lhs, const modint& rhs) {       return modint(lhs.n * rhs.n);     }     friend modint operator/(const modint& lhs, const modint& rhs) {       return modint(lhs.n * (~rhs).n);     }   };   istream& operator>>(istream& is, modint m) {     is >> m.n;     return is;   }   ostream& operator<<(ostream& os, modint m) {     os << m.n;     return os;   }   long long extgcd(long long a, long long b, long long& x, long long& y) {     long long d = a;     if (b != 0) {       d = extgcd(b, a % b, y, x);       y -= (a / b) * x;     } else {       x = 1;       y = 0;     }     return d;   }   long long mod_inverse(long long a, long long m) {     long long x, y;     if (extgcd(a, m, x, y) == 1)       return (m + x % m) % m;     else       return -1;   }   vector<long long> fact(1010101 + 1, inf);   long long mod_fact(long long n, long long& e) {     if (fact[0] == inf) {       fact[0] = 1;       if (1010101 != 0) fact[1] = 1;       for (ll i = 2; i <= 1010101; ++i) {         fact[i] = (fact[i - 1] * i) % mod;       }     }     e = 0;     if (n == 0) return 1;     long long res = mod_fact(n / mod, e);     e += n / mod;     if ((n / mod) % 2 != 0) return (res * (mod - fact[n % mod])) % mod;     return (res * fact[n % mod]) % mod;   }   long long mod_comb(long long n, long long k) {     if (n < 0 || k < 0 || n < k) return 0;     long long e1, e2, e3;     long long a1 = mod_fact(n, e1), a2 = mod_fact(k, e2),               a3 = mod_fact(n - k, e3);     if (e1 > e2 + e3) return 0;     return (a1 * mod_inverse((a2 * a3) % mod, mod)) % mod;   }   using mi = modint;   mi mod_pow(mi a, ll n) {     mi ret = 1;     mi tmp = a;     while (n > 0) {       if (n % 2) ret *= tmp;       tmp = tmp * tmp;       n /= 2;     }     return ret;   }   ll gcd(ll a, ll b) {     if (b == 0) return a;     return gcd(b, a % b);   }   struct SuffixArray {     vector<int> SA;     const string s;     SuffixArray(const string& str) : s(str) {       SA.resize(s.size());       iota(begin(SA), end(SA), 0);       sort(begin(SA), end(SA),            [&](int a, int b) { return s[a] == s[b] ? a > b : s[a] < s[b]; });       vector<int> classes(s.size()), c(s.begin(), s.end()), cnt(s.size());       for (int len = 1; len < s.size(); len <<= 1) {         for (int i = 0; i < s.size(); i++) {           if (i > 0 && c[SA[i - 1]] == c[SA[i]] && SA[i - 1] + len < s.size() &&               c[SA[i - 1] + len / 2] == c[SA[i] + len / 2]) {             classes[SA[i]] = classes[SA[i - 1]];           } else {             classes[SA[i]] = i;           }         }         iota(begin(cnt), end(cnt), 0);         copy(begin(SA), end(SA), begin(c));         for (int i = 0; i < s.size(); i++) {           int s1 = c[i] - len;           if (s1 >= 0) SA[cnt[classes[s1]]++] = s1;         }         classes.swap(c);       }     }     int operator[](int k) const { return SA[k]; }     size_t size() const { return s.size(); }     bool lt_substr(const string& t, int si = 0, int ti = 0) {       int sn = (int)s.size(), tn = (int)t.size();       while (si < sn && ti < tn) {         if (s[si] < t[ti]) return true;         if (s[si] > t[ti]) return false;         ++si, ++ti;       }       return si >= sn && ti < tn;     }     int lower_bound(const string& t) {       int low = -1, high = (int)SA.size();       while (high - low > 1) {         int mid = (low + high) / 2;         if (lt_substr(t, SA[mid]))           low = mid;         else           high = mid;       }       return high;     }     pair<int, int> lower_upper_bound(string& t) {       int idx = lower_bound(t);       int low = idx - 1, high = (int)SA.size();       t.back()++;       while (high - low > 1) {         int mid = (low + high) / 2;         if (lt_substr(t, SA[mid]))           low = mid;         else           high = mid;       }       t.back()--;       return {idx, high};     }     void output() {       for (int i = 0; i < size(); i++) {         cout << i <<  :   << s.substr(SA[i]) << endl;       }     }   };   struct LongestCommonPrefixArray {     const SuffixArray& SA;     vector<int> LCP, rank;     LongestCommonPrefixArray(const SuffixArray& SA) : SA(SA), LCP(SA.size()) {       rank.resize(SA.size());       for (int i = 0; i < SA.size(); i++) {         rank[SA[i]] = i;       }       for (int i = 0, h = 0; i < SA.size(); i++) {         if (rank[i] + 1 < SA.size()) {           for (int j = SA[rank[i] + 1];                max(i, j) + h < SA.size() && SA.s[i + h] == SA.s[j + h]; ++h)             ;           LCP[rank[i] + 1] = h;           if (h > 0) --h;         }       }     }     int operator[](int k) const { return LCP[k]; }     size_t size() const { return LCP.size(); }     void output() {       for (int i = 0; i < size(); i++) {         cout << i <<  :   << LCP[i] <<     << SA.s.substr(SA[i]) << endl;       }     }   };   int main() {     cin.tie(0);     ios::sync_with_stdio(false);     string x;     cin >> x;     int n = (int)x.size();     SuffixArray sa(x);     LongestCommonPrefixArray lcpa(sa);     vector<vector<int>> pd(n, vector<int>(n));     vector<int> rev(n);     for (ll i = (0); i < (ll)(n); i++) rev[sa[i]] = i;     for (ll i = (0); i < (ll)(n - 1); i++) {       int a = sa[i];       int mn = lcpa[i + 1];       for (int j = i + 1; j < n; j++) {         mn = min(mn, lcpa[j]);         int b = sa[j];         pd[a][b] = pd[b][a] = mn;       }     }     vector<vector<pair<int, int>>> dp(         n, vector<pair<int, int>>(n, make_pair(0, inf)));     vector<vector<pair<int, int>>> acm(         n, vector<pair<int, int>>(n, make_pair(0, inf)));     for (ll i = (0); i < (ll)(n); i++) {       for (ll j = (0); j < (ll)(n); j++) {         if (i + 1 < j + 1) continue;         if (x[i - j] ==  0 ) continue;         if (i + 1 == j + 1) {           dp[i][j].first = 1;           dp[i][j].second = 1;         } else {           if (j) {             dp[i][j].first = acm[i - j - 1][j - 1].first;             dp[i][j].second = acm[i - j - 1][j - 1].second + 1;           }           if (i - j - 1 - j < 0) continue;           if (pd[i - j - 1 - j][i - j] >= j + 1) {             dp[i][j].first += dp[i - j - 1][j].first;             dp[i][j].first %= mod;             dp[i][j].second = min(dp[i][j].second, dp[i - j - 1][j].second + 1);           } else if (rev[i - j - 1 - j] < rev[i - j]) {             dp[i][j].first += dp[i - j - 1][j].first;             dp[i][j].first %= mod;             dp[i][j].second = min(dp[i][j].second, dp[i - j - 1][j].second + 1);           }         }       }       acm[i][0] = dp[i][0];       for (ll j = (1); j < (ll)(n); j++) {         acm[i][j].first = acm[i][j - 1].first + dp[i][j].first;         acm[i][j].first %= mod;         acm[i][j].second = min(acm[i][j - 1].second, dp[i][j].second);       }     }     mi ans1 = acm[n - 1][n - 1].first;     ll ans2 = inf * inf;     ll tmp = 0;     bool good = false;     for (int i = n - 1; i >= 0; i--) {       if (x[i] ==  1 ) tmp += mod_pow(2, n - 1 - i).n;       if (good && n - 1 - i > 8) break;       if (n - 1 - i > 8) tmp %= mod;       if (acm[n - 1][n - 1 - i].second != inf) {         good = true;         if (n - 1 - i > 8) {           ans2 = tmp + acm[n - 1][n - 1 - i].second;           break;         } else {           ans2 = min(ans2, tmp + acm[n - 1][n - 1 - i].second);         }       }     }     ans2 %= mod;     cout << ans1 << endl;     cout << ans2 << endl;     return 0;   }