Problem:
Score : 1400 points

Problem Statement

Consider the following set of rules for encoding strings consisting of 0 and 1:

Strings 0 and 1 can be encoded as 0 and 1, respectively.

If strings A and B can be encoded as P and Q, respectively, then string AB can be encoded as PQ.

If string A can be encoded as P and K \geq 2 is a positive integer, then string AA...A (A repeated K times) can be encoded as (PxK).

For example, string 001001001, among other possibilities, can be encoded as 001001001, 00(1(0x2)x2)1 and (001x3).

Let's call string A a subset of string B if:

A and B are equal in length and consist of 0 and 1;

for all indices i such that A_i = 1, it's also true that B_i = 1.

You are given string S consisting of 0 and 1. Find the total number of distinct encodings of all subsets of S, modulo 998244353.

Constraints

1 \leq |S| \leq 100

S consists of 0 and 1.

Input

Input is given from Standard Input in the following format:

S

Output

Print the total number of distinct encodings of all subsets of S modulo 998244353.

Sample Input 1

011

Sample Output 1

9

There are four subsets of S:

011 can be encoded as 011 and 0(1x2);

010 can be encoded as 010;

001 can be encoded as 001 and (0x2)1;

000 can be encoded as 000, 0(0x2), (0x2)0 and (0x3).

Thus, the total number of encodings of all subsets of S is 2 + 1 + 2 + 4 = 9.

Sample Input 2

0000

Sample Output 2

10

This time S has only one subset, but it can be encoded in 10 different ways.

Sample Input 3

101110

Sample Output 3

156

Sample Input 4

001110111010110001100000100111

Sample Output 4

363383189

Don't forget to take the result modulo 998244353.

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

#include<bits/stdc++.h>
#define Rint register int
using namespace std;
typedef long long LL;
const int N = 103, mod = 998244353;
inline void qmo(int &x){x += (x >> 31) & mod;}
map<string, int> F, G;
string S;
int f(string s);
int g(string s){
	if(G.count(s)) return G[s];
	if(s.size() == 1) return G[s] = s[0] - '0' + 1;
	int &ans = G[s];
	for(Rint i = 1;i < s.size();++ i) if(!(s.size() % i)){
		string t; int tmp = s.size() / i;
		for(Rint j = 0;j < i;++ j){
			bool flag = true;
			for(Rint k = 0;k < tmp && flag;++ k) flag &= s[i * k + j] == '1';
			t += (char)(flag + '0');
		}
		qmo(ans += f(t) - mod);
	}
	return ans;
}
int f(string s){
	if(F.count(s)) return F[s];
	int &ans = F[s];
	for(Rint i = 1;i <= s.size();++ i)
		qmo(ans += (LL) g(s.substr(0, i)) * f(s.substr(i)) % mod - mod);
	return ans;
}
int main(){
	cin >> S; F[""] = 1; cout << f(S);
}