stablegradients/pie-gem5-bysrc huggingface dataset:
// Original C++ solution (slower):
#include<stdio.h>

#include<string>

#include<math.h>

#include<stdlib.h>

#include<set>

#include<bitset>

#include<map>

#include<vector>

#include<string.h>

#include<algorithm>

#include<iostream>

#include<queue>

#include<deque>

#include<stack>

#include<cmath>

#include<ctime>

#include<complex>

#include<list>

#include<limits.h>

using namespace std;



const int N=5e5+5;

int n=1,tot;



void failure(char s[],int fail[]){

	fail[1]=0;

	for(int i=2,j=0;i<=n;i++){

		while(j&&s[j+1]!=s[i]) j=fail[j];

		if(s[j+1]==s[i]) j++;

		fail[i]=j;

	}

}



char s[N],rs[N];

int f[N],rf[N];



int main(){

	scanf("%s",s);

	n=strlen(s);

	for(int i=1;i<=n;i++) rs[i]=s[n-i];

	rs[n+1]='\0';

	for(int i=n;i>=1;i--) s[i]=s[i-1];

	s[n+1]='\0';

	failure(s,f);

	failure(rs,rf);

	if(f[n]==n-1) printf("%d\n1\n",n);

	else if(f[n]==0||rf[n]==0||n%(n-f[n])!=0||n%(n-rf[n])!=0) puts("1\n1");

	else{

		for(int i=1;i<n;i++) if((i%(i-f[i])!=0||f[i]==0)&&(rf[n-i]==0||(n-i)%(n-i-rf[n-i])!=0)) tot++;

		printf("2\n%d\n",tot);

	}

	return 0;

}

// Optimized solution to the same problem (faster):
#include <stdio.h>

#include <string.h>

#include <algorithm>

#define Maxn 500005

char s[Maxn];

int n, ans, fail1[Maxn], fail2[Maxn];

void buildFail(char *s, int *fail) {

	int j = fail[0] = -1;

	for (int i = 1; i <= n; ++ i) {

		while (j >= 0 && s[j] != s[i - 1]) j = fail[j];

		fail[i] = ++ j;

	}

}

