Problem:
ぶりしゃぶしゃぶり部
次のニュースです．新型コロナウイルスの感染拡大により飲食店以外でのよりよい食事を求める動きが強まる中，ある部活動が注目を集めています．
その名も，ぶりしゃぶしゃぶり部．この新しい活動に取り組む，都内のあるグループを取材しました．
渋谷区のマンションの一室．10 代から 30 代までの若い男女が集まって鍋を囲っています．「このカニもういけるんじゃない？」「あ，ほんとだ」
外から見る限りは，普通のカニ鍋のようです．ぶりですらないようですが……？
このグループの代表を務める男性に話を聞きました．
ICPC-JAG (International Collegiate Programming Contest Japanese Alumni Group) 代表 N さん「今日はICPC模擬国内予選の打ち上げです．」
記者「えっ，じゃあぶりしゃぶしゃぶり部というのはいったいなんなんでしょう？」
N さん「ぶりしゃぶしゃぶり部って回文っぽくないですか？」
記者「か，回文……？」
N さん「回文というのは，前から読んでも後ろから読んでも同じになる文のことです．回文っぽいっていうのは，そうですね……」
JAGのメンバーでありこの会話を横で聞きながらカニ鍋をつついていたあなたは，文字列の回文っぽさを判定するプログラムをここで書いてあげれば取材の助けになるかもしれないと思った．ここで，文字列の回文っぽさとは，次のように定められる数である．
文字列後半（奇数長のときには中央の文字を含まない）から範囲の重複しない区間を 0 個以上の任意の個数選び，それぞれの区間の部分文字列を反転することで，全体の文字列を回文にすることを考える．回文になる区間の選び方全体が空でないとき，これらのうちそれぞれの区間の長さの二乗の総和の最小値を文字列の回文っぽさとする．回文になる区間の選び方が存在しないとき，回文っぽさは -1 とする．長さ
n
の文字列
S = S
1
S
2
... S
n
が回文であるとは，任意の
i = 1, ..., n
に対して
S
i
= S
n+1-i
が成り立つことのみをいう．
Input
入力は 50 個以下のデータセットからなる． 各データセットは次の形式で表される．
S
S
は小文字アルファベットからなる文字列であり，
1 ≤ |S| ≤ 20000
を満たす．
入力の終わりは # の 1 文字のみからなる行で表される．
Output
各データセットに対し，文字列
S
の回文っぽさを 1 行に出力せよ．
Sample Input
burisyabusyaburibu
abcdefefbcda
satorarepotenetoperarotas
abcacb
#
Output for the Sample Input
33
13
0
-1

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
#define rep(i, n) for (ll i = 0; i < (ll)(n); i++)
#define rrep(i,start,end) for (ll i = start;i >= (ll)(end);i--)
#define repn(i,end) for(ll i = 0; i <= (ll)(end); i++)
#define reps(i,start,end) for(ll i = start; i < (ll)(end); i++)
#define repsn(i,start,end) for(ll i = start; i <= (ll)(end); i++)
#define each(p,a) for(auto &p:a)
typedef vector<ll> vll;
typedef vector<pair<ll ,ll>> vpll;
typedef vector<vector<ll>> vvll;
typedef set<ll> sll;
typedef map<ll , ll> mpll;
typedef pair<ll ,ll> pll;
typedef tuple<ll , ll , ll> tpl3;
#define LL(...) ll __VA_ARGS__; input(__VA_ARGS__)
#define LD(...) ld __VA_ARGS__; input(__VA_ARGS__)
#define Str(...) string __VA_ARGS__; input(__VA_ARGS__)
#define Ch(...) char __VA_ARGS__; input(__VA_ARGS__)
#define all(a)  (a).begin(),(a).end()
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define sz(x) (ll)x.size()
// << std::fixed << std::setprecision(10)
const ll INF = 1LL << 60;
const ld EPS = 1e-9;
 
ll lceil(ll a,ll b){if(a%b==0){return a/b;}if(a>=0){return (a/b)+1;}else{return -((-a)/b);}}
ll lfloor(ll a,ll b){if(a%b==0){return a/b;}if(a>=0){return (a/b);}else{return -((-a)/b)-1;}}
inline ll positive_mod(ll a,ll m){return (a % m + m)%m;}
inline ll popcnt(ull a){ return __builtin_popcountll(a);}
//0indexed
inline ll topbit(ll a){assert(a != 0);return 63 - __builtin_clzll(a);}
inline ll smlbit(ll a){assert(a != 0);return __builtin_ctzll(a);}
template<class T> bool chmin(T& a, T b){if(a > b){a = b;return true;}return false;}
template<class T> bool chmax(T& a, T b){if(a < b){a = b;return true;}return false;}
template<typename T> std::istream &operator>>(std::istream&is,std::vector<T>&v){for(T &in:v){is>>in;}return is;}
template<typename T> std::ostream &operator<<(std::ostream&os,const std::vector<T>&v){for(auto it=std::begin(v);it!=std::end(v);){os<<*it<<((++it)!=std::end(v)?" ":"");}return os;}
template<typename T1, typename T2>std::ostream &operator<< (std::ostream &os, std::pair<T1,T2> p){os << "{" << p.first << "," << p.second << "}";return os;}
template<class... T>void input(T&... a){(cin >> ... >> a);}
void print(){cout << endl;}
template<class T, class... Ts>void print(const T& a, const Ts&... b){cout << a;((cout << ' ' << b), ...);cout << endl;}
template<class T> void pspace(const T& a){ cout << a << ' ';}
void perr(){cerr << endl;}
template<class T, class... Ts>void perr(const T& a, const Ts&... b){cerr << a;((cerr << ' ' << b), ...);cerr << endl;}
void yes(bool i = true){ return print(i?"yes":"no"); }
void Yes(bool i = true){ return print(i?"Yes":"No"); }
void YES(bool i = true){ return print(i?"YES":"NO"); }
template <class T> vector<T> &operator++(vector<T> &v) {for(auto &e : v) e++;return v;}
template <class T> vector<T> operator++(vector<T> &v, signed) {auto res = v;for(auto &e : v) e++;return res;}
template <class T> vector<T> &operator--(vector<T> &v) {for(auto &e : v) e--;return v;}
template <class T> vector<T> operator--(vector<T> &v, signed) {auto res = v;for(auto &e : v) e--;return res;}
//grid探索用
vector<ll> _ta = {0,0,1,-1,1,1,-1,-1};
vector<ll> _yo = {1,-1,0,0,1,-1,1,-1};
bool isin(ll now_i,ll now_j,ll h,ll w){return (0<=now_i && now_i < h && 0 <= now_j && now_j < w);}
  
ll lpow(ll x,ll n){ll ans = 1;while(n >0){if(n & 1)ans *= x;x *= x;n >>= 1;}return ans;}
ll Modlpow(ll x,ll n,ll m){ll ans = 1;ll a = x%m;while(n >0){if(n & 1){ans *= a;ans%= m;}a *= a;a %= m;n >>= 1;}return ans;} 
const ll MOD9 = 998244353LL;
const ll MOD10 = 1000000007LL;

//参考 https://drken1215.hatenablog.com/entry/2019/03/12/135500
//https://qiita.com/keymoon/items/11fac5627672a6d6a9f6
//verify https://atcoder.jp/contests/tessoku-book/submissions/52829138
struct RollingHash{

  const ull MASK30 = (1UL << 30) - 1;
  const ull MASK31 = (1UL << 31) - 1;
  const ull MOD = (1UL << 61) - 1;
  const ull MASK61 = MOD;
  const ull POSITIVIZER = MOD * 4;
  const ull base = 9973;


  string s;
  vector<ull> hash;

  RollingHash(){}

  RollingHash(const string &_s){
    init(_s);
  }

  //mod 2^61-1を計算する関数
  ull CalcMod(ull x)
  {
      ull xu = x >> 61;
      ull xd = x & MASK61;
      ull res = xu + xd;
      if (res >= MOD) res -= MOD;
      return res;
  }
  //a*b mod 2^61-1を返す関数(最後にModを取る)
  ull Mul(ull a, ull b)
  {
      ull au = a >> 31;
      ull ad = a & MASK31;
      ull bu = b >> 31;
      ull bd = b & MASK31;
      ull mid = ad * bu + au * bd;
      ull midu = mid >> 30;
      ull midd = mid & MASK30;
      return CalcMod(au * bu * 2 + midu + (midd << 31) + ad * bd);
  }
  
  //2^61 -1 で割る時のpow計算
  
  ull SuperMODpow(ll x,ll n){
    // MOD = (1UL << 61) - 1;,Mul,CalcMod必要
    ull ans = 1;
    ull a = x;
    while(n> 0){
      if(n & 1){
        ans = Mul(ans,a);
      }
      a = Mul(a,a);
      n>>=1;
    }
    return ans;
  }

  void init(const string &_s){
    s = _s;
    ll n = s.size();
    hash.assign(n+1,0);
    rep(i,n){
      hash[i + 1] = CalcMod((Mul(hash[i],base) + s[i]));
    }
  }

  //[l,r)のハッシュを返す
  inline ull get(ll l,ll r){
    return CalcMod(hash[r]+ POSITIVIZER - Mul(hash[l],SuperMODpow(base,r-l)));
  }
};

void solve(string s){
  ll n = sz(s);
  ll sid  = n/2;
  ll tid = n/2;
  if(n % 2 == 1)sid++;
  // string t = s.substr(0,n/2);
  RollingHash rs(s);
  vector<ll> dp(n/2 + 1,INF);
  dp[0] = 0;
  // rep(i,n){

  // }
  rep(i,n/2){
    if(s[sid+i] == s[tid-i -1]){
      chmin(dp[i+1],dp[i]);
      continue;
    }
    //伸ばす
    bool find = false;
    for(ll j = 2;sid+i+j <= n;j++){
      if(rs.get(sid+i,sid+i+j) == rs.get(tid-(i+j),tid-i)){
        chmin(dp[i+j],dp[i]+j*j);
        i = i+j-1;
        find = true;
        break;
      }
    }
    if(!find)break;
    
  }
  if(dp[n/2] == INF){
    cout << -1 << endl;
  }else{
    cout << dp[n/2] << endl;
  }
}
 
int main(){
  ios::sync_with_stdio(false);cin.tie(nullptr);
  while(true){
    Str(s);
    if(s == "#")break;
    solve(s);
  }
}
accuracy: 1
time_ms: 10
memory_kb: 3944
final_rank: 11

code_snippet: //#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define rep(i,n) for (ll i=0;i<(ll)n;i++)
#define rrep(i,n) for (ll i=n-1;i>=(ll)0;i--)
#define loop(i,m,n) for(ll i=m;i<=(ll)n;i++)
#define rloop(i,m,n) for(ll i=m;i>=(ll)n;i--)
#define vl vector<long long>
#define vvl vector<vector<long long>>
#define vdbg(a) rep(ii,a.size()){cout<<a[ii]<<" ";}cout<<endl;
#define vvdbg(a) rep(ii,a.size()){rep(jj,a[ii].size()){cout<<a[ii][jj]<<" ";}cout<<endl;}
#define setdbg(a) for(const auto & ii:a){cout<<ii<<" ";}cout<<endl;
#define inf 4000000000000000000LL
#define mod 998244353LL
#define eps 0.000000001
//#define mod 1000000007LL
random_device rnd;// 非決定的な乱数生成器
mt19937 mt(rnd());// メルセンヌ・ツイスタの32ビット版、引数は初期シード

template<typename T>
struct RollingHash{
	//桁の進数
	static vector<pair<ll,ll>> base;
	//桁の進数のinv
	static vector<pair<ll,ll>> baseinv;
	//管理のmod
	static ll md;
	
	vector<pair<ll,ll>> hash={{0,0}},rhash={{0,0}};
	map<T,ll> table;

	//(HashTable)
	RollingHash(map<T,ll> h){table=h;}

	void push_back(T c){
		if(base.size()==hash.size()){
			base.push_back({(base.back().first*base[1].first)%md,(base.back().second*base[1].second)%md});
			baseinv.push_back({(baseinv.back().first*baseinv[1].first)%md,(baseinv.back().second*baseinv[1].second)%md});
		}
		ll tmp=hash.size()-1;
		hash.push_back({(hash[tmp].first+base[tmp].first*table[c])%md,(hash[tmp].second+base[tmp].second*table[c])%md});
		rhash.push_back({(rhash[tmp].first*base[1].first+table[c])%md,(rhash[tmp].second*base[1].second+table[c])%md});
	}
	
	void pop_back(){
		hash.pop_back();
		rhash.pop_back();
	}

	pair<ll,ll> get_hash(ll l,ll r){
		pair<ll,ll> ans={((hash[r].first-hash[l].first+md)*baseinv[l].first)%md,((hash[r].second-hash[l].second+md)*baseinv[l].second)%md};
		return ans;
	}

	pair<ll,ll> get_revhash(ll l,ll r){
		pair<ll,ll> ans={(rhash[r].first-((rhash[l].first*base[r-l].first)%md)+md)%md,(rhash[r].second-((rhash[l].second*base[r-l].second)%md)+md)%md};
		return ans;
	}

	bool ispalindrome(ll l,ll r){
		pair<ll,ll> obv={((hash[r].first-hash[l].first+md)*baseinv[l].first)%md,((hash[r].second-hash[l].second+md)*baseinv[l].second)%md};
		pair<ll,ll> rev={(rhash[r].first-((rhash[l].first*base[r-l].first)%md)+md)%md,(rhash[r].second-((rhash[l].second*base[r-l].second)%md)+md)%md};
		return obv==rev;		
	}
	
	ll size(){
		return hash.size()-1;
	}
};
template<typename T>
vector<pair<ll,ll>> RollingHash<T>::base = {{1,1},{999999929,999999937}};
template<typename T>
vector<pair<ll,ll>> RollingHash<T>::baseinv = {{1,1},{209585860,189774042}};
template<typename T>
ll RollingHash<T>::md = 1048828087;


ll solve(){
	string s;
	cin>>s;
	if(s=="#"){return 1;}

	map<char,ll> table;
	rep(i,26){
		table['a'+i]=mt()%1048828087;
	}
	
	RollingHash<char> mae(table);
	RollingHash<char> usiro(table);
	
	ll n=s.size();
	ll ans=0;

	ll st=0;

	rep(i,n/2){
		//文字列の追加
		mae.push_back(s[i]);
		usiro.push_back(s[n-i-1]);

		//一致したらフリップ
		if(mae.get_hash(st,i+1)==usiro.get_revhash(st,i+1)){
			if(st!=i){
				ans+=(i+1-st)*(i+1-st);
			}
			st=i+1;
		}
	}
	if((n/2)==st)cout<<ans<<endl;
	else cout<<-1<<endl;
	return 0;
}

