Problem:
Score : 1100 points

Problem Statement

Given is a string S consisting of 0 and 1. Find the number of strings, modulo 998244353, that can result from applying the following operation on S zero or more times:

Remove the two characters at the beginning of S, erase one of them, and reinsert the other somewhere in S. This operation can be applied only when S has two or more characters.

Constraints

1 \leq |S| \leq 300

S consists of 0 and 1.

Input

Input is given from Standard Input in the following format:

S

Output

Print the number of strings, modulo 998244353, that can result from applying the operation on S zero or more times.

Sample Input 1

0001

Sample Output 1

8

Eight strings, 0001, 001, 010, 00, 01, 10, 0, and 1, can result.

Sample Input 2

110001

Sample Output 2

24

Sample Input 3

11101111011111000000000110000001111100011111000000001111111110000000111111111

Sample Output 3

697354558

Solution in C++ (GCC 9.2.1) (judge verdict: Wrong Answer)

#pragma GCC target ("avx2")
#pragma GCC optimize ("unroll-loops")
#pragma GCC optimize ("O3")
#include "bits/stdc++.h"
#include <unordered_set>
#include <unordered_map>
#include <random>
using namespace std;
typedef long long ll;
const ll MOD = /*1'000'000'007LL;*/ 998'244'353LL;
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for(int (i)=0; (i)<(n); (i)++)
const int dx[4]={ 1,0,-1,0 };
const int dy[4]={ 0,1,0,-1 };

template<typename T>
T power(T x, long long n, const T &m){
	if(n == 0) return 1;
	if(n == 1) return x;
	T tmp = power(x, n/2, m);
	if(n%2 == 0) return tmp * tmp % m;
	else return tmp * tmp % m * x % m;
}

template<typename T>
T inverse(T x, const T &m){
	return power(x, m-2, m);
}

struct Combination{
private:
	int N;
	long long M;
	vector<long long> f, i;
public:
	void init(int n, long long m){
		N = n; M = m;
		f.resize(N+1); f[0] = 1;
		i.resize(N+1); i[0] = 1;
		for(long long j=1; j<=N; j++){
			f[j] = f[j-1]*j%M;
			i[j] = inverse(f[j], M);
		}
	}
	long long fact(int n){
		return f[n];
	}
	long long C(int n, int r){
		return f[n] * i[r] % M * i[n-r] % M;
	}
};

string S;

ll dp[305][305][305];
ll solve(int n, int c0, int c1){
	if(n == S.size()){
		if(c0 == 0 && c1 == 0) return 1;
		else{
			if(dp[n][c0][c1] != -1) return dp[n][c0][c1];
			return dp[n][c0][c1] = ((c0 > 0 ? solve(n, c0-1, c1) : 0)
				+ (c1 > 0 ? solve(n, c0, c1-1) : 0)) % MOD;
		}
	}
	if(dp[n][c0][c1] != -1) return dp[n][c0][c1];
	if(S[n] == '0'){
		return dp[n][c0][c1] = (solve(n+1, c0, c1)
			+ (c1 > 0 ? solve(n, c0, c1-1) : 0)) % MOD;
	}
	else{
		return dp[n][c0][c1] = (solve(n+1, c0, c1) 
			+ (c0 > 0 ? solve(n, c0-1, c1) : 0)) % MOD;
	}
}

int memo[305][305][305];
int calc(int n, int c0, int c1){
	if(c0 == 0 && c1 == 0) return n;
	if(memo[n][c0][c1] != -1) return memo[n][c0][c1];
	int ret = INT_MAX;
	if(n < S.size() && S[n] == '0' && c0 > 0)
		ret = min(ret, calc(n+1, c0-1, c1));
	if(n+1 < S.size() && S[n+1] == '0' && c0 > 0)
		ret = min(ret, calc(n+2, c0-1, c1));
	if(n < S.size() && S[n] == '1' && c1 > 0)
		ret = min(ret, calc(n+1, c0, c1-1));
	if(n+1 < S.size() && S[n+1] == '1' && c1 > 0)
		ret = min(ret, calc(n+2, c0, c1-1));
	return memo[n][c0][c1] = ret;
}

Combination C;

signed main(){
	cin >> S;
	ll ans = 0;
	memset(memo, -1, sizeof(memo));
	memset(dp, -1, sizeof(dp));
	int i;
	for(i=0; 2*i<S.size(); i++){
		ll tmp = 0;
		for(int j=0; j<=i; j++){
			if(calc(0, j, min(i, (int)S.size()-i)-j) > 2*i) continue;
			tmp += solve(2*i, j, i-j);
		}
		ans += tmp;
		ans %= MOD;
	}
	int cnt0 = 0;
	int cnt1 = 0;
	rep(j, S.size()){
		if(S[j] == '0') cnt0++;
		else cnt1++;
	}
	C.init(305, MOD);
	for(; i<S.size(); i++){
		ll tmp = 0;
		for(int j=0; j<=min(cnt0, (int)S.size()-i); j++){
			if(S.size()-i-j > cnt1) continue;
			tmp += C.C(S.size()-i, j);
		}
		ans += tmp;
		ans %= MOD;
	}
	cout << ans << endl;
}