// Original C++ solution (slower):
#include <cstdio>

#include <iostream>

#include <algorithm>

#include <string>

#include <cstring>

#include <vector>

#include <queue>

#include <set>

#include <map>

#include <cmath>

#include <iomanip>

#include <cassert>

#include <bitset>

using namespace std;



typedef pair<int, int> P;

#define rep(i, n) for (int i=0; i<(n); i++)

#define all(c) (c).begin(), (c).end()

#define uniq(c) c.erase(unique(all(c)), (c).end())

#define index(xs, x) (int)(lower_bound(all(xs), x) - xs.begin())

#define _1 first

#define _2 second

#define pb push_back

#define INF 1145141919

#define MOD 1000000007



const int B = 321;

int N;

string S;

int dp[500001];

int num[500001];

int T[500001];

int pB[500001];

bool good_prefix[500000], good_suffix[500000];



inline int rhash(int l, int r) {

  return (1LL * ((T[r]+MOD-(l>0?T[l-1]:0))%MOD) * pB[N-l]) % MOD;

}



bool cycle(int l, int r, int d) {

  if (2*d > r-l+1) return false;

  // [l, r-d] = [l+d, r]

  return rhash(l, r-d) == rhash(l+d, r);

}



bool is_good(int l, int r) {

  int n = r-l+1;

  int til = sqrt(n);

  for (int d=1; d<=til; d++) {

    if (n % d) continue;

    if (cycle(l, r, d)) return false;

    if (cycle(l, r, n/d)) return false;

  }

  return true;

}



signed main() {

  ios::sync_with_stdio(false); cin.tie(0);

  cin >> S;

  N = S.length();

  pB[0] = 1;

  for (int i=1; i<=500000; i++) pB[i] = (1LL*pB[i-1]*B) % MOD;

  rep(i, N) {

    T[i] = (1LL*pB[i]*S[i])%MOD;

    if (i > 0) T[i] = (T[i] + T[i-1]) % MOD;

  }



  bool same = true;

  rep(i, N-1) if (S[i] != S[i+1]) same = false;

  if (same) {

    cout << N << "\n";

    cout << 1 << "\n";

    return 0;

  }

  if (is_good(0, N-1)) {

    cout << 1 << "\n";

    cout << 1 << "\n";

    return 0;

  }

  rep(i, N) if (is_good(0    , i  )) good_prefix[i] = true;

  rep(i, N) if (is_good(N-1-i, N-1)) good_suffix[i] = true;

  int s = 0;

  for (int p=1; p<=N-1; p++) {

    if (good_prefix[p-1] && good_suffix[N-1-p]) s++;

  }

  cout << 2 << "\n";

  cout << s << "\n";

  return 0;

}


// Optimized solution to the same problem (faster):
#include <cstdio>

#include <iostream>

#include <algorithm>

#include <string>

#include <cstring>

#include <vector>

#include <queue>

#include <set>

#include <map>

#include <cmath>

#include <iomanip>

#include <cassert>

#include <bitset>

using namespace std;



typedef pair<int, int> P;

#define rep(i, n) for (int i=0; i<(n); i++)

#define all(c) (c).begin(), (c).end()

#define uniq(c) c.erase(unique(all(c)), (c).end())

#define index(xs, x) (int)(lower_bound(all(xs), x) - xs.begin())

#define _1 first

#define _2 second

#define pb push_back

#define INF 1145141919

#define MOD 1000000007



int N;

string S;

bool good_prefix[500000], good_suffix[500000];



vector<int> KMP(string &S) {

  vector<int> A(S.length()+1, -1);

  A[0] = -1;

  int j = -1;

  rep(i, S.length()) {

    while (j >= 0 && S[i] != S[j]) j = A[j];

    A[i+1] = ++j;

  }

  A.erase(A.begin());

  return A;

}



signed main() {

  ios::sync_with_stdio(false); cin.tie(0);

  cin >> S;

  N = S.length();

  vector<int> A = KMP(S); rep(i, N) A[i] = i+1 - A[i];

  rep(i, N) good_prefix[i] = !((i+1) % A[i] == 0 && A[i] != i+1);

  if (A[N-1] == 1) {

    cout << N << "\n";

    cout << 1 << "\n";

    return 0;

  }



  reverse(all(S));

  A = KMP(S); rep(i, N) A[i] = i+1 - A[i];

  rep(i, N) good_suffix[i] = !((i+1) % A[i] == 0 && A[i] != i+1);



  if (good_prefix[N-1]) {

    cout << 1 << "\n";

    cout << 1 << "\n";

    return 0;

  }

  int s = 0;

  for (int p=1; p<=N-1; p++) {

    if (good_prefix[p-1] && good_suffix[N-1-p]) s++;

  }

  cout << 2 << "\n";

  cout << s << "\n";

  return 0;

}


// Fastest known solution for this problem: