#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const long long MOD = 1e9 + 7;
const int N = 5050;
const int LG = 14;
int b[N][N];
int g[N][N];
int n;
string s;
struct suff_array {
  int L;
  string s;
  int i, skip, lvl;
  vector<vector<int>> P;
  vector<pair<pair<int, int>, int>> M;
  suff_array(const string& s)
      : L(s.size()), s(s), P(1, vector<int>(L, 0)), M(L) {
    for (i = 0; i < L - (L == 1); i++) P[0][i] = int(s[i]);
    for (skip = 1, lvl = 1; skip < L; skip *= 2, lvl++) {
      P.push_back(vector<int>(L, 0));
      for (int i = 0; i < L; i++)
        M[i] = {{P[lvl - 1][i], i + skip < L ? P[lvl - 1][i + skip] : -1000},
                i};
      sort(M.begin(), M.end());
      for (int i = 0; i < L; i++)
        P[lvl][M[i].second] = (i > 0 && M[i].first == M[i - 1].first)
                                  ? P[lvl][M[i - 1].second]
                                  : i;
    }
  }
  const vector<int>& get_sarray() { return P.back(); }
  int lcp(int i, int j) {
    int len = 0;
    if (i == j) return L - i;
    for (int k = P.size() - 1; k >= 0 && i < L && j < L; k--)
      if (P[k][i] == P[k][j]) {
        i += 1 << k;
        j += 1 << k;
        len += 1 << k;
      }
    return len;
  }
  int orig(int i) const { return M[i].second; }
  int ord(int i) const { return P.back()[i]; }
};
suff_array sa("asdf");
int mv[LG][N];
void setup() {
  memset(mv, INF, sizeof mv);
  for (int i = 0; i < n - 1; ++i) {
    mv[0][i] = sa.lcp(sa.orig(i), sa.orig(i + 1));
  }
  for (int l = 0; l < LG - 1; ++l) {
    for (int i = 0; i + (1 << l) < n - 1; ++i) {
      mv[l + 1][i] = min(mv[l][i], mv[l][i + (1 << l)]);
    }
  }
}
long long get_lcp(int i, int j) {
  int a = sa.ord(i);
  int b = sa.ord(j);
  if (a == b) return n - i;
  if (a > b) swap(a, b);
  --b;
  int len = (b - a) + 1;
  int lg = 31 - __builtin_clz(len);
  return min(mv[lg][a], mv[lg][b - (1 << lg) + 1]);
}
long long get_cost(int i, int j) {
  long long tp = 1;
  long long ans = 0;
  for (int k = j - 1; k >= i; --k) {
    ans = (ans + (s[k] == '1' ? tp : 0)) % MOD;
    tp = tp * 2 % MOD;
  }
  return ans;
}
bool leq(int a, int b, int len) {
  if (a < 0) return true;
  int lcp = get_lcp(a, b);
  if (lcp >= len) return true;
  assert(s[lcp + a] != s[lcp + b]);
  return s[lcp + a] < s[lcp + b];
}
int main() {
  ios_base::sync_with_stdio(0), cin.tie(0);
  cin >> s;
  n = s.size();
  sa = suff_array(s);
  setup();
  for (int i = 0; i < N; ++i) {
    g[0][i] = 1;
    b[i][0] = INF;
    b[0][i] = 0;
  }
  for (int i = 1; i <= n; ++i) {
    if (i % 100 == 0) {
    }
    for (int j = 1; i - j >= 0; ++j) {
      bool can_jump = s[i - j] == '1';
      bool leq_result = leq(i - j * 2, i - j, j);
      int a_crit;
      if (!can_jump) {
        g[i][j] = g[i][j - 1];
        b[i][j] = b[i][j - 1];
      } else {
        g[i][j] = leq_result ? g[i - j][j] : g[i - j][j - 1];
        g[i][j] = (g[i][j] + g[i][j - 1]) % MOD;
        int bv = leq_result ? b[i - j][j] : b[i - j][j - 1];
        ++bv;
        b[i][j] = min(b[i][j - 1], bv);
      }
    }
    for (int j = i + 1; j <= n; ++j) {
      g[i][j] = g[i][j - 1];
      b[i][j] = b[i][j - 1];
    }
  }
  long long tcost = 0;
  int elen = 0;
  pair<int, int> best(2, INF);
  long long base = 1;
  long long cur_cost = 0;
  int above = 0;
  for (int i = 1; i <= n; ++i) {
    if (s[n - i] == '1') {
      cur_cost += base;
      if (cur_cost > MOD) {
        cur_cost -= MOD;
        above = 1;
      }
    }
    if (b[n][i] != INF) {
      long long tv = b[n][i] + cur_cost;
      long long fv = (tv >= MOD || above);
      pair<int, int> xv = pair<int, int>(fv, tv % MOD);
      best = min(best, xv);
      if (fv) break;
    }
    base *= 2;
    if (base > MOD) {
      base -= MOD;
      above = 1;
    }
  }
  cout << g[n][n] << "\n";
  cout << best.second << "\n";
  return 0;
}
