#include <bits/stdc++.h>
using namespace std;
#define rep2(i, m, n) for (int i = (m); i < (n); ++i)
#define rep(i, n) rep2(i, 0, n)
#define drep2(i, m, n) for (int i = (m)-1; i >= (n); --i)
#define drep(i, n) drep2(i, n, 0)
#define all(x) (x).begin(), (x).end()
template<typename T> using V = vector<T>;
template<typename T> using P = pair<T, T>;
using ll = long long;
using ld = long double;
using Vi = V<int>;  using VVi = V<Vi>;
using Vl = V<ll>;   using VVl = V<Vl>;
using Vd = V<ld>;   using VVd = V<Vd>;
using Vb = V<bool>; using VVb = V<Vb>;
using Pi = P<int>;
using Pl = P<ll>;
using Pd = P<ld>;
template<typename T> vector<T> make_vec(size_t n, T a) { return vector<T>(n, a); }
template<typename... Ts> auto make_vec(size_t n, Ts... ts) { return vector<decltype(make_vec(ts...))>(n, make_vec(ts...)); }
template<typename T> inline int sz(T &x) { return x.size(); }
template<typename T> inline bool chmin(T &a, T b) { if (a > b) { a = b; return true; } return false; }
template<typename T> inline bool chmax(T &a, T b) { if (a < b) { a = b; return true; } return false; }
template<typename T1, typename T2> istream &operator>>(istream &is, pair<T1, T2> &p) { is >> p.first >> p.second; return is; }
template<typename T1, typename T2> ostream &operator<<(ostream &os, const pair<T1, T2> &p) { os << p.first << "\n" << p.second; return os; }
template<typename T> istream &operator>>(istream &is, vector<T> &v) { for (auto &e : v) is >> e; return is; }
template<typename T> ostream &operator<<(ostream &os, const vector<T> &v) { for (auto &e : v) os << e << ' '; return os; }
template<typename T> inline int count_between(vector<T> &a, T l, T r) { return lower_bound(all(a), r) - lower_bound(all(a), l); } // [l, r)
inline int cDiv(const ll x, const ll y) { return (x+y-1) / y; } // ceil(x/y)
inline int fLog2(const ll x) { assert(x > 0); return 63-__builtin_clzll(x); } // floor(log2(x))
inline int cLog2(const ll x) { assert(x > 0); return (x == 1) ? 0 : 64-__builtin_clzll(x-1); } // ceil(log2(x))
inline int popcount(const ll x) { return __builtin_popcountll(x); }
inline void fail() { cout << -1 << '\n'; exit(0); }
struct fast_ios { fast_ios(){ cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(20); }; } fast_ios_;
#ifdef LOCAL
void debug_out() { cerr << endl; }
template <typename Head, typename... Tail> void debug_out(Head H, Tail... T) { cerr << ' ' << H; debug_out(T...); }
#define debug(...) cerr << 'L' << __LINE__ << " [" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#else
#define debug(...) (void(0))
#endif
// const int INF  = 1<<30;
// const ll INFll = 1ll<<60;
// const ld EPS   = 1e-10;
// const ld PI    = acos(-1.0);
// const int MOD  = int(1e9)+7;
// const int MOD  = 998244353;


struct RollingHash {
  using ui64 = uint64_t;
  using ui128 = __uint128_t;
  static const ui64 mod = (1ull<<61) - 1;
  vector<ui64> hash, power;
  ui64 base;

  static inline ui64 add(ui64 a, ui64 b) { if ((a += b) >= mod) a -= mod; return a; }
  static inline ui64 mul(ui64 a, ui64 b) { ui128 c = ui128(a)*b; return add(c>>61, c&mod); }
  static inline ui64 generate_base() {
    mt19937_64 mt(chrono::steady_clock::now().time_since_epoch().count());
    uniform_int_distribution<ui64> rand(2, mod-2);
    return rand(mt);
  }

  template<typename T>
  RollingHash(const T &s, ui64 b = 0) : base(b) {
    if (base == 0) base = generate_base();
    int n = s.size();
    hash.assign(n+1, 0);
    power.assign(n+1, 1);
    rep(i, n) {
      power[i+1] = mul(power[i], base);
      hash[i+1] = add(mul(hash[i], base), s[i]);
    }
  }

  ui64 get(int l, int r) const { return add(hash[r], mod - mul(hash[l], power[r-l])); }

// longest common prefix of s[l1:r1] and s[l2:r2]
  int lcp(int l1, int r1, int l2, int r2) const {
    int len = min(r1-l1, r2-l2);
    int ok = 0, ng = len+1;
    while (ng-ok > 1) {
      int md = (ok+ng)>>1;
      if (get(l1, l1+md) == get(l2, l2+md)) ok = md;
      else ng = md;
    }
    return ok;
  }
  
// longest common prefix of s[l1:r1] and t[l2:r2]
  int lcp(RollingHash &rh, int l1, int r1, int l2, int r2) const {
    int len = min(r1-l1, r2-l2);
    int ok = 0, ng = len+1;
    while (ng-ok > 1) {
      int md = (ok+ng)>>1;
      if (get(l1, l1+md) == rh.get(l2, l2+md)) ok = md;
      else ng = md;
    }
    return ok;
  }
};


Pi solve() {
  string s; cin >> s;
  RollingHash rh(s);

  int n = sz(s);
  Vb bl(n+1);
  Vb br(n+1);

  rep2(i, 1, n) {
    for (int j = i; j+i <= n; j += i) {
      if (rh.get(0, i) == rh.get(j, j+i)) bl[j+i] = true;
      else break;
    }
    for (int j = n-i; j >= i; j -= i) {
      if (rh.get(n-i, n) == rh.get(j-i, j)) br[j-i] = true;
      else break;
    }
  }

  if (!bl[n]) return {1, 1};
  
  bool allsame = true;
  rep(i, n) if (s[0] != s[i]) allsame = false;
  if (allsame) return {n, 1};

  int cnt = 0;
  rep2(i, 1, n) if (!bl[i] && !br[i]) ++cnt;
  return {2, cnt};
}


int main() {
  cout << solve() << '\n';
}

// abcabcabcabcabcab

Measured memory_bytes: 11632