//メイン
int main(){
	while(solve()==0);
	return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 4812
final_rank: 13

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define all(a) (a).begin(), (a).end()
#define rep(i, n) for (int i = 0; i < (int)(n); ++i)
#define rrep(i, n) for (int i = (int)(n) - 1; 0 <= i; --i)
template <typename T> bool chmax(T& a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <typename T> bool chmin(T& a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
void solve();
string s;
signed main() {
  cin.tie(nullptr)->sync_with_stdio(false);
  cout << fixed << setprecision(20);
  int TESTCASES = 1<<30;
  //cin >> TESTCASES;
  while (TESTCASES--) {
    cin>>s;
    if(s=="#")break;
    solve();
  }
}
class RollingHash {
private:
  vector<unsigned long long> hash;
  vector<unsigned long long> power;
  unsigned long long mod = ((unsigned long long)1 << 61) - 1;

  unsigned long long add(unsigned long long a, unsigned long long b) {
    unsigned long long ret = a + b;
    if (mod <= ret) {
      ret -= mod;
    }
    return ret;
  }

  unsigned long long mul(unsigned long long a, unsigned long long b) {
    unsigned long long ret = (__uint128_t)a * (__uint128_t)b % (__uint128_t)mod;
    return ret;
  }

public:
  RollingHash(string a, unsigned long long base = 10007) {
    int n = a.size();
    hash.assign(n + 1, 0);
    power.assign(n + 1, 0);
    power[0] = 1;
    for (int i = 0; i < n; ++i) {
      power[i + 1] = mul(power[i], base);
      hash[i + 1] = add(mul(hash[i], base), (unsigned long long)a[i]);
    }
  }

  unsigned long long query(int l, int r) {
    return add(hash[r], mod - mul(hash[l], power[r - l]));
  }

  unsigned long long connect(unsigned long long lhs, unsigned long long rhs, int rhs_len) {
    return add(mul(lhs, power[rhs_len]), rhs);
  }
};
constexpr ll inf=(ll)1<<60;
ll dp[2<<17];
void solve() {
  int n=s.size();
  RollingHash rh(s);
  rep(i,n+1)dp[i]=inf;
  dp[(n+1)/2]=0;
  for(int i=(n+1)/2;i<n;++i){
    if(s[i]==s[n-1-i])chmin(dp[i+1],dp[i]);
    for(int j=i+2;j<=n;++j){
      if(rh.query(i,j)==rh.query(n-j,n-i)){
        ll cost=(ll)(j-i)*(j-i);
        chmin(dp[j],dp[i]+cost);
      }
    }
  }
  if(dp[n]==inf)dp[n]=-1;
  cout<<dp[n]<<'\n';
}
accuracy: 1
time_ms: 4450
memory_kb: 4024
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;
// 18:18
class RollingHash {
   private:
    vector<unsigned long long> hash;
    vector<unsigned long long> power;
    unsigned long long mod = ((unsigned long long)1 << 61) - 1;

    unsigned long long add(unsigned long long a, unsigned long long b) {
        unsigned long long ret = a + b;
        if (mod <= ret) {
            ret -= mod;
        }
        return ret;
    }

    unsigned long long mul(unsigned long long a, unsigned long long b) {
        unsigned long long ret =
            (__uint128_t)a * (__uint128_t)b % (__uint128_t)mod;
        return ret;
    }

   public:
    RollingHash(string a, unsigned long long base = 10007) {
        int n = a.size();
        hash.assign(n + 1, 0);
        power.assign(n + 1, 0);
        power[0] = 1;
        for (int i = 0; i < n; ++i) {
            power[i + 1] = mul(power[i], base);
            hash[i + 1] = add(mul(hash[i], base), (unsigned long long)a[i]);
        }
    }

    unsigned long long query(int l, int r) {
        return add(hash[r], mod - mul(hash[l], power[r - l]));
    }

    unsigned long long connect(unsigned long long lhs, unsigned long long rhs,
                               int rhs_len) {
        return add(mul(lhs, power[rhs_len]), rhs);
    }
};
string s;
using ull = unsigned long long;
using ll = long long;
bool chmin(ll& a, ll b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
void solve() {
    RollingHash H(s);
    int N = s.size();
    constexpr ll inf = (ll)1 << 60;
    vector<ll> dp(N + 1, inf);
    int start = (N + 1) / 2;
    dp[start] = 0;
    for (int i = start; i < N; ++i) {
        if (s[i] == s[N - 1 - i]) chmin(dp[i + 1], dp[i]);
        for (int j = i + 2; j <= N; ++j) {
            // [i, j) <-> [N-j, N-i)
            if (H.query(i, j) == H.query(N - j, N - i)) {
                chmin(dp[j], dp[i] + (ll)(j - i) * (j - i));
            }
        }
    }
    if (dp[N] == inf) dp[N] = -1;
    cout << dp[N] << '\n';
}
int main() {
    while (1) {
        cin >> s;
        if (s == "#") break;
        solve();
    }
}
accuracy: 1
time_ms: 4460
memory_kb: 3972
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define ALL(v) (v).begin(), (v).end()
using ll = long long;

using ll = long long;
using ull = unsigned long long;


const ull mod = 0x1fffffffffffffff, base = chrono::duration_cast<chrono::microseconds>(chrono::system_clock::now().time_since_epoch()).count() % mod;
struct RollingHash {
    vector<ull> hashed, power;
    
    static constexpr ull mask(ll a){ return (1ULL << a) - 1; }
    
    inline ull mul(ull a, ull b) const {
        //*
        __uint128_t ans = __uint128_t(a) * b;
        /*/
         // without __uint128_t
         ull a31 = a >> 31, b31 = b >> 31;
         a &= mask(31);
         b &= mask(31);
         ull x = a * b31 + b * a31;
         ull ans = (a31 * b31 << 1) + (x >> 30) + ((x & mask(30)) << 31) + a * b;
         //*/
        ans = (ans >> 61) + (ans & mod);
        if(ans >= mod) ans -= mod;
        return ans;
    }
    
    
    RollingHash(const string &s) {
        ll n = s.size();
        hashed.assign(n + 1, 0);
        power.assign(n + 1, 0);
        power[0] = 1;
        for(ll i = 0; i < n; i++) {
            power[i + 1] = mul(power[i], base);
            hashed[i + 1] = mul(hashed[i], base) + s[i];
            if(hashed[i + 1] >= mod) hashed[i + 1] -= mod;
        }
    }
    
    ull get(ll l, ll r) const {
        ull ret = hashed[r] + mod - mul(hashed[l], power[r - l]);
        if(ret >= mod) ret -= mod;
        return ret;
    }
    
    ull connect(ull h1, ull h2, ll h2len) const {
        ull ret = mul(h1, power[h2len]) + h2;
        if(ret >= mod) ret -= mod;
        return ret;
    }
    
    void connect(const string &s){
        ll n = hashed.size() - 1, m = s.size();
        hashed.resize(n + m + 1);
        power.resize(n + m + 1);
        for(ll i = n; i < n + m; i++) {
            power[i + 1] = mul(power[i], base);
            hashed[i + 1] = mul(hashed[i], base) + s[i - n];
            if(hashed[i + 1] >= mod) hashed[i + 1] -= mod;
        }
    }
    
    ll LCP(const RollingHash &b, ll l1, ll r1, ll l2, ll r2) {
        ll len = min(r1 - l1, r2 - l2);
        ll low = -1, high = len + 1;
        while(high - low > 1) {
            ll mid = (low + high) / 2;
            if(get(l1, l1 + mid) == b.get(l2, l2 + mid)) low = mid;
            else high = mid;
        }
        return low;
    }
};

int main() {
    while (true) {
        string S; cin >> S;
        if (S == "#") break;
        int N = S.size();
        string T = S.substr(0, N/2), U = S.substr((N+1)/2);
        string rT = T;
        reverse(ALL(rT));
        RollingHash TH(T), rTH(rT), UH(U);
        ll ans = 0;
        int l = 0;
        for (int r = 1; r <= N/2; r++) {
            if (rTH.get(l, r) == UH.get(l, r)) {
                l = r;
                continue;
            }
            if (TH.get(N/2-r, N/2-l) == UH.get(l, r)) {
                reverse(U.begin()+l, U.begin()+r);
                ans += (r - l) * (r - l);
                l = r;
            }
        }
        cout << (rT == U ? ans : -1) << "\n";
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3668
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define all(...) std::begin(__VA_ARGS__), std::end(__VA_ARGS__)
#define rall(...) std::rbegin(__VA_ARGS__), std::rend(__VA_ARGS__)
#define OVERLOAD_REP(_1, _2, _3, _4, name, ...) name
#define REP1(n) for(ll i=0;i<(n);i++)
#define REP2(i, n) for (ll i=0;i<(n);i++)
#define REP3(i, a, n) for (ll i=a;i<(n);i++)
#define REP4(i, a, b, n) for(ll i=a;i<(n);i+=b)
#define rep(...) OVERLOAD_REP(__VA_ARGS__, REP4, REP3, REP2, REP1)(__VA_ARGS__)
#define OVERLOAD_RREP(_1, _2, _3, _4, name, ...) name
#define RREP1(n) for(ll i=(n)-1;i>=0;i--)
#define RREP2(i, n) for(ll i=(n)-1;i>=0;i--)
#define RREP3(i, a, n) for(ll i=(n)-1;i>=(a);i--)
#define RREP4(i, a, b, n) for(ll i=(n)-1;i>=(a);i-=(b))
#define rrep(...) OVERLOAD_RREP(__VA_ARGS__, RREP4, RREP3, RREP2, RREP1)(__VA_ARGS__)
#define uniq(a) sort(all(a));a.erase(unique(all(a)),end(a))
#define len(n) (long long)(n).size()
using ll = long long;
using ld = long double;
using ull = unsigned long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vvvi = vector<vvi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using vvvll = vector<vvll>;
using vs = vector<string>;
using vvs = vector<vs>;
using vvvs = vector<vvs>;
using vld = vector<ld>;
using vvld = vector<vld>;
using vvvld = vector<vvld>;
using vc = vector<char>;
using vvc = vector<vc>;
using vvvc = vector<vvc>;
using pll = pair<ll,ll>;
using vpll = vector<pll>;
using vvpll = vector<vpll>;

ll intpow(ll a,ll b){
    ll ans = 1;
    while (b){
        if (b & 1){
            ans *= a;
        }
        a *= a;
        b /= 2;
    }
    return ans;
}
ll modpow(ll a,ll b,ll c){
    ll ans = 1;
    while (b){
        if (b & 1){
            ans *= a;
            ans %= c;
        }
        a *= a;
        a %= c;
        b /= 2;
    }
    return ans;
}

template<class... T>
void input(T&... a){
    (cin >> ... >> a);
}

#define INT(...) int __VA_ARGS__; input(__VA_ARGS__)
#define LL(...) ll __VA_ARGS__; input(__VA_ARGS__)
#define ULL(...) ull __VA_ARGS__; input(__VA_ARGS__)
#define LD(...) ld __VA_ARGS__; input(__VA_ARGS__)
#define STR(...) string __VA_ARGS__; input(__VA_ARGS__)
#define CHA(...) char __VA_ARGS__; input(__VA_ARGS__)
#define VLL(name,length) vll name(length);rep(i,length){cin >> name[i];}
#define VVLL(name,h,w) vvll name(h,vll(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVLL(name,a,b,c) vvvll name(a,vvll(b,vll(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define VI(name,length) vi name(length);rep(i,length){cin >> name[i];}
#define VVI(name,h,w) vvi name(h,vi(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVI(name,a,b,c) vvvi name(a,vvll(b,vi(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define VLD(name,length) vld name(length);rep(i,length){cin >> name[i];}
#define VVLD(name,h,w) vvld name(h,vld(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVLD(name,a,b,c) vvvld name(a,vvld(b,vld(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define VC(name,length) vc name(length);rep(i,length){cin >> name[i];}
#define VVC(name,h,w) vvc name(h,vc(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVC(name,a,b,c) vvvc name(a,vvc(b,vc(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define VS(name,length) vs name(length);rep(i,length){cin >> name[i];}
#define VVS(name,h,w) vvs name(h,vs(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVS(name,a,b,c) vvvs name(a,vvs(b,vs(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define PLL(name) pll name;cin>>name.first>>name.second;
#define VPLL(name,length) vpll name(length);rep(i,length){cin>>name[i].first>>name[i].second;}

void print(){cout << "\n";}

template <typename T1, typename T2>
std::ostream& operator<<(std::ostream& os, const std::pair<T1, T2>& p) {
    os << "(" << p.first << ", " << p.second << ")";
    return os;
}

template <typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& vec) {
    os << "[";
    for (size_t i = 0; i < vec.size(); ++i) {
        os << vec[i];
        if (i + 1 < vec.size()) os << ", ";
    }
    os << "]";
    return os;
}

template <typename T1, typename T2>
std::ostream& operator<<(std::ostream& os, const std::vector<std::pair<T1, T2>>& a) {
    os << "[";
    for (size_t j = 0; j < a.size(); ++j) {
        os << "(" << a[j].first << ", " << a[j].second << ")";
		if (j + 1 < a.size()) os << ", ";
    }
	os << "]";
    return os;
}

template <typename T1, typename T2>
std::ostream& operator<<(std::ostream& os, const std::vector<std::vector<std::pair<T1, T2>>>& mat) {
	os << "[";
    for (size_t i = 0; i < mat.size(); ++i) {
		os << "[";
        for (size_t j = 0; j < mat[i].size(); ++j) {
            os << "(" << mat[i][j].first << ", " << mat[i][j].second << ")";
			if (j + 1 < mat[i].size()) os << ", ";
        }
		os << "]";
		if (i + 1 < mat.size()) os << ", ";
    }
	os << "]";
    return os;
}

template <typename T>
std::ostream& operator<<(std::ostream& os, const std::set<T>& s) {
    os << "{";
    bool first = true;
    for (const auto& x : s) {
        if (!first) os << ", ";
        os << x;
        first = false;
    }
    os << "}";
    return os;
}

template <typename K, typename V>
std::ostream& operator<<(std::ostream& os, const std::map<K, V>& m) {
    os << "{";
    bool first = true;
    for (const auto& [key, val] : m) {
        if (!first) os << ", ";
        os << key << ": " << val;
        first = false;
    }
    os << "}";
    return os;
}

template<class T, class... Ts>
void print(const T& a, const Ts&... b){cout << a;(cout << ... << (cout << ' ', b));cout << '\n';}

void write(){cout << "\n";}
template<class T, class... Ts>
void write(const T& a, const Ts&... b){cout << a;(cout << ... << (cout << ' ', b));cout << '\n';}
void write(vll x){rep(i,len(x)){cout << x[i];if(i!=len(x)-1){cout << " ";}else{cout << '\n';}}}
void write(vvll x){rep(i,len(x))rep(j,len(x[i])){cout << x[i][j];if(j!=len(x[i])-1){cout << " ";}else{cout << '\n';}}}
void write(vi x){rep(i,len(x)){cout << x[i];if(i!=len(x)-1){cout << " ";}else{cout << '\n';}}}
void write(vvi x){rep(i,len(x))rep(j,len(x[i])){cout << x[i][j];if(j!=len(x[i])-1){cout << " ";}else{cout << '\n';}}}
void write(vvvi x){rep(i,len(x))rep(j,len(x[i]))rep(k,len(x[i][j])){cout << x[i][j][k];if(k!=len(x[i][j])-1){cout << " ";}else if(j!=len(x[i])-1){cout << " | ";}else{cout << '\n';}}}
void write(vld x){rep(i,len(x)){cout << x[i];if(i!=len(x)-1){cout << " ";}else{cout << '\n';}}}
void write(vvld x){rep(i,len(x))rep(j,len(x[i])){cout << x[i][j];if(j!=len(x[i])-1){cout << " ";}else{cout << '\n';}}}
void write(vvvld x){rep(i,len(x))rep(j,len(x[i]))rep(k,len(x[i][j])){cout << x[i][j][k];if(k!=len(x[i][j])-1){cout << " ";}else if(j!=len(x[i])-1){cout << " | ";}else{cout << '\n';}}}
void write(vc x){rep(i,len(x)){cout << x[i];if(i!=len(x)-1){cout << " ";}else{cout << '\n';}}}
void write(vvc x){rep(i,len(x))rep(j,len(x[i])){cout << x[i][j];if(j!=len(x[i])-1){cout << " ";}else{cout << '\n';}}}
void write(vvvc x){rep(i,len(x))rep(j,len(x[i]))rep(k,len(x[i][j])){cout << x[i][j][k];if(k!=len(x[i][j])-1){cout << " ";}else if(j!=len(x[i])-1){cout << " | ";}else{cout << '\n';}}}
void write(vs x){rep(i,len(x)){cout << x[i];if(i!=len(x)-1){cout << " ";}else{cout << '\n';}}}
void write(vvs x){rep(i,len(x))rep(j,len(x[i])){cout << x[i][j];if(j!=len(x[i])-1){cout << " ";}else{cout << '\n';}}}
void write(vvvs x){rep(i,len(x))rep(j,len(x[i]))rep(k,len(x[i][j])){cout << x[i][j][k];if(k!=len(x[i][j])-1){cout << " ";}else if(j!=len(x[i])-1){cout << " | ";}else{cout << '\n';}}}
void write(pll x){cout << x.first << ' ' << x.second << '\n';}
void write(vpll x){rep(i,len(x)){cout << x[i].first << ' ' << x[i].second << '\n';}}
void write(vvpll x){rep(i,len(x))rep(j,len(x[i])){cout << x[i][j].first << ' ' << x[i][j].second;if(j!=len(x[i])-1){cout << " ";}else{cout << '\n';}}}

template <typename T>
T sum(const std::vector<T>& v) {
    return std::accumulate(v.begin(), v.end(), T(0));
}

template<class T> bool chmin(T& a, const T& b){ if(a > b){ a = b; return 1; } return 0; }
template<class T> bool chmax(T& a, const T& b){ if(a < b){ a = b; return 1; } return 0; }
template<class T, class U> bool chmin(T& a, const U& b){ if(a > T(b)){ a = b; return 1; } return 0; }
template<class T, class U> bool chmax(T& a, const U& b){ if(a < T(b)){ a = b; return 1; } return 0; }

#include<atcoder/convolution>
#include<atcoder/modint>
using namespace atcoder;
using mint = modint998244353;

class Comb {
public:
    vector<ll> fact, fact_inv;
    ll mod;

    Comb(int n, ll mod) : fact(n + 1), fact_inv(n + 1), mod(mod) {
        fact[0] = fact[1] = 1;
        fact_inv[0] = fact_inv[1] = 1;

        for (int i = 2; i <= n; ++i) {
            fact[i] = fact[i - 1] * i % mod;
        }

        int m = min(n, int(mod - 1));
        fact_inv[m] = mod_pow(fact[m], mod - 2);

        for (int i = m - 1; i >= 2; --i) {
            fact_inv[i] = fact_inv[i + 1] * (i + 1) % mod;
        }
    }

    ll ncr(int n, int r) const {
        if (n < r || r < 0) return 0;
        return fact[n] * fact_inv[r] % mod * fact_inv[n - r] % mod;
    }

    ll nhr(int n, int r) const {
        return ncr(n + r - 1, r);
    }

private:
    ll mod_pow(ll x, ll y) const {
        ll res = 1;
        while (y > 0) {
            if (y & 1) res = res * x % mod;
            x = x * x % mod;
            y >>= 1;
        }
        return res;
    }
};

int main(){
	ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
    while(1){
        STR(s);
        if(s == "#"){break;}
        string t =  s;
        reverse(all(t));
        if(s == t){
            print(0);
            continue;
        }
        string a,b;
        rep(i,len(s)){
            if(i == len(s)/2 && len(s) % 2 == 1){continue;}
            if(i < len(s)/2){
                a += s[i];
            }
            if(i >= len(s)/2){
                b += s[i];
            }
        }
        reverse(all(a));
        ll ans = 0;
        auto f = [&](string x,string y){
            reverse(all(y));
            return x == y;
        };
        //print(a,b);
        string x,y;
        rep(i,len(b)){
            x += a[i];
            y += b[i];
            if(f(x,y)){
                ans += (len(y) == 1?0:len(y) * len(y));
                x.clear();
                y.clear();
            }
        }
        if(x.empty()){
            print(ans);
        }
        else{
            print(-1);
        }
    }
}
accuracy: 1
time_ms: 80
memory_kb: 3840
final_rank: 10

code_snippet: #line 1 "2021JAGD.cpp"
#include <bits/stdc++.h>
#line 1 "/home/ardririy/repos/cp-libs/libraries-cpp/input.hpp"


#line 6 "/home/ardririy/repos/cp-libs/libraries-cpp/input.hpp"
using namespace std;
vector<long long> i64_vec_IN(int n) {vector<long long> res(n); for(int i=0; i<n; i++) { cin >> res[i]; } return res; }
vector<string> str_vec_IN(int n) { vector<string> res(n); for(int i=0; i<n; i++) { cin >> res[i]; } return res; }
vector<vector<int>> graph_IN(int n, int m) { vector<vector<int>> g(n); int u, v; for(int i=0; i<m; i++) { cin >> u >> v; u--; v--; g[u].emplace_back(v); g[v].emplace_back(u); } return g; }
vector<vector<pair<int, long long>>> weighted_graph_IN(int n, int m) { vector<vector<pair<int, long long>>> g(n); int u, v; long long w; for(int i=0; i<m; i++) { cin >> u >> v >> w; u--; v--; g[u].push_back({v, w}); g[v].push_back({u, w}); } return g; }


#line 3 "2021JAGD.cpp"

using namespace std;

// using namespace atcoder;

#ifdef ADRY
#include <dbg.h>
#else
// DO NOTHING
#define dbg(...)
#endif


#define all(v) v.begin(),v.end()
#define resort(v) sort(v.rbegin(),v.rend())
using ll = long long;
using ull = unsigned long long;
using vll=vector<ll>;
using vvll = vector<vector<ll>>;
using P = pair<ll,ll>;
using vp=vector<pair<ll, ll>>;
using djks=priority_queue<P, vp, greater<P>>;

const int inf=1ll<<30;
#define mod10 (ll)1e9+7
#define mod99 (ll)998244353
const double PI = acos(-1);

#define rep(i,n) for (ll i=0;i<(n);++i)
#define per(i,n) for(ll i=(n)-1;i>=0;--i)
#define rep2(i,a,n) for (ll i=(a);i<(n);++i)
#define per2(i,a,n) for (ll i=(n)-1;i>=(a);--i)


template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return true; } return false; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return true; } return false; }

ll dx[] = {1, 0, -1, 0, -1, 1, -1, 1};
ll dy[] = {0, 1, 0, -1, -1, 1, 1, -1};

class RollingHash {
    static constexpr std::uint64_t MOD = (1ULL << 61) - 1;
    static inline std::uint64_t mod_add(std::uint64_t a, std::uint64_t b) {
        std::uint64_t z = a + b;
        if (z >= MOD) z -= MOD;
        return z;
    }
    static inline std::uint64_t mod_mul(__uint128_t a, __uint128_t b) {
        __uint128_t z = a * b;
        z = (z >> 61) + (z & MOD);
        if (z >= MOD) z -= MOD;
        return static_cast<std::uint64_t>(z);
    }

    static std::uint64_t generate_base() {
        static std::mt19937 rng(std::random_device{}());
        std::uniform_int_distribution<std::uint64_t> dist(2, MOD - 2);
        return dist(rng);
    }

    std::uint64_t base;
    std::vector<std::uint64_t> pow;
    std::vector<std::uint64_t> pref;

public:
    explicit RollingHash(const std::string& s,
                         std::uint64_t base_ = 0)
        : base(base_ ? base_ : generate_base()) {

        if (base <= 1 || base >= MOD)
            throw std::invalid_argument("RollingHash: invalid base");

        std::size_t n = s.size();
        pow.resize(n + 1, 1);
        pref.resize(n + 1, 0);

        for (std::size_t i = 0; i < n; ++i) {
            pow[i + 1]  = mod_mul(pow[i], base);
            std::uint64_t c = static_cast<unsigned char>(s[i]) + 1; // +1 で '\0' 回避
            pref[i + 1] = mod_add(mod_mul(pref[i], base), c);
        }
    }

    std::uint64_t hash(std::size_t l, std::size_t r) const {
        std::uint64_t res = pref[r]
            + MOD
            - mod_mul(pref[l], pow[r - l]);
        if (res >= MOD) res -= MOD;
        return res;
    }

    static std::size_t lcp(const RollingHash& a, std::size_t i,
                           const RollingHash& b, std::size_t j,
                           std::size_t max_len) {
        if (a.base != b.base) throw std::invalid_argument("RollingHash::lcp: base mismatch");

        std::size_t low = 0, high = max_len + 1;
        while (high - low > 1) {
            std::size_t mid = (low + high) >> 1;
            if (a.hash(i, i + mid) == b.hash(j, j + mid))
                low = mid;
            else
                high = mid;
        }
        return low;
    }

    std::uint64_t get_base() const noexcept { return base; }
    static constexpr std::uint64_t mod() noexcept { return MOD; }
};


int solve(){
    string s; cin >> s;
    if(s=="#") return 1;
    int n = s.size();
    int m = s.size() / 2;
    string s1 = "";
    string s2 = "";
    rep(i,m) s1 += s[i];
    rep(i,m) s2 += s[m+n%2+i];
    dbg(s1,s2);

    RollingHash hash1(s1), hash2(s2, hash1.get_base());
    vector<ll> dp(m+1,inf);
    dp[0] = 0;
    rep(i,m) {
        if(dp[i]==inf) continue;
        rep2(x,1,m-i+1) {
            if(hash1.hash(m-x-i,m-i) == hash2.hash(i,i+x)) {
                dbg(i,x);
                chmin(dp[i+x], dp[i] + ((x==1)?0:x*x));
            }
        }
    }
    cout << ((dp[m] == inf)?-1:dp[m]) << '\n';
    return 0;
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    while(!solve());
}
accuracy: 1
time_ms: 4120
memory_kb: 3676
final_rank: 14

code_snippet: #pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#ifdef LOCAL_JUDGE
#define _GLIBCXX_DEBUG
#endif
#include <stdio.h>
#include <iostream> // cout, endl, cin
#include <string> // string, to_string, stoi
#include <vector> // vector
#include <algorithm> // min, max, swap, sort, reverse, lower_bound, upper_bound
#include <utility> // pair, make_pair
#include <tuple> // tuple, make_tuple
#include <cstdint> // int64_t, int*_t
#include <iomanip> //setprecision
#include <map> // map
#include <unordered_map> //unordered_map
#include <queue> // queue, priority_queue
#include <set> // set,multiset
#include <stack> // stack
#include <deque> // deque
#include <math.h>//pow,,,
#include <cmath>//abs,,,
#include <bitset> // bitset
#include <numeric> //accumulate,,,
#include <sstream>
#include <initializer_list>
#include <random>
#include <unordered_set>
#include <time.h>
#include <stdio.h>
#include <string.h>
#include <functional>
#include <climits>
#include <utility>
#include <cassert>
//#include <atcoder/all> // aclibraryを使う際は g++ a.cpp -O2 -std=c++17 -I . でコンパイルする
//using namespace atcoder;
using namespace std;
const long long INF = 4000000000000000001; // 4*10^18
const int inf = 2001001001;
const long long MOD = 998244353;
const double pi = 3.141592653589;
const vector<int> dh = {1,0,-1,0} , dw = {0,1,0,-1};
const vector<int> dh8 = {-1,-1,-1,0,0,1,1,1} , dw8 = {-1,0,1,-1,1,-1,0,1};
#define endl "\n";
long long modpow(long long a, long long n, long long mod) {
    a %= mod;
    long long ret = 1;
    while (n > 0) {
        if (n & 1) ret = ret * a % mod;
        a = a * a % mod;
        n >>= 1;
    }
    return ret % mod;
}
long long modinv(long long a, long long m) {
    long long b = m, u = 1, v = 0;
    while (b) {
        long long t = a / b;
        a -= t * b; swap(a, b);
        u -= t * v; swap(u, v);
    }
    u %= m; 
    if (u < 0) u += m;
    return u;
}
long long gcd(long long a, long long b) {
    if (b == 0) return a; else return gcd(b, a % b);
}
long long lcm(long long a, long long b) {
    return a / gcd(a, b) * b ;
}
long long get_mod(long long res){
    if(res < 0) res += MOD;
    return res % MOD;
}
double DegToRad(double deg){
    return deg*(pi/180.0);
}
double RadToDeg(double rad){
    return rad/(pi/180.0);
}
int uniform_rand(int mini , int maxi){
    random_device seed;
    mt19937_64 engine(seed());
    uniform_real_distribution<> ran(mini , maxi+1);
    int ret = ran(engine);
    if(ret >= maxi+1) ret = maxi;
    return ret;
}



int main() {
    ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    // FILE* in = freopen("mojain/in1.txt" , "r" , stdin); //2つ以上のケースを試したい場合はファイル名をループ回してin2.txt等で指定していく
    // FILE* out = freopen("mojaout/out1.txt", "w", stdout);
    // ifstream ifs("in.txt"); // 巨大ケースは in.txt に書いてifsで標準入力

    while(true){
        string S;cin >> S;
        if(S == "#"){
            break;
        } 

        string former = S.substr(0,S.size()/2);
        string latter = (S.size() % 2 == 0 ? S.substr(S.size()/2 , S.size()/2) : S.substr(S.size()/2+1 , S.size()/2));
        //cout << former << " " << latter << endl;

        reverse(former.begin(),former.end());

        int ans = 0;
        string nowf = "" , nowl = "";
        for(int i = 0;i<S.size()/2;i++){
            nowf += former.at(i);
            nowl += latter.at(i);
            reverse(nowl.begin(),nowl.end());
            if(nowf == nowl){
                if(nowl.size() != 1){
                    ans += (nowl.size())*(nowl.size());
                }
                nowl = ""; nowf = "";
                continue;
            }
            reverse(nowl.begin(),nowl.end());
        }

        if(nowf == ""){
            cout << ans << endl;
        }
        else{
            cout << -1 << endl;
        }


    }

    

    
    

    

    

}
accuracy: 1
time_ms: 10
memory_kb: 3292
final_rank: 1

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

#include <unistd.h>

namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf


uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
    char num[10000][4];
    constexpr Pre() : num() {
        for (int i = 0; i < 10000; i++) {
            int n = i;
            for (int j = 3; j >= 0; j--) {
                num[i][j] = n % 10 | '0';
                n /= 10;
            }
        }
    }
} constexpr pre;

inline void load() {
    memmove(ibuf, ibuf + pil, pir - pil);
    pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
    pil = 0;
    if (pir < SZ)
        ibuf[pir++] = '\n';
}

inline void flush() {
    fwrite(obuf, 1, por, stdout);
    por = 0;
}

void rd(char &c) {
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
}

void rd(string &x) {
    x.clear();
    char c;
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
    do {
        x += c;
        if (pil == pir)
            load();
        c = ibuf[pil++];
    } while (!isspace(c));
}

template <typename T> void rd_real(T &x) {
    string s;
    rd(s);
    x = stod(s);
}

template <typename T> void rd_integer(T &x) {
    if (pil + 100 > pir)
        load();
    char c;
    do
        c = ibuf[pil++];
    while (c < '-');
    bool minus = 0;
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (c == '-') {
            minus = 1, c = ibuf[pil++];
        }
    }
    x = 0;
    while ('0' <= c) {
        x = x * 10 + (c & 15), c = ibuf[pil++];
    }
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (minus)
            x = -x;
    }
}

void rd(int &x) {
    rd_integer(x);
}
void rd(ll &x) {
    rd_integer(x);
}
void rd(i128 &x) {
    rd_integer(x);
}
void rd(uint &x) {
    rd_integer(x);
}
void rd(ull &x) {
    rd_integer(x);
}
void rd(u128 &x) {
    rd_integer(x);
}
void rd(double &x) {
    rd_real(x);
}
void rd(long double &x) {
    rd_real(x);
}

template <class T, class U> void rd(pair<T, U> &p) {
    return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T> void rd_tuple(T &t) {
    if constexpr (N < std::tuple_size<T>::value) {
        auto &x = std::get<N>(t);
        rd(x);
        rd_tuple<N + 1>(t);
    }
}
template <class... T> void rd(tuple<T...> &tpl) {
    rd_tuple(tpl);
}

template <size_t N = 0, typename T> void rd(array<T, N> &x) {
    for (auto &d : x)
        rd(d);
}
template <class T> void rd(vector<T> &x) {
    for (auto &d : x)
        rd(d);
}

void read() {}
template <class H, class... T> void read(H &h, T &...t) {
    rd(h), read(t...);
}

void wt(const char c) {
    if (por == SZ)
        flush();
    obuf[por++] = c;
}
void wt(const string s) {
    for (char c : s)
        wt(c);
}
void wt(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++)
        wt(s[i]);
}

template <typename T> void wt_integer(T x) {
    if (por > SZ - 100)
        flush();
    if (x < 0) {
        obuf[por++] = '-', x = -x;
    }
    int outi;
    for (outi = 96; x >= 10000; outi -= 4) {
        memcpy(out + outi, pre.num[x % 10000], 4);
        x /= 10000;
    }
    if (x >= 1000) {
        memcpy(obuf + por, pre.num[x], 4);
        por += 4;
    } else if (x >= 100) {
        memcpy(obuf + por, pre.num[x] + 1, 3);
        por += 3;
    } else if (x >= 10) {
        int q = (x * 103) >> 10;
        obuf[por] = q | '0';
        obuf[por + 1] = (x - q * 10) | '0';
        por += 2;
    } else
        obuf[por++] = x | '0';
    memcpy(obuf + por, out + outi + 4, 96 - outi);
    por += 96 - outi;
}

template <typename T> void wt_real(T x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << double(x);
    string s = oss.str();
    wt(s);
}

void wt(int x) {
    wt_integer(x);
}
void wt(ll x) {
    wt_integer(x);
}
void wt(i128 x) {
    wt_integer(x);
}
void wt(uint x) {
    wt_integer(x);
}
void wt(ull x) {
    wt_integer(x);
}
void wt(u128 x) {
    wt_integer(x);
}
void wt(double x) {
    wt_real(x);
}
void wt(long double x) {
    wt_real(x);
}

template <class T, class U> void wt(const pair<T, U> val) {
    wt(val.first);
    wt(' ');
    wt(val.second);
}
template <size_t N = 0, typename T> void wt_tuple(const T t) {
    if constexpr (N < std::tuple_size<T>::value) {
        if constexpr (N > 0) {
            wt(' ');
        }
        const auto x = std::get<N>(t);
        wt(x);
        wt_tuple<N + 1>(t);
    }
}
template <class... T> void wt(tuple<T...> tpl) {
    wt_tuple(tpl);
}
template <class T, size_t S> void wt(const array<T, S> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}
template <class T> void wt(const vector<T> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}

void print() {
    wt('\n');
}
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    wt(head);
    if (sizeof...(Tail))
        wt(' ');
    print(forward<Tail>(tail)...);
}
void __attribute__((destructor)) _d() {
    flush();
}
} // namespace fastio


using fastio::flush;
using fastio::print;
using fastio::read;

inline void first(bool i = true) {
    print(i ? "first" : "second");
}
inline void Alice(bool i = true) {
    print(i ? "Alice" : "Bob");
}
inline void Takahashi(bool i = true) {
    print(i ? "Takahashi" : "Aoki");
}
inline void yes(bool i = true) {
    print(i ? "yes" : "no");
}
inline void Yes(bool i = true) {
    print(i ? "Yes" : "No");
}
inline void No() {
    print("No");
}
inline void YES(bool i = true) {
    print(i ? "YES" : "NO");
}
inline void NO() {
    print("NO");
}
inline void Yay(bool i = true) {
    print(i ? "Yay!" : ":(");
}
inline void Possible(bool i = true) {
    print(i ? "Possible" : "Impossible");
}
inline void POSSIBLE(bool i = true) {
    print(i ? "POSSIBLE" : "IMPOSSIBLE");
}

/**
 * @brief Fast IO
 */

template <unsigned mod = 1000000007> struct fp {
    unsigned v;
    static constexpr int get_mod() {
        return mod;
    }
    constexpr unsigned inv() const {
        assert(v != 0);
        int x = v, y = mod, p = 1, q = 0, t = 0, tmp = 0;
        while (y > 0) {
            t = x / y;
            x -= t * y, p -= t * q;
            tmp = x, x = y, y = tmp;
            tmp = p, p = q, q = tmp;
        }
        if (p < 0)
            p += mod;
        return p;
    }
    constexpr fp(ll x = 0) : v(x >= 0 ? x % mod : (mod - (-x) % mod) % mod) {}
    fp operator-() const {
        return fp() - *this;
    }
    fp pow(ull t) {
        fp res = 1, b = *this;
        while (t) {
            if (t & 1)
                res *= b;
            b *= b;
            t >>= 1;
        }
        return res;
    }
    fp &operator+=(const fp &x) {
        if ((v += x.v) >= mod)
            v -= mod;
        return *this;
    }
    fp &operator-=(const fp &x) {
        if ((v += mod - x.v) >= mod)
            v -= mod;
        return *this;
    }
    fp &operator*=(const fp &x) {
        v = ull(v) * x.v % mod;
        return *this;
    }
    fp &operator/=(const fp &x) {
        v = ull(v) * x.inv() % mod;
        return *this;
    }
    fp operator+(const fp &x) const {
        return fp(*this) += x;
    }
    fp operator-(const fp &x) const {
        return fp(*this) -= x;
    }
    fp operator*(const fp &x) const {
        return fp(*this) *= x;
    }
    fp operator/(const fp &x) const {
        return fp(*this) /= x;
    }
    bool operator==(const fp &x) const {
        return v == x.v;
    }
    bool operator!=(const fp &x) const {
        return v != x.v;
    }
    friend istream &operator>>(istream &is, fp &x) {
        return is >> x.v;
    }
    friend ostream &operator<<(ostream &os, const fp &x) {
        return os << x.v;
    }
};

template <unsigned mod> void rd(fp<mod> &x) {
    fastio::rd(x.v);
}
template <unsigned mod> void wt(fp<mod> x) {
    fastio::wt(x.v);
}

template <typename T> T Inv(ll n) {
    static const int md = T::get_mod();
    static vector<T> buf({0, 1});
    assert(n > 0);
    n %= md;
    while (SZ(buf) <= n) {
        int k = SZ(buf), q = (md + k - 1) / k;
        buf.push_back(buf[k * q - md] * q);
    }
    return buf[n];
}

template <typename T> T Fact(ll n, bool inv = 0) {
    static const int md = T::get_mod();
    static vector<T> buf({1, 1}), ibuf({1, 1});
    assert(n >= 0 and n < md);
    while (SZ(buf) <= n) {
        buf.push_back(buf.back() * SZ(buf));
        ibuf.push_back(ibuf.back() * Inv<T>(SZ(ibuf)));
    }
    return inv ? ibuf[n] : buf[n];
}

template <typename T> T nPr(int n, int r, bool inv = 0) {
    if (n < 0 || n < r || r < 0)
        return 0;
    return Fact<T>(n, inv) * Fact<T>(n - r, inv ^ 1);
}
template <typename T> T nCr(int n, int r, bool inv = 0) {
    if (n < 0 || n < r || r < 0)
        return 0;
    return Fact<T>(n, inv) * Fact<T>(r, inv ^ 1) * Fact<T>(n - r, inv ^ 1);
}
template <typename T> T nHr(int n, int r, bool inv = 0) {
    return nCr<T>(n + r - 1, r, inv);
}

/**
 * @brief Modint
 */

int main() {
while(1) {
    string S;
    cin >> S;
    if (S == "#") return 0;
    int N = S.size();
    int M = N / 2;
    string T, U;
    T = S.substr(0,M), U = S.substr(N-M,M);
    int Cur = 0, ANS = 0;
    rep(i,1,M+1) {
        if (T.substr(Cur, i-Cur) == U.substr(M-i, i-Cur)) {
            if (i - Cur != 1) ANS += (i - Cur) * (i - Cur);
            Cur = i;
        }
    }
    if (Cur != M) cout << -1 << endl;
    else cout << ANS << endl;
}
}
accuracy: 1
time_ms: 10
memory_kb: 3584
final_rank: 5

code_snippet: #include <bits/stdc++.h>

#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("sse4.2,avx,avx2,tune=native")

using ll = long long;

template <typename T, size_t Size>
std::ostream& operator<<(
    std::ostream& stream, const std::array<T, Size>& values
) {
    bool first = true;
    for (const auto& i : values) {
        if (first) {
            first = false;
        } else {
            stream << ' ';
        }
        stream << i;
    }
    return stream;
}

template <typename T, typename U, T MOD> class ModInt {
public:
    constexpr ModInt() : rep(0) {}
    constexpr ModInt(const T value) : rep(value) {}

    ModInt& operator+=(const ModInt& other) {
        rep = (rep + other.rep) % MOD;
        return *this;
    }
    ModInt& operator*=(const ModInt& other) {
        rep = ((U)rep * other.rep) % MOD;
        return *this;
    }
    ModInt& operator-=(const ModInt& other) {
        rep = ((rep - other.rep) % MOD + MOD) % MOD;
        return *this;
    }
    ModInt& operator/=(const ModInt& other) {
        return *this *= other.inv();
    }

    ModInt operator+(const ModInt& other) const {
        ModInt copy = *this;
        copy += other;
        return copy;
    }
    ModInt operator-(const ModInt& other) const {
        ModInt copy = *this;
        copy -= other;
        return copy;
    }
    ModInt operator*(const ModInt& other) const {
        ModInt copy = *this;
        copy *= other;
        return copy;
    }
    ModInt operator/(const ModInt& other) const {
        ModInt copy = *this;
        copy /= other;
        return copy;
    }

    ModInt pow(const ll exp) const {
        if (exp == 0) {
            return 1;
        }
        if (exp % 2 == 1) {
            return *this * pow(exp - 1);
        }
        const auto temp = pow(exp / 2);
        return temp * temp;
    }

    ModInt inv() const {
        return pow(MOD - 2);
    }

    bool operator==(const ModInt& other) const {
        return rep == other.rep;
    }

    friend std::istream& operator>>(std::istream& stream, ModInt& value) {
        stream >> value.rep;
        return stream;
    }

    friend std::ostream& operator<<(std::ostream& stream, const ModInt& value) {
        stream << value.rep;
        return stream;
    }

private:
    T rep;
};

using ModIntMersenne = ModInt<int, ll, 1000000007>;

using namespace std;

inline constexpr int MUL_MIN = 1e3;
inline constexpr int MUL_MAX = 1e7;

template <typename ModInt, size_t MaxLen>
auto precompute_mul_pows(const ModInt mul) {
    std::array<ModInt, MaxLen + 1> prec_pow;
    prec_pow[0] = 1;
    for (size_t i = 1; i <= MaxLen; ++i) {
        prec_pow[i] = prec_pow[i - 1] * mul;
    }
    return prec_pow;
}

template <typename ModInt> using MulPowFunc = ModInt (*)(ll);

template <typename ModInt, MulPowFunc<ModInt>... MulPow> class RollingHash {
public:
    RollingHash() : len(0), hash{} {}
    RollingHash(const char c) : len(1) {
        std::fill(std::begin(hash), std::end(hash), c);
    }
    RollingHash(const string& s) : len(0), hash{} {
        for (const auto& i : s) {
            *this += i;
        }
    }

    RollingHash& operator+=(const RollingHash& other) {
        size_t i = 0;
        ((hash[i] = hash[i] * MulPow(other.len) + other.hash[i], ++i), ...);
        len += other.len;
        return *this;
    }

    RollingHash& operator-=(const RollingHash& other) {
        size_t i = 0;
        ((hash[i] -= other.hash[i] * MulPow(len - other.len), ++i), ...);
        len -= other.len;
        return *this;
    }

    RollingHash operator+(const RollingHash& other) const {
        RollingHash copy = *this;
        copy += other;
        return copy;
    }

    RollingHash operator-(const RollingHash& other) const {
        RollingHash copy = *this;
        copy -= other;
        return copy;
    }

    bool operator==(const RollingHash& other) const {
        return len == other.len && hash == other.hash;
    }

    friend std::ostream& operator<<(
        std::ostream& stream, const RollingHash& h
    ) {
        stream << '(' << h.len << " | " << h.hash << ')';
        return stream;
    }

private:
    ll len;
    std::array<ModInt, sizeof...(MulPow)> hash;
};

#define UsingHashHelper(ModInt, MaxN, Index)                            \
    const auto HASH_MUL##Index = rand_int(MUL_MIN, MUL_MAX);            \
    const auto HASH_MUL_POW##Index = precompute_mul_pows<ModInt, MaxN>( \
        HASH_MUL##Index                                                 \
    );                                                                  \
    ModInt hash_pow_mul##Index(const ll exp) {                          \
        return HASH_MUL_POW##Index[exp];                                \
    }

#define UsingHash(TargetTypeName, ModInt, MaxN) \
    UsingHashHelper(ModInt, MaxN, 0);           \
    using TargetTypeName = RollingHash<ModInt, hash_pow_mul0>;

constexpr int MAX_N = 2e4;
constexpr int INF = 1e9;

static std::mt19937_64 rng64(
    std::chrono::steady_clock::now().time_since_epoch().count()
);

template <typename T> T rand_int(const T lo, const T hi) {
    return std::uniform_int_distribution<T>(lo, hi)(rng64);
}

UsingHash(Hash, ModIntMersenne, MAX_N);

Hash pref_fwd[MAX_N + 1];

Hash get_hash(int l, int r) {
    return pref_fwd[r + 1] - pref_fwd[l];
}

int dp[MAX_N + 1];

ll piyo(const string& s) {
    const int n = s.length();

    for (int i = 1; i <= n; ++i) {
        pref_fwd[i] = pref_fwd[i - 1] + s[i - 1];
    }

    const int start_left = n / 2 - 1;
    const int start_right = (n + 1) / 2;
    const int dp_range = n - start_right;

    fill_n(dp, dp_range + 1, INF);
    dp[0] = 0;
    for (int i = 0; i < dp_range; ++i) {
        if (dp[i] >= INF) {
            continue;
        }
        const auto left = start_left - i;
        if (s[left] == s[i + start_right]) {
            dp[i + 1] = min(dp[i + 1], dp[i]);
        }
        for (int j = 1; i + j < dp_range; ++j) {
            if (get_hash(i + start_right, i + start_right + j)
                == get_hash(left - j, left)) {
                int add = (j + 1) * (j + 1);
                dp[i + j + 1] = min(dp[i + j + 1], dp[i] + add);
            }
        }
    }
    if (dp[dp_range] < INF) {
        return dp[dp_range];
    }
    return -1;
}

int main() {
    while (true) {
        string s;
        cin >> s;
        if (s == "#") {
            break;
        }
        cout << piyo(s) << '\n';
    }
}
accuracy: 1
time_ms: 3890
memory_kb: 3936
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define all(x) (x).begin(),(x).end()
#define rall(x) (x).rbegin(),(x).rend()
using ll = long long;
typedef pair<int, int> P;
#define EPS (1e-12)
// const int MOD=1e9+7;
// const int vx[]={0,1,0,-1},vy[]={1,0,-1,0};
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return 1; } return 0; }


using ull=unsigned long long;using i128=__int128_t;
template<ull RBASE=0xdeadbeef>
struct RollingHash{
    inline static vector<ull>RPOW{1};
    static const ull MOD=(1UL<<61)-1;
    static ull resolve(ull v){return v>=MOD?v-MOD:v;}
    static ull mul(i128 a,i128 b){
        i128 t=a*b;return resolve((t>>61)+ (t&MOD));
    }
    vector<ull>h;
    RollingHash(){}
    RollingHash(const vector<ull>&v){
        while(RPOW.size()<=v.size())
            RPOW.emplace_back(mul(RPOW.back(),RBASE));
        h.resize(v.size()+1,0);
        for(int i=0;i<v.size();++i)
            h[i+1]=resolve(mul(h[i],RBASE)+v[i]+1);
    }
    RollingHash(string&s):RollingHash({s.begin(),s.end()}){}
    ull hash(int l,int r){
        return resolve(MOD+h[r]-mul(h[l],RPOW[r-l]));
    }
    static ull join(ull l,ull r,int rlen){
        return resolve(mul(l,RPOW[rlen])+r);
    }
};


int main(){
    while(1) {
        string s;
        cin >> s;
        if(s[0] == '#') break;
        int n = s.size();
        RollingHash d(s);
        reverse(all(s));
        RollingHash rd(s);
        int now = (n + 1) / 2;
        ll ans = 0;
        for(int i = (n + 1) / 2; i < n; i++) {
            if(d.hash(now, i + 1) == d.hash(n - i - 1, n - now - 1 + 1)) {
                if(i - now + 1 > 1) ans += (i - now + 1) * (i - now + 1);
                now = i + 1;
            }
        }
        if(now < n) {
            cout << -1 << endl;
        }
        else {
            cout << ans << endl;
        }
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3780
final_rank: 8

code_snippet: // #include "my_template.hpp"
// #include "string/rolling_hash.hpp"
// RollingHash<mint261> rh(20000);
// using namespace std;
// 
// void solve(string S) {
//     int N = LEN(S) / 2;
//     string S0 = S.substr(0, N);
//     string S1 = S.substr(N + LEN(S) % 2, N);
//     auto hs0 = rh.build(S0);
//     auto hs1 = rh.build(S1);
//     // dp[r] = S0[0, r) が回分になっているような最小コスト
//     vector<i64> dp(N + 1, INF<i64>);
//     dp[0] = 0;
//     REP(l, N) {
//         if (dp[l] == INF<i64>) continue;
//         REP(r, l + 1, N + 1) {
//             if (rh.prod(hs0, l, r) == rh.prod(hs1, N - r, N - l)) {
//                 i64 cost = (r - l) * (r - l);
//                 if (cost == 1) cost = 0;
//                 chmin(dp[r], dp[l] + cost);
//             }
//         }
//     }
//     i64 ans = dp[N];
//     if (ans == INF<i64>) ans = -1;
//     print(ans);
//     return;
// }
// 
// int main() {
//     string S;
//     while (cin >> S, S != "#") solve(S);
//     return 0;
// }
#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <chrono>
#include <cmath>
#include <complex>
#include <deque>
#include <forward_list>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <memory>
#include <numeric>
#include <optional>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <tuple>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

#ifdef RUTHEN_LOCAL
#include <debug.hpp>
#else
#define show(x) true
#endif

// type definition
using i64 = long long;
using u32 = unsigned int;
using u64 = unsigned long long;
using f32 = float;
using f64 = double;
using f128 = long double;
template <class T> using pque = std::priority_queue<T>;
template <class T> using pqueg = std::priority_queue<T, std::vector<T>, std::greater<T>>;
// overload
#define overload4(_1, _2, _3, _4, name, ...) name
#define overload3(_1, _2, _3, name, ...) name
#define overload2(_1, _2, name, ...) name
// for loop
#define REP1(a) for (long long _ = 0; _ < (a); _++)
#define REP2(i, a) for (long long i = 0; i < (a); i++)
#define REP3(i, a, b) for (long long i = (a); i < (b); i++)
#define REP4(i, a, b, c) for (long long i = (a); i < (b); i += (c))
#define REP(...) overload4(__VA_ARGS__, REP4, REP3, REP2, REP1)(__VA_ARGS__)
#define RREP1(a) for (long long _ = (a)-1; _ >= 0; _--)
#define RREP2(i, a) for (long long i = (a)-1; i >= 0; i--)
#define RREP3(i, a, b) for (long long i = (b)-1; i >= (a); i--)
#define RREP(...) overload3(__VA_ARGS__, RREP3, RREP2, RREP1)(__VA_ARGS__)
#define FORE1(x, a) for (auto &&x : a)
#define FORE2(x, y, a) for (auto &&[x, y] : a)
#define FORE3(x, y, z, a) for (auto &&[x, y, z] : a)
#define FORE(...) overload4(__VA_ARGS__, FORE3, FORE2, FORE1)(__VA_ARGS__)
#define FORSUB(t, s) for (long long t = (s); t >= 0; t = (t == 0 ? -1 : (t - 1) & (s)))
// function
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define SORT(a) std::sort((a).begin(), (a).end())
#define RSORT(a) std::sort((a).rbegin(), (a).rend())
#define REV(a) std::reverse((a).begin(), (a).end())
#define UNIQUE(a)                      \
    std::sort((a).begin(), (a).end()); \
    (a).erase(std::unique((a).begin(), (a).end()), (a).end())
#define LEN(a) (int)((a).size())
#define MIN(a) *std::min_element((a).begin(), (a).end())
#define MAX(a) *std::max_element((a).begin(), (a).end())
#define SUM1(a) std::accumulate((a).begin(), (a).end(), 0LL)
#define SUM2(a, x) std::accumulate((a).begin(), (a).end(), (x))
#define SUM(...) overload2(__VA_ARGS__, SUM2, SUM1)(__VA_ARGS__)
#define LB(a, x) std::distance((a).begin(), std::lower_bound((a).begin(), (a).end(), (x)))
#define UB(a, x) std::distance((a).begin(), std::upper_bound((a).begin(), (a).end(), (x)))
template <class T, class U> inline bool chmin(T &a, const U &b) { return (a > T(b) ? a = b, 1 : 0); }
template <class T, class U> inline bool chmax(T &a, const U &b) { return (a < T(b) ? a = b, 1 : 0); }
template <class T, class S> inline T floor(const T x, const S y) {
    assert(y);
    return (y < 0 ? floor(-x, -y) : (x > 0 ? x / y : x / y - (x % y == 0 ? 0 : 1)));
}
template <class T, class S> inline T ceil(const T x, const S y) {
    assert(y);
    return (y < 0 ? ceil(-x, -y) : (x > 0 ? (x + y - 1) / y : x / y));
}
template <class T, class S> std::pair<T, T> inline divmod(const T x, const S y) {
    T q = floor(x, y);
    return {q, x - q * y};
}
// 10 ^ n
constexpr long long TEN(int n) { return (n == 0) ? 1 : 10LL * TEN(n - 1); }
// 1 + 2 + ... + n
#define TRI1(n) ((n) * ((n) + 1LL) / 2)
// l + (l + 1) + ... + r
#define TRI2(l, r) (((l) + (r)) * ((r) - (l) + 1LL) / 2)
#define TRI(...) overload2(__VA_ARGS__, TRI2, TRI1)(__VA_ARGS__)
// bit operation
// bit[i] (= 0 or 1)
#define IBIT(bit, i) (((bit) >> (i)) & 1)
// (0, 1, 2, 3, 4) -> (0, 1, 3, 7, 15)
#define MASK(n) ((1LL << (n)) - 1)
#define POW2(n) (1LL << (n))
// (0, 1, 2, 3, 4) -> (0, 1, 1, 2, 1)
int popcnt(int x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(i64 x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }
// (0, 1, 2, 3, 4) -> (-1, 0, 1, 1, 2)
int topbit(int x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); }
int topbit(u32 x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); }
int topbit(i64 x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); }
int topbit(u64 x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); }
// (0, 1, 2, 3, 4) -> (-1, 0, 1, 0, 2)
int lowbit(int x) { return (x == 0 ? -1 : __builtin_ctz(x)); }
int lowbit(u32 x) { return (x == 0 ? -1 : __builtin_ctz(x)); }
int lowbit(i64 x) { return (x == 0 ? -1 : __builtin_ctzll(x)); }
int lowbit(u64 x) { return (x == 0 ? -1 : __builtin_ctzll(x)); }
// binary search
template <class T, class F> T bin_search(T ok, T ng, F &f) {
    while ((ok > ng ? ok - ng : ng - ok) > 1) {
        T md = (ng + ok) >> 1;
        (f(md) ? ok : ng) = md;
    }
    return ok;
}
template <class T, class F> T bin_search_real(T ok, T ng, F &f, const int iter = 100) {
    for (int _ = 0; _ < iter; _++) {
        T md = (ng + ok) / 2;
        (f(md) ? ok : ng) = md;
    }
    return ok;
}
// rotate matrix counterclockwise by pi / 2
template <class T> void rot(std::vector<std::vector<T>> &a) {
    if ((int)(a.size()) == 0) return;
    if ((int)(a[0].size()) == 0) return;
    int n = (int)(a.size()), m = (int)(a[0].size());
    std::vector res(m, std::vector<T>(n));
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            res[m - 1 - j][i] = a[i][j];
        }
    }
    a.swap(res);
}
// const value
constexpr int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
constexpr int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
// infinity
template <class T> constexpr T INF = 0;
template <> constexpr int INF<int> = 1'000'000'000;                 // 1e9
template <> constexpr i64 INF<i64> = i64(INF<int>) * INF<int> * 2;  // 2e18
template <> constexpr u32 INF<u32> = INF<int>;                      // 1e9
template <> constexpr u64 INF<u64> = INF<i64>;                      // 2e18
template <> constexpr f32 INF<f32> = INF<i64>;                      // 2e18
template <> constexpr f64 INF<f64> = INF<i64>;                      // 2e18
template <> constexpr f128 INF<f128> = INF<i64>;                    // 2e18
// I/O
// input
template <class T> std::istream &operator>>(std::istream &is, std::vector<T> &v) {
    for (auto &&i : v) is >> i;
    return is;
}
template <class... T> void in(T &...a) { (std::cin >> ... >> a); }
void scan() {}
template <class Head, class... Tail> void scan(Head &head, Tail &...tail) {
    in(head);
    scan(tail...);
}
// input macro
#define INT(...)     \
    int __VA_ARGS__; \
    scan(__VA_ARGS__)
#define I64(...)     \
    i64 __VA_ARGS__; \
    scan(__VA_ARGS__)
#define U32(...)     \
    u32 __VA_ARGS__; \
    scan(__VA_ARGS__)
#define U64(...)     \
    u64 __VA_ARGS__; \
    scan(__VA_ARGS__)
#define F32(...)     \
    f32 __VA_ARGS__; \
    scan(__VA_ARGS__)
#define F64(...)     \
    f64 __VA_ARGS__; \
    scan(__VA_ARGS__)
#define F128(...)     \
    f128 __VA_ARGS__; \
    scan(__VA_ARGS__)
#define STR(...)             \
    std::string __VA_ARGS__; \
    scan(__VA_ARGS__)
#define CHR(...)      \
    char __VA_ARGS__; \
    scan(__VA_ARGS__)
#define VEC(type, name, size)     \
    std::vector<type> name(size); \
    scan(name)
#define VEC2(type, name1, name2, size)          \
    std::vector<type> name1(size), name2(size); \
    for (int i = 0; i < size; i++) scan(name1[i], name2[i])
#define VEC3(type, name1, name2, name3, size)                \
    std::vector<type> name1(size), name2(size), name3(size); \
    for (int i = 0; i < size; i++) scan(name1[i], name2[i], name3[i])
#define VEC4(type, name1, name2, name3, name4, size)                      \
    std::vector<type> name1(size), name2(size), name3(size), name4(size); \
    for (int i = 0; i < size; i++) scan(name1[i], name2[i], name3[i], name4[i])
#define VV(type, name, h, w)                       \
    std::vector name((h), std::vector<type>((w))); \
    scan(name)
// output
template <class T> std::ostream &operator<<(std::ostream &os, const std::vector<T> &v) {
    auto n = v.size();
    for (size_t i = 0; i < n; i++) {
        if (i) os << ' ';
        os << v[i];
    }
    return os;
}
template <class... T> void out(const T &...a) { (std::cout << ... << a); }
void print() { out('\n'); }
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    out(head);
    if (sizeof...(Tail)) out(' ');
    print(tail...);
}
// for interactive problems
void printi() { std::cout << std::endl; }
template <class Head, class... Tail> void printi(Head &&head, Tail &&...tail) {
    out(head);
    if (sizeof...(Tail)) out(' ');
    printi(tail...);
}
// bool output
void YES(bool t = 1) { print(t ? "YES" : "NO"); }
void Yes(bool t = 1) { print(t ? "Yes" : "No"); }
void yes(bool t = 1) { print(t ? "yes" : "no"); }
void NO(bool t = 1) { YES(!t); }
void No(bool t = 1) { Yes(!t); }
void no(bool t = 1) { yes(!t); }
void POSSIBLE(bool t = 1) { print(t ? "POSSIBLE" : "IMPOSSIBLE"); }
void Possible(bool t = 1) { print(t ? "Possible" : "Impossible"); }
void possible(bool t = 1) { print(t ? "possible" : "impossible"); }
void IMPOSSIBLE(bool t = 1) { POSSIBLE(!t); }
void Impossible(bool t = 1) { Possible(!t); }
void impossible(bool t = 1) { possible(!t); }
void FIRST(bool t = 1) { print(t ? "FIRST" : "SECOND"); }
void First(bool t = 1) { print(t ? "First" : "Second"); }
void first(bool t = 1) { print(t ? "first" : "second"); }
void SECOND(bool t = 1) { FIRST(!t); }
void Second(bool t = 1) { First(!t); }
void second(bool t = 1) { first(!t); }
// I/O speed up
struct SetUpIO {
    SetUpIO() {
        std::ios::sync_with_stdio(false);
        std::cin.tie(0);
        std::cout << std::fixed << std::setprecision(15);
    }
} set_up_io;

struct Modint261 {
    static constexpr unsigned long long m = (1ULL << 61) - 1;
    using mint = Modint261;
    unsigned long long _v;

    static constexpr long long mod() { return m; }
    static constexpr unsigned long long umod() { return m; }

    Modint261() : _v(0ULL) {}

    template <class T> Modint261(T v) {
        long long x = (long long)(v % (long long)(umod()));
        if (x < 0) x += umod();
        _v = (unsigned long long)(x);
    }

    unsigned long long val() const { return _v; }

    mint &operator++() {
        _v++;
        if (_v == umod()) _v = 0;
        return *this;
    }
    mint &operator--() {
        if (_v == 0) _v = umod();
        _v--;
        return *this;
    }
    mint operator++(int) {
        mint result = *this;
        ++*this;
        return result;
    }
    mint operator--(int) {
        mint result = *this;
        --*this;
        return result;
    }

    mint &operator+=(const mint &rhs) {
        _v += rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint &operator-=(const mint &rhs) {
        _v -= rhs._v;
        if (_v >= umod()) _v += umod();
        return *this;
    }
    mint &operator*=(const mint &rhs) {
        __uint128_t z = _v;
        z *= rhs._v;
        z = (z >> 61) + (z & umod());
        if (z >= umod()) z -= umod();
        _v = (unsigned long long)z;
        return *this;
    }
    mint &operator/=(const mint &rhs) { return (*this *= rhs.inv()); }

    mint operator+() const { return *this; }
    mint operator-() const { return mint() - *this; }

    mint pow(long long n) const {
        assert(n >= 0);
        mint x = *this, r = 1;
        while (n) {
            if (n & 1) r *= x;
            x *= x;
            n >>= 1;
        }
        return r;
    }

    mint inv() const { return pow(umod() - 2); }

    friend mint operator+(const mint &lhs, const mint &rhs) { return mint(lhs) += rhs; }
    friend mint operator-(const mint &lhs, const mint &rhs) { return mint(lhs) -= rhs; }
    friend mint operator*(const mint &lhs, const mint &rhs) { return mint(lhs) *= rhs; }
    friend mint operator/(const mint &lhs, const mint &rhs) { return mint(lhs) /= rhs; }
    friend bool operator==(const mint &lhs, const mint &rhs) { return lhs._v == rhs._v; }
    friend bool operator!=(const mint &lhs, const mint &rhs) { return lhs._v != rhs._v; }
    friend std::ostream &operator<<(std::ostream &os, const mint &v) { return os << v.val(); }
};
using mint261 = Modint261;

template <class Mint> struct RollingHash {
    std::vector<Mint> pwr;
    const Mint base;

    static inline Mint generate_base() {
        std::mt19937_64 mt(std::chrono::steady_clock::now().time_since_epoch().count());
        std::uniform_int_distribution<uint64_t> rand(1, Mint::mod() - 1);
        return Mint(rand(mt));
    }

    void extend() {
        int n = pwr.size();
        int m = n * 2;
        pwr.resize(m);
        for (int i = n; i < m; i++) pwr[i] = pwr[i - 1] * base;
    }

    RollingHash(int N = 0, Mint base = generate_base()) : base(base) {
        pwr.resize(1, Mint(1));
        while (N >= (int)pwr.size()) extend();
    }

    Mint power(int i) {  // return base ^ i
        assert(i >= 0);
        while (i >= (int)pwr.size()) extend();
        return pwr[i];
    }

    std::vector<Mint> build(const std::string &s) const {
        int N = (int)s.size();
        std::vector<Mint> res(N + 1);
        for (int i = 0; i < N; i++) {
            res[i + 1] = res[i] * base + s[i];
        }
        return res;
    }

    template <class T> std::vector<Mint> build(const std::vector<T> &s) const {
        int N = (int)s.size();
        std::vector<Mint> res(N + 1);
        for (int i = 0; i < N; i++) {
            res[i + 1] = res[i] * base + s[i];
        }
        return res;
    }

    Mint prod(const std::vector<Mint> &hs, int l, int r) {
        assert(0 <= l and l <= r and r < hs.size());
        return hs[r] - hs[l] * power(r - l);
    }

    Mint combine(Mint h1, Mint h2, int h2len) { return h1 * power(h2len) + h2; }
};
RollingHash<mint261> rh(20000);
using namespace std;

void solve(string S) {
    int N = LEN(S) / 2;
    string S0 = S.substr(0, N);
    string S1 = S.substr(N + LEN(S) % 2, N);
    auto hs0 = rh.build(S0);
    auto hs1 = rh.build(S1);
    // dp[r] = S0[0, r) が回分になっているような最小コスト
    vector<i64> dp(N + 1, INF<i64>);
    dp[0] = 0;
    REP(l, N) {
        if (dp[l] == INF<i64>) continue;
        REP(r, l + 1, N + 1) {
            if (rh.prod(hs0, l, r) == rh.prod(hs1, N - r, N - l)) {
                i64 cost = (r - l) * (r - l);
                if (cost == 1) cost = 0;
                chmin(dp[r], dp[l] + cost);
            }
        }
    }
    i64 ans = dp[N];
    if (ans == INF<i64>) ans = -1;
    print(ans);
    return;
}

int main() {
    string S;
    while (cin >> S, S != "#") solve(S);
    return 0;
}
accuracy: 1
time_ms: 6420
memory_kb: 3724
final_rank: 20

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long int;
typedef vector<ll> vll;
typedef vector<vll> vvll;
typedef vector<vvll> vvvll;
typedef vector<bool> vb;
typedef vector<string> vs;
typedef pair<ll,ll> pll;
typedef vector<pair<ll,ll>> vp;
#define rep(i,a,n) for(ll i=a;i<n;i++)
#define rrep(i,a,n) for(ll i=n-1;i>=a;i--)
#define mod 998244353
#define all(a) a.begin(),a.end()

int main(){
    while(true){
        string s;
        cin >> s;
        if(s == "#")return 0;
        ll len = s.size();
        string x = s.substr(0,len/2);
        string y = s.substr(len/2);
        if(x.size() != y.size()){
            reverse(all(y));
            y.pop_back();
            reverse(all(y));
        }
        ll ans = 0;
        ll cnt = -1;
        ll pos = 0;
        string xx,yy;
        while(pos < y.size()){
            xx += x[pos];
            yy += y[y.size()-pos-1];
            reverse(all(xx));
            if(xx == yy){
                if(xx.size() != 1)ans += xx.size()*xx.size();
                xx.erase(),yy.erase();
                cnt = pos;
            }
            reverse(all(xx));
            pos++;
        }
        if(cnt != pos-1)ans = -1;
        cout << ans << endl;
    } 
}
accuracy: 1
time_ms: 150
memory_kb: 3324
final_rank: 2

code_snippet: #include<bits/stdc++.h>
using namespace std;
//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
using ll=long long;
#define overload4(_1, _2, _3, _4, name, ...) name
#define rep1(n) for(ll i = 0; i < (n); ++i)
#define rep2(i, n) for(ll i = 0; i < (n); ++i)
#define rep3(i, a, b) for(ll i = (a); i < (b); ++i)
#define rep4(i, a, b, c) for(ll i = (a); i < (b); i += (c))
#define rep(...) overload4(__VA_ARGS__, rep4, rep3, rep2, rep1)(__VA_ARGS__)
#define rrep1(n) for(ll i=n;i--;)
#define rrep2(i,n) for(ll i=n;i--;)
#define rrep3(i,a,b) for(ll i=b;i-->(a);)
#define rrep4(i,a,b,c) for(ll i=(a)+((b)-(a)-1)/(c)*(c);i>=(a);i-=c)
#define rrep(...) overload4(__VA_ARGS__,rrep4,rrep3,rrep2,rrep1)(__VA_ARGS__)
#define all(i) begin(i), end(i)
#define rall(i) (i).rbegin(), (i).rend()
#define Sort(a) sort(all(a))
#define Rev(a) reverse(all(a))
#define elif else if
template<class T> bool chmin(T &a, const T &b){ if(a > b){ a = b; return 1; } else return 0; }
template<class T> bool chmax(T &a, const T &b){ if(a < b){ a = b; return 1; } else return 0; }
template<class T> ll sum(const T& a){ return accumulate(all(a), 0LL); }
template<class T> auto min(const T& a){ return *min_element(all(a)); }
template<class T> auto max(const T& a){ return *max_element(all(a)); }
vector<ll> iota(ll n, ll begin = 0){ vector<ll> a(n); iota(a.begin(), a.end(), begin); return a; }
const int INF =0x3fffffff;
const ll INFll =0x1fffffffffffffff;// 4times ok
const int MOD= int(1e9)+7;
const int MODD=998244353;
using P= pair<int,int>;
using Pl= pair<ll,ll>;
using ld=long double;
using VVl=vector<vector<ll>>;
using VVd=vector<vector<ld>>;
using Vd=vector<ld>;
using tuplis =array<ll, 3>;
using quatro=array<ll,4>;
#define vec(type,name,...) vector<type> name(__VA_ARGS__)
#define vv(type,name,h,...) vector<vector<type>>name(h,vector<type>(__VA_ARGS__))
template<class T> using pq = priority_queue<T, vector<T>, greater<T>>;
const ll four[] = {0, 1, 0, -1, 0};
const ll eight[] = {0, 1, 1, 0, -1, -1, 1, -1, 0};
const ld EPS = 1e-9;
const ld PI = 3.1415926535897932;
ll gcd(ll a, ll b){ while(b){ ll c = b; b = a % b; a = c; } return a; }
ll lcm(ll a, ll b){ if(!a || !b) return 0; return a * b / gcd(a, b); }
ll intpow(ll a, ll b){ ll ans = 1; while(b){ if(b & 1) ans *= a; a *= a; b /= 2; } return ans; }
ll modpow(ll a, ll b, ll p){ a%=p; ll ans = 1; while(b){ if(b & 1) (ans *= a) %= p; (a *= a) %= p; b /= 2; } return ans; }
ll isqr(ll x){ll r=sqrt(x)-1;while((r+1)*(r+1)<=x)r++;return r;}
vector<ll> divisor(ll x){vector<ll> ans; for(ll i = 1; i * i <= x; i++) if(x % i == 0) ans.push_back(i); rrep(ans.size() - (ans.back() * ans.back() == x)) ans.push_back(x / ans[i]); return ans; }
int scan(){ return getchar(); }
void scan(int& a){ scanf("%d", &a); }
void scan(unsigned& a){ scanf("%u", &a); }
void scan(long& a){ scanf("%ld", &a); }
void scan(long long& a){ scanf("%lld", &a); }
void scan(unsigned long long& a){ scanf("%llu", &a); }
void scan(char& a){ do{ a = getchar(); }while(a == ' ' || a == '\n'); }
void scan(float& a){ scanf("%f", &a); }
void scan(double& a){ scanf("%lf", &a); }
void scan(long double& a){ scanf("%Lf", &a); }
void scan(vector<bool>& a){ for(unsigned i = 0; i < a.size(); i++){ int b; scan(b); a[i] = b; } }
void scan(char a[]){ scanf("%s", a); }
void scan(string& a){ cin >> a; }
template<class T> void scan(vector<T>&);
template<class T, size_t size> void scan(array<T, size>&);
template<class T, class L> void scan(pair<T, L>&);
template<class T, size_t size> void scan(T(&)[size]);
template<class T> void scan(vector<T>& a){ for(auto&& i : a) scan(i); }
template<class T> void scan(deque<T>& a){ for(auto&& i : a) scan(i); }
template<class T, size_t size> void scan(array<T, size>& a){ for(auto&& i : a) scan(i); }
template<class T, class L> void scan(pair<T, L>& p){ scan(p.first); scan(p.second); }
template<class T, size_t size> void scan(T (&a)[size]){ for(auto&& i : a) scan(i); }
template<class T> void scan(T& a){ cin >> a; }
void in(){}
template <class Head, class... Tail> void in(Head& head, Tail&... tail){ scan(head); in(tail...); }
void print(){ putchar(' '); }
void print(bool a){ printf("%d", a); }
void print(int a){ printf("%d", a); }
void print(unsigned a){ printf("%u", a); }
void print(long a){ printf("%ld", a); }
void print(long long a){ printf("%lld", a); }
void print(unsigned long long a){ printf("%llu", a); }
void print(char a){ printf("%c", a); }
void print(char a[]){ printf("%s", a); }
void print(const char a[]){ printf("%s", a); }
void print(float a){ printf("%.15f", a); }
void print(double a){ printf("%.15f", a); }
void print(long double a){ printf("%.15Lf", a); }
void print(const string& a){ for(auto&& i : a) print(i); }
template<class T> void print(const complex<T>& a){ if(a.real() >= 0) print('+'); print(a.real()); if(a.imag() >= 0) print('+'); print(a.imag()); print('i'); }
template<class T> void print(const vector<T>&);
template<class T, size_t size> void print(const array<T, size>&);
template<class T, class L> void print(const pair<T, L>& p);
template<class T, size_t size> void print(const T (&)[size]);
template<class T> void print(const vector<T>& a){ if(a.empty()) return; print(a[0]); for(auto i = a.begin(); ++i != a.end(); ){ putchar(' '); print(*i); } }
template<class T> void print(const deque<T>& a){ if(a.empty()) return; print(a[0]); for(auto i = a.begin(); ++i != a.end(); ){ putchar(' '); print(*i); } }
template<class T, size_t size> void print(const array<T, size>& a){ print(a[0]); for(auto i = a.begin(); ++i != a.end(); ){ putchar(' '); print(*i); } }
template<class T, class L> void print(const pair<T, L>& p){ print(p.first); putchar(' '); print(p.second); }
template<class T, size_t size> void print(const T (&a)[size]){ print(a[0]); for(auto i = a; ++i != end(a); ){ putchar(' '); print(*i); } }
template<class T> void print(const T& a){ cout << a; }
int out(){ putchar('\n'); return 0; }
template<class T> int out(const T& t){ print(t); putchar('\n'); return 0; }
template<class Head, class... Tail> int out(const Head& head, const Tail&... tail){ print(head); putchar(' '); out(tail...); return 0; }
#define INT(...) int __VA_ARGS__; in(__VA_ARGS__)
#define LL(...) ll __VA_ARGS__; in(__VA_ARGS__)
#define ULL(...) ull __VA_ARGS__; in(__VA_ARGS__)
#define STR(...) string __VA_ARGS__; in(__VA_ARGS__)
#define CHR(...) char __VA_ARGS__; in(__VA_ARGS__)
#define DBL(...) double __VA_ARGS__; in(__VA_ARGS__)
#define LD(...) ld __VA_ARGS__; in(__VA_ARGS__)
#define VEC(type,name,size) vector<type> name(size); in(name)
#define VV(type, name, h, w) vector<vector<type>> name(h, vector<type>(w)); in(name)

bool solve(){
    STR(s);
    if(s=="#")return false;
    string target="";
    int n=s.size();
    int m=(n+1)/2;
    target+=s.substr(0,m);
    string tmp="";
    if(n%2==1)tmp=s.substr(0,m-1);
    else tmp=s.substr(0,m);
    Rev(tmp);
    target+=tmp;
    ll ans=0;
//    out("target:",target);
    for(ll i=m;i<n;){
        ll now=1;
        while(1) {
            string tar=target.substr(i,now);
            Rev(tar);
            if (s.substr(i,now)==tar){
                if(now!=1)ans+=now*now;
//                out("i:",i,"now:",now);
                i+=now;
                break;
            }
            if(i+now>=n){
                out(-1);
                return true;
            }
            now++;
        }
    }
    out(ans);
    return true;
}

int main(){
    ll t=1;
    while(solve());
    return 0;
}
accuracy: 1
time_ms: 90
memory_kb: 3660
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i, n) for (int i = 0; i < (int)(n); ++i)

struct RollingHash {
    static constexpr int M = 2;
    static constexpr long long MODS[M] = {999999937, 1000000007};
    static constexpr long long BASE = 9973;
    vector<long long> powb[M], hash[M];
    int n;
    RollingHash() {}
    RollingHash(const string &str) { init(str); }
    void init(const string &str) {
        n = str.size();
        for (int k = 0; k < M; k++) {
            powb[k].resize(n + 1, 1);
            hash[k].resize(n + 1, 0);
            for (int i = 0; i < n; i++) {
                hash[k][i + 1] = (hash[k][i] * BASE + str[i]) % MODS[k];
                powb[k][i + 1] = powb[k][i] * BASE % MODS[k];
            }
        }
    }
    // get hash str[l,r)
    long long get(int l, int r, int k) {
        long long res = hash[k][r] - hash[k][l] * powb[k][r - l] % MODS[k];
        if (res < 0) res += MODS[k];
        return res;
    }
};

bool match(RollingHash &rh1, int l1, int r1, RollingHash &rh2, int l2, int r2) {
    bool res = true;
    for (int k = 0; k < RollingHash::M; k++) {
        res &= rh1.get(l1, r1, k) == rh2.get(l2, r2, k);
    }
    return res;
}
void solve() {
    while (1) {
    

    string S;
    cin >> S;
    if (S == "#") break;
    ll n = S.size();
    string s1 = S.substr(0, n / 2);
    string s2 = S.substr((n + 1) / 2, n / 2);
    string rs2(s2);
    reverse(rs2.begin(), rs2.end());

    RollingHash rh1 = RollingHash(s1);
    RollingHash rh2 = RollingHash(s2);
    ll noans = false;
    ll ans = 0;

    int i = 0;
    while (i < n / 2) {
        if (s1[i] == s2[(n / 2) - i - 1]) {
            ++i;
            continue;
        } else {

            int j = 1;
            bool ok = false;
            while (!ok) {
                if (j+i> (n/2)) {
                    noans = true;
                    break;
                }
                else if (!match(rh1, i, i + j, rh2, (n/2) - i - j, (n/2) - i)) {
                    ++j;
                } else {
                    ok = true;
                }
            }

            ans += j*j;
            i += j;
        }
    }

    if (noans) ans = -1;
    cout << ans << endl;
    }
}

int main() {
    solve();
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3820
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, n) for (ll i = 0; i < ((ll)n); i++)
#define P pair<ll, ll>

int main(void) {
  ll ans = 0, l, r;
  string s, t, before, after;

  cin >> s;

  while (s != "#") {
    ans = 0;
    before = s.substr(0, s.size() / 2);
    after = s.substr((s.size() + 1) / 2);
    reverse(before.begin(), before.end());
    l = 0;
    r = 1;
    while (l < before.size() && before[l] == after[l]) {
      l++;
    }
    r = l + 1;
    while (r < before.size()) {
      string s2, t2;
      s2 = before.substr(l, r - l + 1);
      t2 = after.substr(l, r - l + 1);

      reverse(t2.begin(), t2.end());
      if (s2 == t2) {
        ans += (ll)s2.size() * s2.size();
        for (int j = l; j <= r; j++) {
          after[j] = before[j];
        }
        l = r + 1;
        r = l + 1;
      } else
        r++;

      while (l < before.size() && before[l] == after[l]) {
        l++;
        r = l + 1;
      }
    }
    if (before == after)
      cout << ans << endl;
    else {
      cout << -1 << endl;
    }
    cin >> s;
  }
  return 0;
}
accuracy: 1
time_ms: 90
memory_kb: 3520
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (n); i++)
using ll = long long;
#define all(x) x.begin(), x.end()
template <class A, class B>
inline bool chmin(A &a, const B &b) {
    return b < a && (a = b, true);
}
template <class A, class B>
inline bool chmax(A &a, const B &b) {
    return b > a && (a = b, true);
}

/**
 * @brief Rolling-Hash(ローリングハッシュ)
 * @see https:
 *
 */
struct RollingHash {
    static const uint64_t mod = (1ull << 61ull) - 1;
    using uint128_t = __uint128_t;
    vector<uint64_t> power;
    const uint64_t base;

    static inline uint64_t add(uint64_t a, uint64_t b) {
        if ((a += b) >= mod) a -= mod;
        return a;
    }

    static inline uint64_t mul(uint64_t a, uint64_t b) {
        uint128_t c = (uint128_t)a * b;
        return add(c >> 61, c & mod);
    }

    static inline uint64_t generate_base() {
        mt19937_64 mt(chrono::steady_clock::now().time_since_epoch().count());
        uniform_int_distribution<uint64_t> rand(1, RollingHash::mod - 1);
        return rand(mt);
    }

    inline void expand(size_t sz) {
        if (power.size() < sz + 1) {
            int pre_sz = (int)power.size();
            power.resize(sz + 1);
            for (int i = pre_sz - 1; i < sz; i++) {
                power[i + 1] = mul(power[i], base);
            }
        }
    }

    explicit RollingHash(uint64_t base = generate_base()): base(base), power{1} {}

    vector<uint64_t> build(const string &s) const {
        int sz = s.size();
        vector<uint64_t> hashed(sz + 1);
        for (int i = 0; i < sz; i++) {
            hashed[i + 1] = add(mul(hashed[i], base), s[i]);
        }
        return hashed;
    }

    template <typename T>
    vector<uint64_t> build(const vector<T> &s) const {
        int sz = s.size();
        vector<uint64_t> hashed(sz + 1);
        for (int i = 0; i < sz; i++) {
            hashed[i + 1] = add(mul(hashed[i], base), s[i]);
        }
        return hashed;
    }

    uint64_t query(const vector<uint64_t> &s, int l, int r) {
        expand(r - l);
        return add(s[r], mod - mul(s[l], power[r - l]));
    }

    uint64_t combine(uint64_t h1, uint64_t h2, size_t h2len) {
        expand(h2len);
        return add(mul(h1, power[h2len]), h2);
    }

    int lcp(const vector<uint64_t> &a, int l1, int r1, const vector<uint64_t> &b, int l2, int r2) {
        int len = min(r1 - l1, r2 - l2);
        int low = 0, high = len + 1;
        while (high - low > 1) {
            int mid = (low + high) / 2;
            if (query(a, l1, l1 + mid) == query(b, l2, l2 + mid))
                low = mid;
            else
                high = mid;
        }
        return low;
    }
};

int solve() {
    string s;
    cin >> s;
    if (s == "#") return 1;
    int n = s.size();
    int half = (n + 1) / 2;
    const ll INF = 1e18;
    vector<ll> dp(n + 1, INF);
    dp[half] = 0;
    RollingHash rh;
    auto table = rh.build(s);

    auto rev = [&](int i) {
        return n - i - 1;
    };

    auto rev_range = [&](int l, int r) {
        return pair<int, int>(rev(r) + 1, rev(l) + 1);
    };

    for (int i = half; i < n; i++) {
        if (dp[i] == INF) continue;
        if (s[i] == s[rev(i)]) chmin(dp[i + 1], dp[i]);
        for (int len = 1; len + i <= n; len++) {
            int l = i;
            int r = i + len;
            auto [ll, rr] = rev_range(l, r);
            if (rh.query(table, l, r) == rh.query(table, ll, rr)) chmin(dp[i + len], dp[i] + len * len);
        }
    }

    cout << (dp.back() == INF ? -1 : dp.back()) << endl;

    return 0;
}

int main() {
    while (!solve())
        ;
}
accuracy: 1
time_ms: 2450
memory_kb: 3744
final_rank: 12

code_snippet: #include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define all(x) (x).begin(),(x).end()
#define eb emplace_back
using namespace std;
using ll = long long;
using ld = long double;
using vl = vector<long long>;
using vvl = vector<vector<long long>>; using vs = vector<string>;
using pl = pair<long long, long long>;
template <typename T> inline bool chmin(T& a, const T& b) {bool compare = a > b; if (a > b) a = b; return compare;}
template <typename T> inline bool chmax(T& a, const T& b) {bool compare = a < b; if (a < b) a = b; return compare;}
template<class T>using rp_queue=priority_queue<T,vector<T>,greater<T>>;
template <typename T> T gcd(T a, T b) {if (b == 0)return a; else return gcd(b, a % b);}
template <typename T> inline T lcm(T a, T b) {return a /gcd(a, b)*b;}
const ll INF = 1LL << 60;
const ld PI = acos(-1);
template <class OStream, class T> OStream &operator<<(OStream &os, const std::vector<T> &vec);
template <class OStream, class T, size_t sz> OStream &operator<<(OStream &os, const std::array<T, sz> &arr);
template <class OStream, class T, class TH> OStream &operator<<(OStream &os, const std::unordered_set<T, TH> &vec);
template <class OStream, class T, class U> OStream &operator<<(OStream &os, const pair<T, U> &pa);
template <class OStream, class T> OStream &operator<<(OStream &os, const std::deque<T> &vec);
template <class OStream, class T> OStream &operator<<(OStream &os, const std::set<T> &vec);
template <class OStream, class T> OStream &operator<<(OStream &os, const std::multiset<T> &vec);
template <class OStream, class T> OStream &operator<<(OStream &os, const std::unordered_multiset<T> &vec);
template <class OStream, class T, class U> OStream &operator<<(OStream &os, const std::pair<T, U> &pa);
template <class OStream, class TK, class TV> OStream &operator<<(OStream &os, const std::map<TK, TV> &mp);
template <class OStream, class TK, class TV, class TH> OStream &operator<<(OStream &os, const std::unordered_map<TK, TV, TH> &mp);
template <class OStream, class... T> OStream &operator<<(OStream &os, const std::tuple<T...> &tpl);

template <class OStream, class T> OStream &operator<<(OStream &os, const std::vector<T> &vec) { os << '['; for (auto v : vec) os << v << ','; os << ']'; return os; }
template <class OStream, class T, size_t sz> OStream &operator<<(OStream &os, const std::array<T, sz> &arr) { os << '['; for (auto v : arr) os << v << ','; os << ']'; return os; }
template <class... T> std::istream &operator>>(std::istream &is, std::tuple<T...> &tpl) { std::apply([&is](auto &&... args) { ((is >> args), ...);}, tpl); return is; }
template <class OStream, class... T> OStream &operator<<(OStream &os, const std::tuple<T...> &tpl) { os << '('; std::apply([&os](auto &&... args) { ((os << args << ','), ...);}, tpl); return os << ')'; }
template <class OStream, class T, class TH> OStream &operator<<(OStream &os, const std::unordered_set<T, TH> &vec) { os << '{'; for (auto v : vec) os << v << ','; os << '}'; return os; }
template <class OStream, class T> OStream &operator<<(OStream &os, const std::deque<T> &vec) { os << "deq["; for (auto v : vec) os << v << ','; os << ']'; return os; }
template <class OStream, class T> OStream &operator<<(OStream &os, const std::set<T> &vec) { os << '{'; for (auto v : vec) os << v << ','; os << '}'; return os; }
template <class OStream, class T> OStream &operator<<(OStream &os, const std::multiset<T> &vec) { os << '{'; for (auto v : vec) os << v << ','; os << '}'; return os; }
template <class OStream, class T> OStream &operator<<(OStream &os, const std::unordered_multiset<T> &vec) { os << '{'; for (auto v : vec) os << v << ','; os << '}'; return os; }
template <class OStream, class T, class U> OStream &operator<<(OStream &os, const std::pair<T, U> &pa) { return os << '(' << pa.first << ',' << pa.second << ')'; }
template <class OStream, class TK, class TV> OStream &operator<<(OStream &os, const std::map<TK, TV> &mp) { os << '{'; for (auto v : mp) os << v.first << "=>" << v.second << ','; os << '}'; return os; }
template <class OStream, class TK, class TV, class TH> OStream &operator<<(OStream &os, const std::unordered_map<TK, TV, TH> &mp) { os << '{'; for (auto v : mp) os << v.first << "=>" << v.second << ','; os << '}'; return os; }
#ifdef LOCAL
const string COLOR_RESET = "\033[0m", BRIGHT_GREEN = "\033[1;32m", BRIGHT_RED = "\033[1;31m", BRIGHT_CYAN = "\033[1;36m", NORMAL_CROSSED = "\033[0;9;37m", RED_BACKGROUND = "\033[1;41m", NORMAL_FAINT = "\033[0;2m";
#define dbg(x) std::cerr << BRIGHT_CYAN << #x << COLOR_RESET << " = " << (x) << NORMAL_FAINT << " (L" << __LINE__ << ") " << __FILE__ << COLOR_RESET << std::endl
#define dbgif(cond, x) ((cond) ? std::cerr << BRIGHT_CYAN << #x << COLOR_RESET << " = " << (x) << NORMAL_FAINT << " (L" << __LINE__ << ") " << __FILE__ << COLOR_RESET << std::endl : std::cerr)
#else
#define dbg(x) ((void)0)
#define dbgif(cond, x) ((void)0)
#endif
void solve();
int main(){
  cin.tie(nullptr);
  ios_base::sync_with_stdio(false);
  cout<<fixed<<setprecision(15);
  int num_tc = 1;
  //cin >> num_tc;
  rep(tc,num_tc){
    //cout << "Case #" << tc+1 << ": " ;// << endl;
    solve();
  }
}
//見切り発車で実装しては行けない．頭の中でコードが完全に出来上がるまで書き始めるな．
const ll mod[5] = {888888901,1000000033,998244353, 1000000007, 1000000009};
const ll base[5] = {rand()%mod[0],rand()%mod[1],rand()%mod[2],rand()%mod[3],rand()%mod[4]};
struct RollingHash{
  private:
    string data;
    vl P[5],H[5];
    int N;
  public:
    RollingHash(const string &S){
      data = S;
      N = (int)S.size();
      rep(i,5)P[i].resize(N+1),H[i].resize(N+1),P[i][0]=1,H[i][0]=1;
      rep(i,N){
        rep(j,5){
          H[j][i+1]=(ll)(H[j][i]*base[j]+S[i])%mod[j];
          P[j][i+1]=(ll)(P[j][i]*base[j])%mod[j];
        }
      }
    }
    //区間[l,r)の値
    vl get(int l,int r){
      vl res(5);
      rep(i,5)res[i] = ((H[i][r] - (H[i][l]*P[i][r-l]))%mod[i]+mod[i])%mod[i];
      return res;
    }
};
void solve(){
  while(true){
    string S;cin>>S;
    if(S=="#")return;
    const int N = S.size();
    const int n = N/2;
    dbg(N);
    string T1 = S.substr(0,N/2);
    string T2 = S.substr(N/2+N%2,N/2);
    RollingHash sh1(T1),sh2(T2);
    //常に短い区間で取っていけば良いです。
    dbg(T1);
    dbg(T2);
    ll ans = 0;
    for(ll i=0;i<n;){
      if(T1[i]==T2[n-i-1]){
        i++;
        continue;
      }
      ll j = i+1;
      bool x = false;
      while(j<n){
        j++;
        dbg(make_pair(i,j));
        dbg(make_pair(n-j,n-i));
        string a,b;
        for(int k=i;k<j;k++)a+=T1[k];
        for(int k=n-j;k<n-i;k++)b+=T2[k];
        dbg(a);
        dbg(b);
        if(sh1.get(i,j)==sh2.get(n-j,n-i)){
          x =true;
          break;
        }
      }
      if(x)ans+=(j-i)*(j-i);
      else{
        ans = -1;
        break;
      }
      i = j;
    }
    cout<<(ans<0?-1:ans)<<endl;
  }
}
accuracy: 1
time_ms: 950
memory_kb: 4940
final_rank: 15

code_snippet: #include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define all(x) (x).begin(),(x).end()
#define eb emplace_back
using namespace std;
using ll = long long;
using ld = long double;
using vl = vector<long long>;
using vvl = vector<vector<long long>>; using vs = vector<string>;
using pl = pair<long long, long long>;
template <typename T> inline bool chmin(T& a, const T& b) {bool compare = a > b; if (a > b) a = b; return compare;}
template <typename T> inline bool chmax(T& a, const T& b) {bool compare = a < b; if (a < b) a = b; return compare;}
template<class T>using rp_queue=priority_queue<T,vector<T>,greater<T>>;
template <typename T> T gcd(T a, T b) {if (b == 0)return a; else return gcd(b, a % b);}
template <typename T> inline T lcm(T a, T b) {return a /gcd(a, b)*b;}
const ll INF = 1LL << 60;
const ld PI = acos(-1);
template <class OStream, class T> OStream &operator<<(OStream &os, const std::vector<T> &vec);
template <class OStream, class T, size_t sz> OStream &operator<<(OStream &os, const std::array<T, sz> &arr);
template <class OStream, class T, class TH> OStream &operator<<(OStream &os, const std::unordered_set<T, TH> &vec);
template <class OStream, class T, class U> OStream &operator<<(OStream &os, const pair<T, U> &pa);
template <class OStream, class T> OStream &operator<<(OStream &os, const std::deque<T> &vec);
template <class OStream, class T> OStream &operator<<(OStream &os, const std::set<T> &vec);
template <class OStream, class T> OStream &operator<<(OStream &os, const std::multiset<T> &vec);
template <class OStream, class T> OStream &operator<<(OStream &os, const std::unordered_multiset<T> &vec);
template <class OStream, class T, class U> OStream &operator<<(OStream &os, const std::pair<T, U> &pa);
template <class OStream, class TK, class TV> OStream &operator<<(OStream &os, const std::map<TK, TV> &mp);
template <class OStream, class TK, class TV, class TH> OStream &operator<<(OStream &os, const std::unordered_map<TK, TV, TH> &mp);
template <class OStream, class... T> OStream &operator<<(OStream &os, const std::tuple<T...> &tpl);

template <class OStream, class T> OStream &operator<<(OStream &os, const std::vector<T> &vec) { os << '['; for (auto v : vec) os << v << ','; os << ']'; return os; }
template <class OStream, class T, size_t sz> OStream &operator<<(OStream &os, const std::array<T, sz> &arr) { os << '['; for (auto v : arr) os << v << ','; os << ']'; return os; }
template <class... T> std::istream &operator>>(std::istream &is, std::tuple<T...> &tpl) { std::apply([&is](auto &&... args) { ((is >> args), ...);}, tpl); return is; }
template <class OStream, class... T> OStream &operator<<(OStream &os, const std::tuple<T...> &tpl) { os << '('; std::apply([&os](auto &&... args) { ((os << args << ','), ...);}, tpl); return os << ')'; }
template <class OStream, class T, class TH> OStream &operator<<(OStream &os, const std::unordered_set<T, TH> &vec) { os << '{'; for (auto v : vec) os << v << ','; os << '}'; return os; }
template <class OStream, class T> OStream &operator<<(OStream &os, const std::deque<T> &vec) { os << "deq["; for (auto v : vec) os << v << ','; os << ']'; return os; }
template <class OStream, class T> OStream &operator<<(OStream &os, const std::set<T> &vec) { os << '{'; for (auto v : vec) os << v << ','; os << '}'; return os; }
template <class OStream, class T> OStream &operator<<(OStream &os, const std::multiset<T> &vec) { os << '{'; for (auto v : vec) os << v << ','; os << '}'; return os; }
template <class OStream, class T> OStream &operator<<(OStream &os, const std::unordered_multiset<T> &vec) { os << '{'; for (auto v : vec) os << v << ','; os << '}'; return os; }
template <class OStream, class T, class U> OStream &operator<<(OStream &os, const std::pair<T, U> &pa) { return os << '(' << pa.first << ',' << pa.second << ')'; }
template <class OStream, class TK, class TV> OStream &operator<<(OStream &os, const std::map<TK, TV> &mp) { os << '{'; for (auto v : mp) os << v.first << "=>" << v.second << ','; os << '}'; return os; }
template <class OStream, class TK, class TV, class TH> OStream &operator<<(OStream &os, const std::unordered_map<TK, TV, TH> &mp) { os << '{'; for (auto v : mp) os << v.first << "=>" << v.second << ','; os << '}'; return os; }
#ifdef LOCAL
const string COLOR_RESET = "\033[0m", BRIGHT_GREEN = "\033[1;32m", BRIGHT_RED = "\033[1;31m", BRIGHT_CYAN = "\033[1;36m", NORMAL_CROSSED = "\033[0;9;37m", RED_BACKGROUND = "\033[1;41m", NORMAL_FAINT = "\033[0;2m";
#define dbg(x) std::cerr << BRIGHT_CYAN << #x << COLOR_RESET << " = " << (x) << NORMAL_FAINT << " (L" << __LINE__ << ") " << __FILE__ << COLOR_RESET << std::endl
#define dbgif(cond, x) ((cond) ? std::cerr << BRIGHT_CYAN << #x << COLOR_RESET << " = " << (x) << NORMAL_FAINT << " (L" << __LINE__ << ") " << __FILE__ << COLOR_RESET << std::endl : std::cerr)
#else
#define dbg(x) ((void)0)
#define dbgif(cond, x) ((void)0)
#endif
void solve();
int main(){
  cin.tie(nullptr);
  ios_base::sync_with_stdio(false);
  cout<<fixed<<setprecision(15);
  int num_tc = 1;
  //cin >> num_tc;
  rep(tc,num_tc){
    //cout << "Case #" << tc+1 << ": " ;// << endl;
    solve();
  }
}
//見切り発車で実装しては行けない．頭の中でコードが完全に出来上がるまで書き始めるな．
void solve(){
  while(true){
    string S;cin>>S;
    if(S=="#")return;
    const int N = S.size();
    const int n = N/2;
    dbg(N);
    string T1 = S.substr(0,N/2);
    string T2 = S.substr(N/2+N%2,N/2);
    reverse(all(T2));
    //常に短い区間で取っていけば良いです。
    dbg(T1);
    dbg(T2);
    ll ans = 0;
    for(ll i=0;i<n;){
      if(T1[i]==T2[i]){
        i++;
        continue;
      }
      string a,b;
      a+=T1[i];
      b+=T2[i];
      ll j = i+1;
      bool x = false;
      while(j<n){
        dbg(a);
        dbg(b);
        a+=T1[j];
        b+=T2[j];
        bool ok = true;
        j++;
        const int m = j-i;
        rep(k,m)ok&=a[k]==b[m-k-1];
        if(ok){
          x = true;
          break;
        }
      }
      dbg(j);
      dbg(a);
      dbg(b);
      if(x)ans+=(j-i)*(j-i);
      else{
        ans = -1;
        break;
      }
      i = j;
    }
    cout<<(ans<0?-1:ans)<<endl;
  }
}
accuracy: 1
time_ms: 130
memory_kb: 3520
final_rank: 4