int main() {

	scanf("%s", s); n = strlen(s);

	buildFail(s, fail1);

	int len = n % (n - fail1[n]) == 0 && (n - fail1[n] <= n / 2) ? n - fail1[n] : -1;

	if (len == -1) return puts("1\n1") & 0;

	if (len == 1) return printf("%d\n1\n", n) & 0;

	puts("2"); std :: reverse(s, s + n);

	buildFail(s, fail2); for (int i = 1; i < n; ++ i)

		if ((!fail1[i] || i % (i - fail1[i])) && (!fail2[n - i] || (n - i) % ((n - i) - fail2[n - i]))) ++ ans;

	printf("%d\n", ans);

	return 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

using namespace std;

typedef long long lint;

typedef unsigned long long ulint;

typedef pair<int, int> pii;

typedef pair<lint, lint> pll;

#define endl '\n'

#define next next_

#define fst first

#define sed second

#define pb push_back

#define mp make_pair

#define rint register int

#define newline putchar('\n')

#define leave_space puthchar(' ')

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

#define reveal(x) cerr << #x << " = " << (x) << endl

#define rep(it, f, e) for (rint it = f; it <= e; ++it)

#define per(it, f, e) for (rint it = f; it >= e; --it)

const int MAXN = 5e5 + 20;

char s[MAXN], t[MAXN];

int n, fail1[MAXN], fail2[MAXN];

inline void getfail(int fail[], char s[]) {

	int j = 0;

	fail[0] = -1;

	rep (i, 1, n - 1) { 

		while (j && s[i] != s[j]) j = fail[j];

		fail[i + 1] = s[i] == s[j] ? ++j : 0;

	}

}

inline bool check_cyc1(int x) {

	return fail1[x] == 0 || x % (x - fail1[x]);

}

inline bool check_cyc2(int x) {

	if (x == 0) return false;

	return fail2[x] == 0 || x % (x - fail2[x]);

}

int main() {

	scanf("%s", s);

	n = strlen(s);

	memcpy(t, s, sizeof(t));

	reverse(t, t + n);

	getfail(fail1, s);

	getfail(fail2, t);

	int res = check_cyc1(n) ? 1 : 2;

	bool flag = true;

	rep (i, 1, n - 1) {

		if (s[i] != s[i - 1]) {

			flag = false;

			break;

		}

	}

	if (flag) {

		cout << n << endl;

		cout << 1 << endl;

	} else if (res == 1) {

		cout << 1 << endl;

		cout << 1 << endl;

	} else {

		int ans = 0;

		rep (i, 0, n - 1) {

			ans += (check_cyc1(i + 1) && check_cyc2(n - i - 1));

		}

		cout << 2 << endl;

		cout << ans << endl;

	}

	return 0;

}

// Optimized solution to the same problem (faster):
// ===================================

//   author: M_sea

//   website: http://m-sea-blog.com/

// ===================================

#include <algorithm>

#include <iostream>

#include <cstdlib>

#include <cstring>

#include <cstdio>

#include <cmath>

#define re register

using namespace std;



inline int read() {

    int X=0,w=1; char c=getchar();

    while (c<'0'||c>'9') { if (c=='-') w=-1; c=getchar(); }

    while (c>='0'&&c<='9') X=X*10+c-'0',c=getchar();

    return X*w;

}



const int N=500000+10;



int n; char s[N];

int prenxt[N],sufnxt[N];



inline void getnext() {

    for (re int i=2,j=prenxt[1]=0;i<=n;++i) {

        while (j&&s[j+1]!=s[i]) j=prenxt[j];

        if (s[j+1]==s[i]) ++j;

        prenxt[i]=j;

    }

    reverse(s+1,s+n+1);

    for (re int i=2,j=sufnxt[n]=0;i<=n;++i) {

        while (j&&s[j+1]!=s[i]) j=sufnxt[j];

        if (s[j+1]==s[i]) ++j;

        sufnxt[i]=j;

    }

}



inline int checkpre(int i) { return !prenxt[i]||i%(i-prenxt[i]); }

inline int checksuf(int i) { return !sufnxt[i]||i%(i-sufnxt[i]); }



int main() {

    scanf("%s",s+1); n=strlen(s+1); getnext();

    if (checkpre(n)) { puts("1\n1"); return 0; }

    if (n-prenxt[n]==1) { printf("%d\n1\n",n); return 0; }

    int ans=0;

    for (re int i=1;i<=n;++i)

        if (checkpre(i)&&checksuf(n-i)) ++ans;

    printf("2\n%d\n",ans);

    return 0;

}

//qwq

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

using namespace std;



const int N = 5e5 + 5;

const int mod = 1e9 + 9277;



int n;

string s;

int hs[N], pw[N];

bool prf[N], suf[N];



int get(int l,int r) {

	return (hs[r] - 1LL * hs[l - 1] * pw[r - l + 1] % mod + mod) % mod;

}



int main() {

	ios_base::sync_with_stdio(false);

	cin >> s; n = s.size(); s = '#' + s;

	hs[0] = 0, pw[0] = 1;

	for (int i = 1; i <= n; ++i) {

		hs[i] = (1LL * hs[i - 1] * 1007 % mod + (s[i] - 'a' + 1)) % mod;

		pw[i] = 1LL * pw[i - 1] * 1007 % mod;

	}

	

	for (int i = 1; i <= n; ++i) {

		for (int j = i + i; j <= n; j += i) {

			if (get(j - i + 1, j) == get(1, i)) prf[j] = true;

			else break;

		}

	}

	

	for (int i = 1; i <= n; ++i) {

		for (int j = n - i - i + 1; j >= 1; j -= i) {

			if (get(j, j + i - 1) == get(n - i + 1, n)) suf[j] = true;

			else break;

		}

	}

	

	if (!prf[n]) return cout << 1 << '\n' << 1 << '\n',0;

	int cnt = 0;

	for (int i = 1; i < n; ++i) if (!prf[i] && !suf[i + 1]) {

		cnt++;

	} 

	if (cnt) cout << 2 << '\n' << cnt << '\n';

	else cout << n << '\n' << 1 << '\n';

}

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

#include <cstring>

#include <algorithm>



const int MAXN = 5e5 + 5;



template<typename _T>

void read( _T &x )

{

	x = 0;char s = getchar();int f = 1;

	while( s > '9' || s < '0' ){if( s == '-' ) f = -1; s = getchar();}

	while( s >= '0' && s <= '9' ){x = ( x << 3 ) + ( x << 1 ) + ( s - '0' ), s = getchar();}

	x *= f;

}



template<typename _T>

void write( _T x )

{

	if( x < 0 ){ putchar( '-' ); x = ( ~ x ) + 1; }

	if( 9 < x ){ write( x / 10 ); }

	putchar( x % 10 + '0' );

}



char S[MAXN];

int nxt1[MAXN], nxt2[MAXN];

int N;



void calc( int *ret )

{

	ret[1] = 0;

	for( int i = 2, j = ret[1] ; i <= N ; i ++ )

	{

		while( j && S[i] ^ S[j + 1] ) j = ret[j];

		if( S[j + 1] == S[i] ) j ++;

		ret[i] = j;

	}

}



bool chkPre( const int p ) { return nxt1[p] && p % ( p - nxt1[p] ) == 0; }

bool chkSuf( const int p ) { return nxt2[p] && p % ( p - nxt2[p] ) == 0; }

bool chk( const int p ) { return chkPre( p ) == 0 && chkSuf( N - p ) == 0; }



int main()

{

	scanf( "%s", S + 1 );

	N = strlen( S + 1 );

	calc( nxt1 ), std :: reverse( S + 1, S + 1 + N ), calc( nxt2 );

	if( nxt1[N] && N % ( N - nxt1[N] ) == 0 )

	{

		if( nxt1[N] == N - 1 ) { printf( "%d\n%d\n", N, 1 ); return 0; }

		puts( "2" ); int ans = 0;

		for( int i = 1 ; i < N ; i ++ ) 

			ans += chk( i );

		write( ans ), putchar( '\n' );

	}

	else puts( "1\n1" );

	return 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

using namespace std;

int n, cnt;

char s[500020];

int p[500020];

int f[500020];

int g[500020];

void gao(int *f) {

	int u = 0;

	for (int i = 2; i <= n; i++) {

		while (u > 0 && s[u + 1] != s[i]) {

			u = p[u];

		}

		if (s[u + 1] == s[i]) {

			u++;

		}

		p[i] = u;

	}

	for (int i = 1; i <= n; i++) {

		if (p[i] == 0 || i % (i - p[i]) > 0) {

			f[i] = 1;

		}

	}

}

int main() {

	scanf("%s", s + 1);

	n = strlen(s + 1);

	gao(f);

	if (f[n]) {

		printf("1\n1\n");

		return 0;

	}

	reverse(s + 1, s + 1 + n);

	gao(g);

	for (int i = 1; i <= n; i++) {

		if (f[i] && g[n - i]) {

			cnt++;

		}

	}

	if (cnt == 0) {

		printf("%d\n1\n", n);

	} else {

		printf("2\n%d\n", cnt);

	}

	return 0;

}


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

#include <cstring>

#include <algorithm>



const int MAXN = 5e5 + 5;



template<typename _T>

void read( _T &x )

{

	x = 0;char s = getchar();int f = 1;

	while( s > '9' || s < '0' ){if( s == '-' ) f = -1; s = getchar();}

	while( s >= '0' && s <= '9' ){x = ( x << 3 ) + ( x << 1 ) + ( s - '0' ), s = getchar();}

	x *= f;

}



template<typename _T>

void write( _T x )

{

	if( x < 0 ){ putchar( '-' ); x = ( ~ x ) + 1; }

	if( 9 < x ){ write( x / 10 ); }

	putchar( x % 10 + '0' );

}



char S[MAXN];

int nxt1[MAXN], nxt2[MAXN];

int N;



void calc( int *ret )

{

	ret[1] = 0;

	for( int i = 2, j = ret[1] ; i <= N ; i ++ )

	{

		while( j && S[i] ^ S[j + 1] ) j = ret[j];

		if( S[j + 1] == S[i] ) j ++;

		ret[i] = j;

	}

}



bool chkPre( const int p ) { return nxt1[p] && p % ( p - nxt1[p] ) == 0; }

bool chkSuf( const int p ) { return nxt2[p] && p % ( p - nxt2[p] ) == 0; }

bool chk( const int p ) { return chkPre( p ) == 0 && chkSuf( N - p ) == 0; }



int main()

{

	scanf( "%s", S + 1 );

	N = strlen( S + 1 );

	calc( nxt1 ), std :: reverse( S + 1, S + 1 + N ), calc( nxt2 );

	if( nxt1[N] && N % ( N - nxt1[N] ) == 0 )

	{

		if( nxt1[N] == N - 1 ) { printf( "%d\n%d\n", N, 1 ); return 0; }

		puts( "2" ); int ans = 0;

		for( int i = 1 ; i < N ; i ++ ) 

			ans += chk( i );

		write( ans ), putchar( '\n' );

	}

	else puts( "1\n1" );

	return 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int N=2e6+20;

const ll mod=1e9+7;

char s[N],t[N];

int fail[N],suf[N];

void getfail(int *fail,char *s)

{

	fail[0]=-1;

	int i=0,j=-1;

	while(s[i])

	{

		if(j==-1||s[i]==s[j])

		{

			fail[i+1]=j+1;

			i++,j++;

		}

		else

			j=fail[j];

	}

}

int main()

{

	scanf("%s",s);

	ll ans=0;

	int len=strlen(s);

	for(int i=0;s[i];i++)

	t[i]=s[len-i-1];

	t[len]='\0';

	getfail(fail,s);

	getfail(suf,t);

	int m;

	if(fail[len]==0||len%(len-fail[len]))

	m=1;

	else

	m=2;

	bool flag=true;

	for(int i=1;s[i];i++)

	{

		if(s[i]!=s[i-1])

			flag=false;

	}	

	if(flag)

	m=len;

	if(m==1||flag)

	ans=1;

	else

	{

		for(int i=0;i<len-1;i++)

		{

			int k=len-i-1;

			if((fail[i+1]==0||(i+1)%((i+1)-fail[i+1])) &&(suf[k]==0||(k)%(k-suf[k])))

			ans++;

		}

	}	

	printf("%d\n%d\n",m,ans);

	return 0;

}

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

#include <cstring>

#include <algorithm>



const int MAXN = 5e5 + 5;



template<typename _T>

void read( _T &x )

{

	x = 0;char s = getchar();int f = 1;

	while( s > '9' || s < '0' ){if( s == '-' ) f = -1; s = getchar();}

	while( s >= '0' && s <= '9' ){x = ( x << 3 ) + ( x << 1 ) + ( s - '0' ), s = getchar();}

	x *= f;

}



template<typename _T>

void write( _T x )

{

	if( x < 0 ){ putchar( '-' ); x = ( ~ x ) + 1; }

	if( 9 < x ){ write( x / 10 ); }

	putchar( x % 10 + '0' );

}



char S[MAXN];

int nxt1[MAXN], nxt2[MAXN];

int N;



void calc( int *ret )

{

	ret[1] = 0;

	for( int i = 2, j = ret[1] ; i <= N ; i ++ )

	{

		while( j && S[i] ^ S[j + 1] ) j = ret[j];

		if( S[j + 1] == S[i] ) j ++;

		ret[i] = j;

	}

}



bool chkPre( const int p ) { return nxt1[p] && p % ( p - nxt1[p] ) == 0; }

bool chkSuf( const int p ) { return nxt2[p] && p % ( p - nxt2[p] ) == 0; }

bool chk( const int p ) { return chkPre( p ) == 0 && chkSuf( N - p ) == 0; }



int main()

{

	scanf( "%s", S + 1 );

	N = strlen( S + 1 );

	calc( nxt1 ), std :: reverse( S + 1, S + 1 + N ), calc( nxt2 );

	if( nxt1[N] && N % ( N - nxt1[N] ) == 0 )

	{

		if( nxt1[N] == N - 1 ) { printf( "%d\n%d\n", N, 1 ); return 0; }

		puts( "2" ); int ans = 0;

		for( int i = 1 ; i < N ; i ++ ) 

			ans += chk( i );

		write( ans ), putchar( '\n' );

	}

	else puts( "1\n1" );

	return 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int N=2e6+20;

const ll mod=1e9+7;

char s[N],t[N];

int fail[N],suf[N];

void getfail(int *fail,char *s)

{

	fail[0]=-1;

	int i=0,j=-1;

	while(s[i])

	{

		if(j==-1||s[i]==s[j])

		{

			fail[i+1]=j+1;

			i++,j++;

		}

		else

			j=fail[j];

	}

}

int main()

{

	while(scanf("%s",s)!=EOF)

	{

		ll ans=0;

		int len=strlen(s);

		for(int i=0;s[i];i++)

			t[i]=s[len-i-1];

		t[len]='\0';

		getfail(fail,s);

		getfail(suf,t);

		int m;

	//	cout<<fail[len]<<endl;

		if(fail[len]==0||len%(len-fail[len]))

			m=1;

		else

			m=2;

		bool flag=true;

		for(int i=1;s[i];i++)

		{

			if(s[i]!=s[i-1])

				flag=false;

		}	

		if(flag)

			m=len;

		if(m==1||flag)

			ans=1;

		else

		{

			for(int i=0;i<len-1;i++)

			{

				int k=len-i-1;

			//	cout<<i<<' '<<k<<endl;

				if((fail[i+1]==0||(i+1)%((i+1)-fail[i+1])) &&(suf[k]==0||(k)%(k-suf[k])))

					ans++;

			}

		}	

		cout<<m<<endl<<ans<<endl;

	}

	return 0;

}


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

#include <cstring>

#include <algorithm>



const int MAXN = 5e5 + 5;



template<typename _T>

void read( _T &x )

{

	x = 0;char s = getchar();int f = 1;

	while( s > '9' || s < '0' ){if( s == '-' ) f = -1; s = getchar();}

	while( s >= '0' && s <= '9' ){x = ( x << 3 ) + ( x << 1 ) + ( s - '0' ), s = getchar();}

	x *= f;

}



template<typename _T>

void write( _T x )

{

	if( x < 0 ){ putchar( '-' ); x = ( ~ x ) + 1; }

	if( 9 < x ){ write( x / 10 ); }

	putchar( x % 10 + '0' );

}



char S[MAXN];

int nxt1[MAXN], nxt2[MAXN];

int N;



void calc( int *ret )

{

	ret[1] = 0;

	for( int i = 2, j = ret[1] ; i <= N ; i ++ )

	{

		while( j && S[i] ^ S[j + 1] ) j = ret[j];

		if( S[j + 1] == S[i] ) j ++;

		ret[i] = j;

	}

}



bool chkPre( const int p ) { return nxt1[p] && p % ( p - nxt1[p] ) == 0; }

bool chkSuf( const int p ) { return nxt2[p] && p % ( p - nxt2[p] ) == 0; }

bool chk( const int p ) { return chkPre( p ) == 0 && chkSuf( N - p ) == 0; }



int main()

{

	scanf( "%s", S + 1 );

	N = strlen( S + 1 );

	calc( nxt1 ), std :: reverse( S + 1, S + 1 + N ), calc( nxt2 );

	if( nxt1[N] && N % ( N - nxt1[N] ) == 0 )

	{

		if( nxt1[N] == N - 1 ) { printf( "%d\n%d\n", N, 1 ); return 0; }

		puts( "2" ); int ans = 0;

		for( int i = 1 ; i < N ; i ++ ) 

			ans += chk( i );

		write( ans ), putchar( '\n' );

	}

	else puts( "1\n1" );

	return 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int N=2e6+20;

const ll mod=1e9+7;

char s[N],t[N];

int fail[N],suf[N];

void getfail(int *fail,char *s)

{

	fail[0]=-1;

	int i=0,j=-1;

	while(s[i])

	{

		if(j==-1||s[i]==s[j])

		{

			fail[i+1]=j+1;

			i++,j++;

		}

		else

			j=fail[j];

	}

}

int main()

{

	while(scanf("%s",s)!=EOF)

	{

		ll ans=0;

		int len=strlen(s);

		for(int i=0;s[i];i++)

			t[i]=s[len-i-1];

		t[len]='\0';

		getfail(fail,s);

		getfail(suf,t);

		int m;

	//	cout<<fail[len]<<endl;

		if(fail[len]==0||len%(len-fail[len]))

			m=1;

		else

			m=2;

		bool flag=true;

		for(int i=1;s[i];i++)

		{

			if(s[i]!=s[i-1])

				flag=false;

		}	

		if(flag)

			m=len;

		if(m==1||flag)

			ans=1;

		else

		{

			for(int i=0;i<len-1;i++)

			{

				int k=len-i-1;

			//	cout<<i<<' '<<k<<endl;

				if((fail[i+1]==0||(i+1)%((i+1)-fail[i+1])) &&(suf[k]==0||(k)%(k-suf[k])))

					ans++;

			}

		}	

		cout<<m<<endl<<ans<<endl;

	}

	return 0;

}

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

#include <cstring>

#include <algorithm>



const int MAXN = 5e5 + 5;



template<typename _T>

void read( _T &x )

{

	x = 0;char s = getchar();int f = 1;

	while( s > '9' || s < '0' ){if( s == '-' ) f = -1; s = getchar();}

	while( s >= '0' && s <= '9' ){x = ( x << 3 ) + ( x << 1 ) + ( s - '0' ), s = getchar();}

	x *= f;

}



template<typename _T>

void write( _T x )

{

	if( x < 0 ){ putchar( '-' ); x = ( ~ x ) + 1; }

	if( 9 < x ){ write( x / 10 ); }

	putchar( x % 10 + '0' );

}



char S[MAXN];

int nxt1[MAXN], nxt2[MAXN];

int N;



void calc( int *ret )

{

	ret[1] = 0;

	for( int i = 2, j = ret[1] ; i <= N ; i ++ )

	{

		while( j && S[i] ^ S[j + 1] ) j = ret[j];

		if( S[j + 1] == S[i] ) j ++;

		ret[i] = j;

	}

}



bool chkPre( const int p ) { return nxt1[p] && p % ( p - nxt1[p] ) == 0; }

bool chkSuf( const int p ) { return nxt2[p] && p % ( p - nxt2[p] ) == 0; }

bool chk( const int p ) { return chkPre( p ) == 0 && chkSuf( N - p ) == 0; }



int main()

{

	scanf( "%s", S + 1 );

	N = strlen( S + 1 );

	calc( nxt1 ), std :: reverse( S + 1, S + 1 + N ), calc( nxt2 );

	if( nxt1[N] && N % ( N - nxt1[N] ) == 0 )

	{

		if( nxt1[N] == N - 1 ) { printf( "%d\n%d\n", N, 1 ); return 0; }

		puts( "2" ); int ans = 0;

		for( int i = 1 ; i < N ; i ++ ) 

			ans += chk( i );

		write( ans ), putchar( '\n' );

	}

	else puts( "1\n1" );

	return 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int N=2e6+20;

const ll mod=1e9+7;

char s[N],t[N];

int fail[N],suf[N];

void getfail(int *fail,char *s)

{

	fail[0]=-1;

	int i=0,j=-1;

	while(s[i])

	{

		if(j==-1||s[i]==s[j])

		{

			fail[i+1]=j+1;

			i++,j++;

		}

		else

			j=fail[j];

	}

}

int main()

{

	while(scanf("%s",s)!=EOF)

	{

		ll ans=0;

		int len=strlen(s);

		for(int i=0;s[i];i++)

			t[i]=s[len-i-1];

		t[len]='\0';

		getfail(fail,s);

		getfail(suf,t);

		int m;

	//	cout<<fail[len]<<endl;

		if(fail[len]==0||len%(len-fail[len]))

			m=1;

		else

			m=2;

		bool flag=true;

		for(int i=1;s[i];i++)

		{

			if(s[i]!=s[i-1])

				flag=false;

		}	

		if(flag)

			m=len;

		if(m==1||flag)

			ans=1;

		else

		{

			for(int i=0;i<len-1;i++)

			{

				int k=len-i-1;

			//	cout<<i<<' '<<k<<endl;

				if((fail[i+1]==0||(i+1)%((i+1)-fail[i+1])) &&(suf[k]==0||(k)%(k-suf[k])))

					ans++;

			}

		}	

		cout<<m<<endl<<ans<<endl;

	}

	return 0;

}


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

#include <cstring>

#define ri register int

const int N=5e5+5;

char s[N]; 

int pnxt[N],snxt[N];

int main(){

	ri n,i,j,ans;

	scanf("%s",s+1);

	n=strlen(s+1);

	for(i=2;i<=n;++i){

		j=pnxt[i-1];

		while(j&&s[j+1]!=s[i]) j=pnxt[j];

		if(s[j+1]==s[i]) pnxt[i]=j+1;

	}

	if(!pnxt[n]||n%(n-pnxt[n])) // 不是循环串

		return puts("1\n1"),0;

	else if(pnxt[n]==n-1) // 所有字母都相等

		return printf("%d\n1\n",n),0; 

	snxt[n]=n+1;

	for(i=n-1;i;--i){

		j=snxt[i+1];

		while(j!=n+1&&s[j-1]!=s[i]) j=snxt[j];

		if(s[j-1]==s[i]) snxt[i]=j-1;

		else snxt[i]=n+1;

	}

	ans=0;

	for(i=1;i^n;++i)

		if((!pnxt[i]||i%(i-pnxt[i]))&&(snxt[i+1]==n+1||(n-i)%(n-i-(n-snxt[i+1]+1)))) ++ans;

	printf("2\n%d\n",ans);

	return 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<bits/stdc++.h>

#define lowbit(i) ((i)&(-(i)))

#define lson(i) ((i)<<1)

#define rson(i) ((i)<<1|1)

#define sqr(x) ((x)*(x))

#define fi first

#define se second

#define mp(x,y) make_pair((x),(y))

#define pb push_back

using namespace std;



typedef long long ll;

typedef unsigned long long ul;

typedef pair<int,int> pii;

typedef vector<int> vii;

typedef vector<pii> vpi;

typedef queue<int> qii;



const int inf=0x3f3f3f3f;

const int maxn=2e6+5;

const long long MOD=1e9+7;



char s[maxn],t[maxn];

int fail[maxn],refail[maxn];



void getfail(int *fail,char *s){

	fail[0]=-1;

	int i=0,j=-1;

	while(s[i]){

		if(j==-1 || s[i]==s[j]){

			fail[i+1]=j+1;

			i++;

			j++;

		}

		else{

			j=fail[j];

		}

	}

}



int main(){

	scanf("%s",&s);

	ll ans=0;

	int len=strlen(s);

	for(int i=0;s[i];i++){

		t[i]=s[len-i-1];

	}

	t[len]='\0';

	getfail(fail,s);

	getfail(refail,t);

	int m;

	if(fail[len]==0 || len%(len-fail[len])){

		m=1;

	}

	else{

		m=2;

	}

	bool flag=1;

	for(int i=1;s[i];i++){

		if(s[i]!=s[i-1]){

			flag=0;

		}

	}

	if(flag){

		m=len;

	}

	if(m==1 || flag){

		ans=1;

	}

	else{

		for(int i=0;i<len-1;i++){

			int k=len-i-1;

			if((fail[i+1]==0 || (i+1)%(i+1-fail[i+1])) && (refail[k]==0 || k%(k-refail[k]))){

				ans++;

				ans%=MOD;

			}

		}

	}

	cout<<m<<endl<<ans%MOD<<endl;

	return 0;

}

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

#include <cstring>

#define ri register int

const int N=5e5+5;

char s[N]; 

int pnxt[N],snxt[N];

int main(){

	ri n,i,j,ans;

	scanf("%s",s+1);

	n=strlen(s+1);

	for(i=2;i<=n;++i){

		j=pnxt[i-1];

		while(j&&s[j+1]!=s[i]) j=pnxt[j];

		if(s[j+1]==s[i]) pnxt[i]=j+1;

	}

	if(!pnxt[n]||n%(n-pnxt[n])) // 不是循环串

		return puts("1\n1"),0;

	else if(pnxt[n]==n-1) // 所有字母都相等

		return printf("%d\n1\n",n),0; 

	snxt[n]=n+1;

	for(i=n-1;i;--i){

		j=snxt[i+1];

		while(j!=n+1&&s[j-1]!=s[i]) j=snxt[j];

		if(s[j-1]==s[i]) snxt[i]=j-1;

		else snxt[i]=n+1;

	}

	ans=0;

	for(i=1;i^n;++i)

		if((!pnxt[i]||i%(i-pnxt[i]))&&(snxt[i+1]==n+1||(n-i)%(n-i-(n-snxt[i+1]+1)))) ++ans;

	printf("2\n%d\n",ans);

	return 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

#define N 500005

using namespace std;

char s[N], t[N];

int n, flag, pre[N], suf[N], ans = 0;

inline void getfail(int *fail,char *s) {

	fail[0] = -1;

	int j = 0;

	for (int i = 1; i < n; ++i){ 

		while (j && s[i] != s[j]) j = fail[j];

		if (s[i] == s[j]) fail[i + 1] = ++j;

		else fail[i + 1] = 0;

	}

}

inline bool checkpre(int pos) { return pre[pos] == 0 || pos % (pos - pre[pos]); }

inline bool checksuf(int pos) { return suf[pos] == 0 || pos % (pos - suf[pos]); }

int main(){

	scanf("%s",s), n = strlen(s);

	for (int i = 0; i < n; ++i) t[i] = s[n - i - 1];

	getfail(pre, s), getfail(suf, t), t[n] = '\0';

	flag = checkpre(n) ? 1 : 2;

	bool f = true;

	for (int i = 1; i < n; ++i) if (s[i] != s[i - 1]) { f = false; break; }

	if (f) flag = n;

	cout << flag << '\n';

	if (flag != 2) { cout << 1; return 0; }

	for (int i = 0; i < n; ++i) {

		int tmp = n - i - 1;

		if (checkpre(i + 1) && checksuf(tmp)) ++ans;

	}

	cout << ans;

	return 0;

}

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

#include <cstring>

#define ri register int

const int N=5e5+5;

char s[N]; 

int pnxt[N],snxt[N];

int main(){

	ri n,i,j,ans;

	scanf("%s",s+1);

	n=strlen(s+1);

	for(i=2;i<=n;++i){

		j=pnxt[i-1];

		while(j&&s[j+1]!=s[i]) j=pnxt[j];

		if(s[j+1]==s[i]) pnxt[i]=j+1;

	}

	if(!pnxt[n]||n%(n-pnxt[n])) // 不是循环串

		return puts("1\n1"),0;

	else if(pnxt[n]==n-1) // 所有字母都相等

		return printf("%d\n1\n",n),0; 

	snxt[n]=n+1;

	for(i=n-1;i;--i){

		j=snxt[i+1];

		while(j!=n+1&&s[j-1]!=s[i]) j=snxt[j];

		if(s[j-1]==s[i]) snxt[i]=j-1;

		else snxt[i]=n+1;

	}

	ans=0;

	for(i=1;i^n;++i)

		if((!pnxt[i]||i%(i-pnxt[i]))&&(snxt[i+1]==n+1||(n-i)%(n-i-(n-snxt[i+1]+1)))) ++ans;

	printf("2\n%d\n",ans);

	return 0;

}

// Fastest known solution for this problem: