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: Accepted)

#pragma GCC optimize("O3")
#include <bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
// using namespace __gnu_pbds;
// gp_hash_table<int, int> mapka;

using namespace std;
#define PB push_back
#define MP make_pair
#define LL long long
#define int LL
#define FOR(i,a,b) for(int i = (a); i <= (b); i++)
#define RE(i,n) FOR(i,1,n)
#define REP(i,n) FOR(i,0,(int)(n)-1)
#define R(i,n) REP(i,n)
#define VI vector<int>
#define PII pair<int,int>
#define LD long double
#define FI first
#define SE second
#define st FI
#define nd SE
#define ALL(x) (x).begin(), (x).end()
#define SZ(x) ((int)(x).size())

template<class C> void mini(C &a4, C b4) { a4 = min(a4, b4); }
template<class C> void maxi(C &a4, C b4) { a4 = max(a4, b4); }

template<class TH> void _dbg(const char *sdbg, TH h){ cerr<<sdbg<<'='<<h<<endl; }
template<class TH, class... TA> void _dbg(const char *sdbg, TH h, TA... a) {
  while(*sdbg!=',')cerr<<*sdbg++;
  cerr<<'='<<h<<','; _dbg(sdbg+1, a...);
}

template<class T> ostream &operator<<(ostream& os, vector<T> V) {
  os << "["; for (auto vv : V) os << vv << ","; return os << "]";
}
template<class L, class R> ostream &operator<<(ostream &os, pair<L,R> P) {
  return os << "(" << P.st << "," << P.nd << ")";
}

#ifdef LOCAL
#define debug(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#else
#define debug(...) (__VA_ARGS__)
#define cerr if(0)cout
#endif

const int P = 998244353;
string s;
int n;
void add(int &a,int b){
  a += b;
  if(a >= P)
    a -= P;
}
const int MAX = 301;
int dp[MAX][MAX][MAX];

#ifdef LOCAL

set<string> odp;
set<string> wyn;
vector<string> todo;
void dodaj(string a){
  if(wyn.insert(a).SE){
    todo.PB(a);
  }
//   if(odp.insert(a).SE){
//     cout << "MAM" << ": " << a << "\n";
//   }
}
void brut() {
//   R(i,SZ(s)){
//     s[i]+='0';
//   }
  dodaj(s);
  R(i,SZ(todo)){
    string x = todo[i];
    if(SZ(x) == 1)continue;
    string y = x.substr(2);
    R(k,2)R(j,SZ(y)+1){
      dodaj(y.substr(0,j) + x[k] + y.substr(j));
    }
  }
  debug(SZ(wyn));
}


int licz(int dl,int zer,int jed){
  int x = (n - dl) + zer + jed;
  int res = 0;
  R(mb,1<<x){
    int ak = dl;
    int i = 0;
    int j = 0;
    string xx;
    R(k,x){
      int pom = (mb >> k) & 1;
      xx += pom + '0';
      if(ak != n && s[ak] == pom){
        ak++;
      }else{
        if(pom){
          j++;
        }else{
          i++;
        }
      }
    }
    if(i == zer && j == jed){
      assert(odp.insert(xx).SE);
      if(wyn.insert(xx).SE){
        cout << "!!!!!!!! " << xx << "\n"; 
      }
      res++;
    }
  }
  return res;
}
#else
int licz(int dl,int zer,int jed){
  int &res = dp[dl][zer][jed];
  if(res != -1) return res;
  res = 0;
  if(dl != n && s[dl] == 0){
    add(res, licz(dl+1,zer,jed));
  }else{
    if(zer)add(res, licz(dl,zer-1,jed));
  }
  if(dl != n && s[dl] == 1){
    add(res, licz(dl+1,zer,jed));
  }else{
    if(jed)add(res, licz(dl,zer, jed-1));
  }
  return res;
}
#endif

bool vis[MAX][MAX][MAX];
void dfs(int a,int b,int c){
  if(vis[a][b][c])return;
  vis[a][b][c] = 1;
  if(a < n){
    if(s[a] == 0)
      b++;
    else
      c++;
    if(b)dfs(a+1,b-1,c);
    if(c)dfs(a+1,b,c-1);
  }
  if(a < n - 1){
    if(s[a+1] == 0)
      b++;
    else
      c++;
    if(s[a] == 0 || s[a+1] == 0)
      dfs(a + 2, b - 1, c);
    if(s[a] == 1 || s[a+1] == 1)
      dfs(a + 2, b, c - 1);
  }
}

int32_t main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout << fixed << setprecision(11);
  cerr << fixed << setprecision(6);
  cin >> s;
  n = SZ(s);
#ifdef LOCAL
  brut();
#endif
  int res = 0;
  int zer = 0;
  int jed = 0;

  R(i,SZ(s)){
    s[i] -= '0';
    if(s[i])jed++;else zer++;
  }
  R(i,SZ(s) + 1)R(j,SZ(s) + 1)R(k,SZ(s) + 1)dp[i][j][k] = -1;
  dp[n][0][0] = 1;
  dfs(0,0,0);
  R(i,zer+1)R(j, jed+1){
    if(i == 0 && j == 0)continue;
    int mam0 = 0;
    int mam1 = 0;
    for(int po = n; i >= mam0 && j >= mam1;){
      if(vis[po][i - mam0][j - mam1]){
        add(res, licz(po,i - mam0,j - mam1));
        break;
      }
      if(po == 0)break;
      po--;
      if(s[po] == 0)
        mam0++;
      else
        mam1++;
    }
  }
  cout << res << "\n";
}