code_snippet: // C++ includes used for precompiling -*- C++ -*-
// Copyright (C) 2003-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.
/** @file stdc++.h
 *  This is an implementation file for a precompiled header.
 */
// 17.4.1.2 Headers
// C
#ifndef _GLIBCXX_NO_ASSERT
#include <cassert>
#endif
#include <cctype>
#include <cerrno>
#include <cfloat>
#include <ciso646>
#include <climits>
#include <clocale>
#include <cmath>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#if __cplusplus >= 201103L
#include <ccomplex>
#include <cfenv>
#include <cinttypes>
#include <cstdbool>
#include <cstdint>
#include <ctgmath>
#include <cwchar>
#include <cwctype>
#endif
// C++
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>
#if __cplusplus >= 201103L
#include <array>
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <forward_list>
#include <future>
#include <initializer_list>
#include <mutex>
#include <random>
#include <ratio>
#include <regex>
#include <scoped_allocator>
#include <system_error>
#include <thread>
#include <tuple>
#include <type_traits>
#include <typeindex>
#include <unordered_map>
#include <unordered_set>

#endif

using namespace std;
using ll = long long;
#define rep(i, n) for (int i = 0; i < n; i++)
#define all(v) v.begin(), v.end()
template <class T, class U>
inline bool chmax(T& a, U b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}
template <class T, class U>
inline bool chmin(T& a, U b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}
constexpr int INF = 1000000000;
constexpr int64_t llINF = 3000000000000000000;
constexpr double eps = 1e-10;
template <class T, T (*op)(T, T), T (*e)()>
struct sparsetable {
    vector<vector<T>> table;
    vector<int> logtable;
    sparsetable(vector<T> v) {
        int len = 0;
        while ((1 << len) <= v.size()) len++;
        table.assign(len, vector<T>(1 << len));
        for (int i = 0; i < (int)v.size(); i++) table[0][i] = v[i];
        for (int i = 1; i < len; i++) {
            for (int j = 0; j + (1 << i) <= (1 << len); j++) {
                table[i][j] = op(table[i - 1][j], table[i - 1][j + (1 << (i - 1))]);
            }
        }
        logtable.resize(v.size() + 1);
        for (int i = 2; i < logtable.size(); i++) {
            logtable[i] = logtable[(i >> 1)] + 1;
        }
    }
    T query(int l, int r) {
        assert(l <= r);
        if (l == r) return e();
        int len = logtable[r - l];
        return op(table[len][l], table[len][r - (1 << len)]);
    }
};
template <class T, T (*op)(T, T), T (*e)()>
struct disjointsparsetable {
    vector<vector<T>> table;
    vector<int> logtable;
    disjointsparsetable(vector<T> v) {
        int len = 0;
        while ((1 << len) <= v.size()) len++;
        table.assign(len, vector<T>(1 << len, e()));
        for (int i = 0; i < (int)v.size(); i++) table[0][i] = v[i];
        for (int i = 1; i < len; i++) {
            int shift = 1 << i;
            for (int j = 0; j < (int)v.size(); j += shift << 1) {
                int t = min(j + shift, (int)v.size());
                table[i][t - 1] = v[t - 1];
                for (int k = t - 2; k >= j; k--) table[i][k] = op(v[k], table[i][k + 1]);
                if (v.size() <= t) break;
                table[i][t] = v[t];
                int r = min(t + shift, (int)v.size());
                for (int k = t + 1; k < r; k++) table[i][k] = op(table[i][k - 1], v[k]);
            }
        }
        logtable.resize(1 << len);
        for (int i = 2; i < logtable.size(); i++) {
            logtable[i] = logtable[(i >> 1)] + 1;
        }
    }
    T query(int l, int r) {
        if (l == r) return e();
        if (l >= --r) return table[0][l];
        int len = logtable[l ^ r];
        return op(table[len][l], table[len][r]);
    };
};

#include <algorithm>
#include <cassert>
#include <numeric>
#include <string>
#include <vector>

namespace atcoder {

namespace internal {

std::vector<int> sa_naive(const std::vector<int>& s) {
    int n = int(s.size());
    std::vector<int> sa(n);
    std::iota(sa.begin(), sa.end(), 0);
    std::sort(sa.begin(), sa.end(), [&](int l, int r) {
        if (l == r) return false;
        while (l < n && r < n) {
            if (s[l] != s[r]) return s[l] < s[r];
            l++;
            r++;
        }
        return l == n;
    });
    return sa;
}

std::vector<int> sa_doubling(const std::vector<int>& s) {
    int n = int(s.size());
    std::vector<int> sa(n), rnk = s, tmp(n);
    std::iota(sa.begin(), sa.end(), 0);
    for (int k = 1; k < n; k *= 2) {
        auto cmp = [&](int x, int y) {
            if (rnk[x] != rnk[y]) return rnk[x] < rnk[y];
            int rx = x + k < n ? rnk[x + k] : -1;
            int ry = y + k < n ? rnk[y + k] : -1;
            return rx < ry;
        };
        std::sort(sa.begin(), sa.end(), cmp);
        tmp[sa[0]] = 0;
        for (int i = 1; i < n; i++) {
            tmp[sa[i]] = tmp[sa[i - 1]] + (cmp(sa[i - 1], sa[i]) ? 1 : 0);
        }
        std::swap(tmp, rnk);
    }
    return sa;
}

// SA-IS, linear-time suffix array construction
// Reference:
// G. Nong, S. Zhang, and W. H. Chan,
// Two Efficient Algorithms for Linear Time Suffix Array Construction
template <int THRESHOLD_NAIVE = 10, int THRESHOLD_DOUBLING = 40>
std::vector<int> sa_is(const std::vector<int>& s, int upper) {
    int n = int(s.size());
    if (n == 0) return {};
    if (n == 1) return {0};
    if (n == 2) {
        if (s[0] < s[1]) {
            return {0, 1};
        } else {
            return {1, 0};
        }
    }
    if (n < THRESHOLD_NAIVE) {
        return sa_naive(s);
    }
    if (n < THRESHOLD_DOUBLING) {
        return sa_doubling(s);
    }

    std::vector<int> sa(n);
    std::vector<bool> ls(n);
    for (int i = n - 2; i >= 0; i--) {
        ls[i] = (s[i] == s[i + 1]) ? ls[i + 1] : (s[i] < s[i + 1]);
    }
    std::vector<int> sum_l(upper + 1), sum_s(upper + 1);
    for (int i = 0; i < n; i++) {
        if (!ls[i]) {
            sum_s[s[i]]++;
        } else {
            sum_l[s[i] + 1]++;
        }
    }
    for (int i = 0; i <= upper; i++) {
        sum_s[i] += sum_l[i];
        if (i < upper) sum_l[i + 1] += sum_s[i];
    }

    auto induce = [&](const std::vector<int>& lms) {
        std::fill(sa.begin(), sa.end(), -1);
        std::vector<int> buf(upper + 1);
        std::copy(sum_s.begin(), sum_s.end(), buf.begin());
        for (auto d : lms) {
            if (d == n) continue;
            sa[buf[s[d]]++] = d;
        }
        std::copy(sum_l.begin(), sum_l.end(), buf.begin());
        sa[buf[s[n - 1]]++] = n - 1;
        for (int i = 0; i < n; i++) {
            int v = sa[i];
            if (v >= 1 && !ls[v - 1]) {
                sa[buf[s[v - 1]]++] = v - 1;
            }
        }
        std::copy(sum_l.begin(), sum_l.end(), buf.begin());
        for (int i = n - 1; i >= 0; i--) {
            int v = sa[i];
            if (v >= 1 && ls[v - 1]) {
                sa[--buf[s[v - 1] + 1]] = v - 1;
            }
        }
    };

    std::vector<int> lms_map(n + 1, -1);
    int m = 0;
    for (int i = 1; i < n; i++) {
        if (!ls[i - 1] && ls[i]) {
            lms_map[i] = m++;
        }
    }
    std::vector<int> lms;
    lms.reserve(m);
    for (int i = 1; i < n; i++) {
        if (!ls[i - 1] && ls[i]) {
            lms.push_back(i);
        }
    }

    induce(lms);

    if (m) {
        std::vector<int> sorted_lms;
        sorted_lms.reserve(m);
        for (int v : sa) {
            if (lms_map[v] != -1) sorted_lms.push_back(v);
        }
        std::vector<int> rec_s(m);
        int rec_upper = 0;
        rec_s[lms_map[sorted_lms[0]]] = 0;
        for (int i = 1; i < m; i++) {
            int l = sorted_lms[i - 1], r = sorted_lms[i];
            int end_l = (lms_map[l] + 1 < m) ? lms[lms_map[l] + 1] : n;
            int end_r = (lms_map[r] + 1 < m) ? lms[lms_map[r] + 1] : n;
            bool same = true;
            if (end_l - l != end_r - r) {
                same = false;
            } else {
                while (l < end_l) {
                    if (s[l] != s[r]) {
                        break;
                    }
                    l++;
                    r++;
                }
                if (l == n || s[l] != s[r]) same = false;
            }
            if (!same) rec_upper++;
            rec_s[lms_map[sorted_lms[i]]] = rec_upper;
        }

        auto rec_sa = sa_is<THRESHOLD_NAIVE, THRESHOLD_DOUBLING>(rec_s, rec_upper);

        for (int i = 0; i < m; i++) {
            sorted_lms[i] = lms[rec_sa[i]];
        }
        induce(sorted_lms);
    }
    return sa;
}

}  // namespace internal

std::vector<int> suffix_array(const std::vector<int>& s, int upper) {
    assert(0 <= upper);
    for (int d : s) {
        assert(0 <= d && d <= upper);
    }
    auto sa = internal::sa_is(s, upper);
    return sa;
}

template <class T>
std::vector<int> suffix_array(const std::vector<T>& s) {
    int n = int(s.size());
    std::vector<int> idx(n);
    iota(idx.begin(), idx.end(), 0);
    sort(idx.begin(), idx.end(), [&](int l, int r) { return s[l] < s[r]; });
    std::vector<int> s2(n);
    int now = 0;
    for (int i = 0; i < n; i++) {
        if (i && s[idx[i - 1]] != s[idx[i]]) now++;
        s2[idx[i]] = now;
    }
    return internal::sa_is(s2, now);
}

std::vector<int> suffix_array(const std::string& s) {
    int n = int(s.size());
    std::vector<int> s2(n);
    for (int i = 0; i < n; i++) {
        s2[i] = s[i];
    }
    return internal::sa_is(s2, 255);
}

// Reference:
// T. Kasai, G. Lee, H. Arimura, S. Arikawa, and K. Park,
// Linear-Time Longest-Common-Prefix Computation in Suffix Arrays and Its
// Applications
template <class T>
std::vector<int> lcp_array(const std::vector<T>& s, const std::vector<int>& sa) {
    int n = int(s.size());
    assert(n >= 1);
    std::vector<int> rnk(n);
    for (int i = 0; i < n; i++) {
        rnk[sa[i]] = i;
    }
    std::vector<int> lcp(n - 1);
    int h = 0;
    for (int i = 0; i < n; i++) {
        if (h > 0) h--;
        if (rnk[i] == 0) continue;
        int j = sa[rnk[i] - 1];
        for (; j + h < n && i + h < n; h++) {
            if (s[j + h] != s[i + h]) break;
        }
        lcp[rnk[i] - 1] = h;
    }
    return lcp;
}

std::vector<int> lcp_array(const std::string& s, const std::vector<int>& sa) {
    int n = int(s.size());
    std::vector<int> s2(n);
    for (int i = 0; i < n; i++) {
        s2[i] = s[i];
    }
    return lcp_array(s2, sa);
}

// Reference:
// D. Gusfield,
// Algorithms on Strings, Trees, and Sequences: Computer Science and
// Computational Biology
template <class T>
std::vector<int> z_algorithm(const std::vector<T>& s) {
    int n = int(s.size());
    if (n == 0) return {};
    std::vector<int> z(n);
    z[0] = 0;
    for (int i = 1, j = 0; i < n; i++) {
        int& k = z[i];
        k = (j + z[j] <= i) ? 0 : std::min(j + z[j] - i, z[i - j]);
        while (i + k < n && s[k] == s[i + k]) k++;
        if (j + z[j] < i + z[i]) j = i;
    }
    z[0] = n;
    return z;
}

std::vector<int> z_algorithm(const std::string& s) {
    int n = int(s.size());
    std::vector<int> s2(n);
    for (int i = 0; i < n; i++) {
        s2[i] = s[i];
    }
    return z_algorithm(s2);
}

}  // namespace atcoder

int op(int a, int b) { return min(a, b); }
int e() { return INF; }
void solve(string s) {
    int n = s.size();
    auto sa = atcoder::suffix_array(s);
    auto la = atcoder::lcp_array(s, sa);
    disjointsparsetable<int, op, e> st(la);
    vector<int> pos(n);
    rep(i, n) pos[sa[i]] = i;
    int l = 0, ans = 0;
    while (l < n / 2) {
        bool ok = false;
        for (int r = l + 1; r <= n / 2; r++) {
            int a = l, b = n - r;
            int c = pos[a], d = pos[b];
            if (c > d) swap(c, d);
            if (st.query(c, d) >= r - l) {
                if (r - l > 1) ans += (r - l) * (r - l);
                l = r;
                ok = true;
                break;
            }
        }
        if (!ok) {
            cout << -1 << endl;
            return;
        }
    }
    cout << ans << endl;
}
int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int x;
    int n, m, k, d, b;
    string s;
    while (cin >> s) {
        if (s == "#") break;
        solve(s);
    }
}
accuracy: 1
time_ms: 30
memory_kb: 5716
final_rank: 19