stablegradients/pie-gem5-pairs huggingface dataset:
// Slower C++ solution:
#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';

}

// Faster C++ solution for the same problem (measured speedup: 5.47130104499142x):
#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;

}
// Slower C++ solution:
#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;

}


// Faster C++ solution for the same problem (measured speedup: 5.270064075070135x):
#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;

}
// Slower C++ solution:
#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;

}

// Faster C++ solution for the same problem (measured speedup: 5.284799118801177x):
#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;

}
// Slower C++ solution:
#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;

}


// Faster C++ solution for the same problem (measured speedup: 5.354806542825832x):
#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;

}
// Slower C++ solution:
#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;

}

// Faster C++ solution for the same problem (measured speedup: 5.354806542825832x):
#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;

}
// Slower C++ solution:
#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;

}


// Faster C++ solution for the same problem (measured speedup: 5.3554041790934255x):
#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;

}
// Slower C++ solution:
#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;

}

// Faster C++ solution for the same problem (measured speedup: 5.314863772196555x):
#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;

}
// Slower C++ solution:
#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;

}

// Faster C++ solution for the same problem (measured speedup: 5.343495651937829x):
#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;

}
// Slower C++ solution:
#include<bits/stdc++.h>

using namespace std;

#define ll long long 

const int maxn=2e6+20;

const ll MOD=1e9+7;

char s[maxn],t[maxn];

int fail[maxn],suf[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(){

	//freopen(".in","r",stdin);

	//freopen(".out","w",stdout);

	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;

}


// Faster C++ solution for the same problem (measured speedup: 5.281357523899082x):
#include <cstdio>

#include <cstring>



const int N(5e5 + 10);

char s[N]; int n, pre[N], nxt[N], ans;

int check(int x)

{

	int p = pre[x], t = n + 1 - nxt[x + 1];

	return ((!p || (x % (x - p))) && (!t || ((n - x) % (n - x - t))));

}



int main()

{

	scanf("%s", s + 1), n = strlen(s + 1), nxt[n] = n + 1;

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

	{

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

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

	}

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

	{

		while (j <= n && s[j - 1] != s[i]) j = nxt[j];

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

	}

	if (!pre[n] || (n % (n - pre[n]))) return puts("1\n1"), 0;

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

	for (int i = 1; i < n; i++) ans += check(i);

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

	return 0;

}
// Slower C++ solution:
#include <iostream>

#include <sstream>

#include <algorithm>

#include <cstdio>

#include <cmath>

#include <set>

#include <map>

#include <queue>

#include <string>

#include <cstring>

#include <bitset>

#include <functional>

#include <random>

#define REP(i,a,n) for(int i=a;i<=n;++i)

#define PER(i,a,n) for(int i=n;i>=a;--i)

#define hr putchar(10)

#define pb push_back

#define lc (o<<1)

#define rc (lc|1)

#define mid ((l+r)>>1)

#define ls lc,l,mid

#define rs rc,mid+1,r

#define x first

#define y second

#define io std::ios::sync_with_stdio(false)

#define endl '\n'

#define DB(a) ({REP(__i,1,n) cout<<a[__i]<<' ';hr;})

using namespace std;

typedef long long ll;

typedef pair<int,int> pii;

const int P = 1e9+7, INF = 0x3f3f3f3f;

ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}

ll qpow(ll a,ll n) {ll r=1%P;for (a%=P;n;a=a*a%P,n>>=1)if(n&1)r=r*a%P;return r;}

ll inv(ll x){return x<=1?1:inv(P%x)*(P-P/x)%P;}

inline int rd() {int x=0;char p=getchar();while(p<'0'||p>'9')p=getchar();while(p>='0'&&p<='9')x=x*10+p-'0',p=getchar();return x;}

//head







const int N = 1e6+50;

int n;

char s[N], t[N];

int pre[N], suf[N];

void getfail(char *s, int *f, int n) {

	int j = 0;

	REP(i,1,n-1) {

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

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

		f[i+1] = j;

	}

}



int main() {

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

	n = strlen(s+1);

	REP(i,1,n) t[i] = s[n-i+1];

	getfail(s+1,pre,n);

	getfail(t+1,suf,n);

	int len = n%(n-pre[n])==0?n/(n-pre[n]):1;

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

	int ans = 0;

	REP(i,1,n-1) {

		int x = i%(i-pre[i])==0?i/(i-pre[i]):1;

		int y = (n-i)%(n-i-suf[n-i])==0?(n-i)/(n-i-suf[n-i]):1;

		if (x==1&&y==1) ++ans;

	}

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

}














// Faster C++ solution for the same problem (measured speedup: 5.318958610865502x):
#include <cstdio>

#include <cstring>



const int N(5e5 + 10);

char s[N]; int n, pre[N], nxt[N], ans;

int check(int x)

{

	int p = pre[x], t = n + 1 - nxt[x + 1];

	return ((!p || (x % (x - p))) && (!t || ((n - x) % (n - x - t))));

}



int main()

{

	scanf("%s", s + 1), n = strlen(s + 1), nxt[n] = n + 1;

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

	{

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

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

	}

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

	{

		while (j <= n && s[j - 1] != s[i]) j = nxt[j];

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

	}

	if (!pre[n] || (n % (n - pre[n]))) return puts("1\n1"), 0;

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

	for (int i = 1; i < n; i++) ans += check(i);

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

	return 0;

}