Problem:
Suffixes may Contain Prefixes
You are playing a game on character strings. At the start of a game, a string of lowercase letters, called the
target string
, is given. Each of the players submits one string of lowercase letters, called a
bullet string
, of the specified length. The winner is the one whose bullet string marks the highest score.
The score of a bullet string is the sum of the points of all of its suffixes. When the bullet
string is "$b_1b_2 ... b_n$", the point of its suffix $s_k$ starting with the $k$-th character ($1 \leq k \leq n$), "$b_kb_{k+1} ... b_n$", is the length of its longest common prefix with the target string. That is, with the target string "$t_1t_2 ... t_m$", the point of $s_k$ is $p$ when $t_j = b_{k+j-1}$ for $1 \leq j \leq p$ and either $p = m, k + p - 1 = n$, or $t_{p+1} \ne b_{k+p}$ holds.
You have to win the game today by any means, as Alyssa promises to have a date with the
winner! The game is starting soon. Write a program in a hurry that finds the highest achievable
score for the given target string and the bullet length.
Input
The input consists of a single test case with two lines. The first line contains the non-empty
target string of at most 2000 lowercase letters. The second line contains the length of the bullet string, a positive integer not exceeding 2000.
Output
Output the highest achievable score for the given target string and the given bullet length.
Sample Input 1
ababc
6
Sample Output 1
10
Sample Input 2
aabaacaabaa
102
Sample Output 2
251
For the first sample, "
ababab
" is the best bullet string. Three among its six suffixes, "
ababab
", "
abab
", and "
ab
" obtain 4, 4, and 2 points, respectively, achieving the score 10. A bullet string
"
ababca
" may look promising, but its suffixes "
ababca
", "
abca
", and "
a
" get 5, 2, and 1, summing up only to 8.

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll INF = 1ll << 60;
#define REP(i, n) for (ll i=0; i<ll(n); i++)
template <class T> using V = vector<T>;
template<class A, class B>
bool chmax(A &a, B b) { return a < b && (a = b, true); }
template<class A, class B>
bool chmin(A &a, B b) { return b < a && (a = b, true); }

// S[:i]の接頭辞と接尾辞が最大何文字一致しているか
// S[:i]=T*cとかけるTの長さの最小値はi%mp[i]=0?mp[i]:i
template <class S>
V<int> mp(const S& s) {
  int n = int(s.size());
  V<int> r(n + 1);
  r[0] = -1;
  for (int i = 0, j = -1; i < n; i++) {
    while (j >= 0 && s[i] != s[j]) j = r[j];
    j++;
    r[i + 1] = j;
  }
  return r;
}

int main() {
    cin.tie(0)->sync_with_stdio(0);
    string s; cin >> s;
    int m; cin >> m;
    auto smp = mp(s);
    int n = ssize(s);
    V<int> points(n+1);
    for(int i = 1; i <= n; i++) {
        points[i] = points[smp[i]] + 1;
    }
    V<array<int, 26>> nxt(n+1);
    REP(i, n+1) {
        REP(c, 26) {
            int j = i;
            while(j >= 0 && (j == n || s[j]-'a' != c)) j = smp[j];
            nxt[i][c] = j+1;
        }
    }
    V<int> dp(n+1, -1);
    dp[0] = 0;
    REP(i, m) {
        V<int> ndp(n+1, -1);
        REP(j, n+1) {
            if(dp[j] == -1) continue;
            REP(c, 26) {
                int nj = nxt[j][c];
                chmax(ndp[nj], dp[j]+points[nj]);
            }
        }
        dp.swap(ndp);
    }
    cout << *ranges::max_element(dp) << '\n';
}
accuracy: 1
time_ms: 90
memory_kb: 3840
final_rank: 2

code_snippet: #include <bits/stdc++.h>
#define sz(x) ((int)(x).size())
#define all(x) begin(x), end(x)
#define rep(i, l, r) for (int i = (l), i##end = (r); i <= i##end; ++i)
#define per(i, l, r) for (int i = (l), i##end = (r); i >= i##end; --i)
#ifdef memset0
#define log(...) fprintf(stderr, __VA_ARGS__)
#else
#define log(...) (void(0))
#define endl '\n'
#endif
using namespace std;
using ll = long long;
using lf = long double;
using lll = __int128;
using ull = unsigned long long;
const int N = 2010;
const int S = 26;
int n, m, t[N], f[N][S + 1], s[N][S + 1];
int ns, nt;
int pn[N];
ll dp[N][N], ans;
string tar;
void ZF() {
  int mi = 2, mt = 1;
  pn[1] = 0;
  for (int i = 2; i <= m; ++i) {
    if (i <= mt) pn[i] = min(pn[i - mi + 1], mt - i + 1);
    else
      pn[i] = 0;
    while (i + pn[i] <= m && t[i + pn[i]] == t[1 + pn[i]]) ++pn[i];
    if (i + pn[i] - 1 > mt) mt = i + pn[i] - 1, mi = i;
    // log("pn %d=%d\n", i, pn[i]);
  }
  pn[1] = m;
}
void Upd(ll &x, ll y) { x = max(x, y); }
int main() {
#ifdef memset0
  freopen("K.in", "r", stdin);
#endif
  cin.tie(0)->sync_with_stdio(0);
  cin >> tar >> n;
  m = tar.size();
  for (int i = 1; i <= m; ++i) t[i] = tar[i - 1] - 'a';
  ZF();
  for (int i = 0; i <= m; ++i) {
    ns = 0;
    for (int j = 1; j <= i + 1; ++j) {
      nt = min(i - j + 1, pn[j]);
      if (j + nt - 1 == i && !f[i][t[nt + 1]]) {
        f[i][t[nt + 1]] = nt + 1;
        s[i][t[nt + 1]] = ns;
      }
      ns += nt;
    }
    for (int j = 0; j <= S; ++j) {
      if (!f[i][j]) s[i][j] = ns;
      // log("F %d %d=%d,S=%d\n", i, j, f[i][j], s[i][j]);
    }
  }
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j <= m && j <= i; ++j) {
      // dp[i][j];
      for (int k = 0; k < S; ++k) Upd(dp[i + 1][f[j][k]], dp[i][j] + s[j][k]);
    }
  }
  for (int i = 0; i <= m && i <= n; ++i) ans = max(ans, dp[n][i] + s[i][S]);
  cout << ans << "\n";
}
accuracy: 1
time_ms: 70
memory_kb: 33860
final_rank: 6

code_snippet: #include<bits/stdc++.h>
#define rep(i, l, r) for(int i(l);i<=(r);++i)
#define per(i, r, l) for(int i(r);i>=(l);--i)
using namespace std;
#define int long long

const int N = 4010;
int n,m;
int f[N][N],val[N];
int nxt[N],st[N][26];
char s[N];

signed main(){
	scanf("%s",s+1);
	n = strlen(s+1);
	scanf("%lld",&m);
	val[1] = 1;
	rep(i, 0, n){
		if(i > 1){
			nxt[i] = nxt[i-1];
			while(nxt[i] && s[nxt[i]+1] != s[i])nxt[i] = nxt[nxt[i]];
			if(s[nxt[i]+1] == s[i])++nxt[i];
			val[i] = val[nxt[i]] + 1;
		}
		rep(j, 0, 25){
			int u = i;
			while(u && s[u+1] != j+'a')u = nxt[u];
			st[i][j] = (s[u+1] != j+'a') ? 0 : u+1;
		}
	}
	memset(f,-0x3f,sizeof f);
	f[0][0] = 0;
	rep(i, 0, m-1)rep(j, 0, n)rep(k, 0, 25)
		f[i+1][st[j][k]] = max(f[i+1][st[j][k]], f[i][j] + val[st[j][k]]);
	int ans = -1e18;
	rep(i, 0, n)ans = max(ans, f[m][i]);
	printf("%lld\n",ans);
	return 0;	
}
accuracy: 1
time_ms: 190
memory_kb: 129608
final_rank: 13

code_snippet: #include<bits/stdc++.h>
using namespace std;

using ll = long long;
#define rep(i,n) for(int i=0;i<n;i++)
#define rep2(i,s,t) for(int i=s;i<t;i++)

using vi = vector<int>;
vi z_algo(string &s) {
  int n = s.size();
  vi z(n);
  z[0] = 0;
  for(int i = 1, j = 0; i < n; i++) {
    int &k = z[i];
    k = (j + z[j] <= i) ? 0 : 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;
}

int main() {

    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    string S;
    int N;
    cin>>S>>N;
    int SN=S.size();
    vector<vector<int>> P(SN+1,vector<int>(26,0));
    vector<vector<int>> SC(SN+1,vector<int>(26,0));
    rep(i,SN+1){
        rep(j,26){
            string T=S+"&"+S.substr(0,i);
            T.push_back(j+'a');
            vector<int> z=z_algo(T);
            for(int k=SN;k<z.size();k++){
                if(z[k]+k>=z.size()){
                    P[i][j]=int(z.size())-k;
                    if(P[i][j]==j+1)SC[i][j]=0;
                    break;
                }
                SC[i][j]+=z[k];
            }
        }
    }
    vector<vector<int>> DP(N+1,vector<int> (SN+1,-1e9));
    DP[0][0]=0;
    rep(i,N)rep(j,SN+1)rep(p,26)DP[i+1][P[j][p]]=max(DP[i+1][P[j][p]],DP[i][j]+SC[j][p]);
    
    int an=0;
    rep(i,SN+1){
        string T=S+S.substr(0,i);
        vector<int> z=z_algo(T);
        rep(k,i)DP[N][i]+=z[k+SN];
        an=max(an,DP[N][i]);
    }
    cout<<an<<endl;
}
accuracy: 0.43243243243243246
time_ms: 830
memory_kb: 19292
final_rank: 14

code_snippet: #include<bits/stdc++.h>
using namespace std;

using ll = long long;
#define rep(i,n) for(int i=0;i<n;i++)
#define rep2(i,s,t) for(int i=s;i<t;i++)

using vi = vector<int>;
// `vi z_algo(s);` : `i` 番目の要素が `LCP( s[0, n), s[i, n) )` である配列
vi z_algo(string &s) {
  int n = s.size();
  vi z(n);
  z[0] = 0;
  for(int i = 1, j = 0; i < n; i++) {
    int &k = z[i];
    k = (j + z[j] <= i) ? 0 : 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;
}

int main() {

    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    string S;
    int N;
    cin>>S>>N;
    int SN=S.size();
    vector<vector<int>> P(SN+1,vector<int>(26,0));
    vector<vector<int>> SC(SN+1,vector<int>(26,0));
    rep(i,SN+1){
        rep(j,26){
            string T=S;
            T.push_back('&');
            T+=S.substr(0,i);
            T.push_back(j+'a');
            vector<int> z=z_algo(T);
            for(int k=SN;k<z.size();k++){
                if(z[k]+k>=z.size()){
                    P[i][j]=int(z.size())-k;
                    break;
                }
                SC[i][j]+=z[k];
            }
        }
    }
    // rep(j,SN+1)rep(p,26){
    //     cout<<SN<<" "<<j<<" "<<p<<" "<<P[j][p]<<endl;
    //     assert(P[j][p]>=0&&P[j][p]<=SN);
    // }
    vector<vector<int>> DP(N+1,vector<int> (SN+1,-1e9));
    DP[0][0]=0;
    rep(i,N)rep(j,SN+1){
        rep(p,26){
            if(P[j][p]==j+1){
                DP[i+1][j+1]=max(DP[i][j],DP[i+1][j+1]);
            }
            else{
                
                DP[i+1][P[j][p]]=max(DP[i+1][P[j][p]],DP[i][j]+SC[j][p]);
            }
        }
    }
    
    int an=0;
    rep(i,SN+1){
        string T=S+S.substr(0,i);
        vector<int> z=z_algo(T);
        rep(k,i){
            DP[N][i]+=z[k+SN];
        }
        an=max(an,DP[N][i]);
    }
    cout<<an<<endl;

}
accuracy: 1
time_ms: 830
memory_kb: 19428
final_rank: 12

code_snippet: #include<bits/stdc++.h>
using namespace std;

using ll = long long;
#define rep(i,n) for(int i=0;i<n;i++)
#define rep2(i,s,t) for(int i=s;i<t;i++)

using vi = vector<int>;
// `vi z_algo(s);` : `i` 番目の要素が `LCP( s[0, n), s[i, n) )` である配列
vi z_algo(string &s) {
  int n = s.size();
  vi z(n);
  z[0] = 0;
  for(int i = 1, j = 0; i < n; i++) {
    int &k = z[i];
    k = (j + z[j] <= i) ? 0 : 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;
}

int main() {

    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    string S;
    int N;
    cin>>S>>N;
    int SN=S.size();
    vector<vector<int>> P(SN+1,vector<int>(26,0));
    vector<vector<int>> SC(SN+1,vector<int>(26,0));
    rep(i,SN+1){
        rep(j,26){
            string T=S+S.substr(0,i);
            T.push_back(j+'a');
            vector<int> z=z_algo(T);
            for(int k=SN;k<z.size();k++){
                if(z[k]+k>=z.size()){
                    P[i][j]=int(z.size())-k;
                    break;
                }
                SC[i][j]+=z[k];
            }
            // cout<<i<<" "<<j<<" "<<P[i][j]<<" "<<z[SN]<<endl;
        }
    }
    vector<vector<int>> DP(N+1,vector<int> (SN+1,-1e9));
    DP[0][0]=0;
    rep(i,N)rep(j,SN+1){
        rep(p,26){
            if(P[j][p]==j+1){
                DP[i+1][j+1]=max(DP[i][j],DP[i+1][j+1]);
            }
            else{
                DP[i+1][P[j][p]]=max(DP[i+1][P[j][p]],DP[i][j]+SC[j][p]);
            }
        }
    }
    int an=0;
    // rep(i,SN+1)cout<<DP[N][i]<<" "<<i<<endl;
    rep(i,SN+1){
        string T=S+S.substr(0,i);
        vector<int> z=z_algo(T);
        // rep(j,z.size())cout<<z[j]<<" ";
        // cout<<endl;
        rep(k,i){
            // if(i==2)cout<<"@@"<<z[k+SN]<<endl;
            DP[N][i]+=z[k+SN];
        }
        an=max(an,DP[N][i]);
    }
    // cout<<DP[2][2]<<endl;
    cout<<an<<endl;

    // cout<<SC[4][3]<<endl;
}
accuracy: 0.43243243243243246
time_ms: 830
memory_kb: 19356
final_rank: 15

code_snippet: #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 <cstdio> // printf
#include <map> // map
#include <queue> // queue, priority_queue
#include <set> // set
#include <stack> // stack
#include <deque> // deque #include <unordered_map> // unordered_map #include <unordered_set> // unordered_set #include <bitset> // bitset
#include <cctype> // isupper, islower, isdigit, toupper, tolower
#include <math.h>
#include <iomanip>
#include <functional>
#include<unordered_map>
#include <random>
#include<bitset>
#include<cassert>
using namespace std;  
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define repi(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define endl '\n'
#define all(x) (x).begin(),(x).end()
#define arr(x) (x).rbegin(),(x).rend()
typedef long long ll;
typedef unsigned long long ull;
const ll inf=1e18;  
using graph = vector<vector<int> > ;
using vi=vector<int>;
using P= pair<ll,ll>;  
using vvi=vector<vi>;
using vvvi=vector<vvi>;
using vll=vector<ll>; 
using vvll=vector<vll>;
using vvvll=vector<vvll>;
using vp=vector<P>;
using vvp=vector<vp>;
using vd=vector<double>;
using vvd =vector<vd>;

const int mod=1e9+7;

struct UnionFind { vector<int> par, siz; UnionFind(int n) : par(n, -1) , siz(n, 1) { } int root(int x) { if (par[x] == -1) return x;
        else return par[x] = root(par[x]);
    }
    bool issame(int x, int y) {
        return root(x) == root(y);
    }
    bool unite(int x, int y) {
        x = root(x), y = root(y);
        if (x == y) return false; 
        if (siz[x] < siz[y]) swap(x, y);
        par[y] = x;
        siz[x] += siz[y];
        return true;
    }
    int size(int x) {
        return siz[root(x)];
    }
};
ll pow_pow(ll x,ll n,ll mod){
    if(n==0) return 1; 
    x%=mod;
    ll res=pow_pow(x*x%mod,n/2,mod);
    if(n&1)res=res*x%mod;
    return res;
}
template<class T> bool chmin(T& a, T b) {
    if (a > b) {
        a = b;
        return true;
    }
    else return false;
}
template<class T> bool chmax(T& a, T b) {
    if (a < b) {
        a = b;
        return true;
    }
    else return false;
}

vll anss; 
void solve(int test){
    string s; cin >> s;
    int n=s.size();
    int c=26;
    vvi to(n+1,vi(c));
    string now="";
    vi rd(c);
    rep(i,c)rd[i]=rand()%mod;
    vll pow2(n+5,1);
    repi(i,1,n+5)pow2[i]=(pow2[i-1]*2)%mod;
    rep(i,n+1){
        rep(j,c){
            now+=char('a'+j);
            int si=now.size();
           // string x="";
           // string y="";
            ll x=0;
            ll y=0;

            repi(len,1,min(si,n)+1){
            //    x=now[now.size()-len]+x;
                x=2*x+rd[now[now.size()-len]-'a'];
                x%=mod;
             //   y+=s[len-1];
                y=y+pow2[len-1]*rd[s[len-1]-'a'];
                y%=mod;
                if(x==y)chmax(to[i][j],len);
            }
            now.pop_back();
        }
        if(i!=n)now+=s[i];
    }
    vi sc(n+2);
    repi(len,1,n+1){
        // string x="";
        // string y="";
        ll x=0;
        ll y=0;
        repi(nowlen,1,len+1){
            //x=s[len-nowlen]+x;
            x=2*x+rd[s[len-nowlen]-'a'];
            x%=mod;
            // y+=s[nowlen-1];
            y=y+pow2[nowlen-1]*rd[s[nowlen-1]-'a'];
            y%=mod;
            if(x==y)sc[len]++;
        }
    }




    vll dp(n+1,-inf);
    vll old(n+1,-inf);
    dp[0]=0;
    int m; cin >> m;
    rep(_,m){
        rep(len,n+1){
            old[len]=dp[len];
            dp[len]=-inf;
        }
        rep(len,n+1){
            ll now=old[len];
            if(now==-inf)continue;
            rep(j,c){
                chmax(dp[to[len][j]],now+sc[to[len][j]]);
            }
        }
    }
    ll ans=-inf;
    rep(j,n+1)chmax(ans,dp[j]);


    cout << ans << endl;
}
//g++ cf.cpp -std=c++17 -I .  
int main(){cin.tie(0);ios::sync_with_stdio(false);
    int t=1;//cin >>t;
    rep(test,t)solve(test);
    for(auto ans:anss){
        cout<< ans << endl;
    }
}
accuracy: 1
time_ms: 200
memory_kb: 3724
final_rank: 5

code_snippet: #include <bits/stdc++.h>
#define sz(x) ((int)(x).size())
#define all(x) begin(x), end(x)
#define rep(i, l, r) for (int i = (l), i##end = (r); i <= i##end; ++i)
#define per(i, l, r) for (int i = (l), i##end = (r); i >= i##end; --i)
#ifdef memset0
#define log(...) fprintf(stderr, __VA_ARGS__)
#else
#define log(...) (void(0))
#define endl '\n'
#endif
using namespace std;
using ll = long long;
using lf = long double;
using lll = __int128;
using ull = unsigned long long;
const int N = 2010;
const int S = 26;
int n, m, t[N], f[N][S + 1], s[N][S + 1];
int ns, nt;
int pn[N];
ll dp[N][N], ans;
string tar;
void ZF() {
  int mi = 2, mt = 1;
  pn[1] = 0;
  for (int i = 2; i <= m; ++i) {
    if (i <= mt) pn[i] = min(pn[i - mi + 1], mt - i + 1);
    else
      pn[i] = 0;
    while (i + pn[i] <= m && t[i + pn[i]] == t[1 + pn[i]]) ++pn[i];
    if (i + pn[i] - 1 > mt) mt = i + pn[i] - 1, mi = i;
    // log("pn %d=%d\n", i, pn[i]);
  }
  pn[1] = m;
}
void Upd(ll &x, ll y) { x = max(x, y); }
int main() {
#ifdef memset0
  freopen("K.in", "r", stdin);
#endif
  cin.tie(0)->sync_with_stdio(0);
  cin >> tar >> n;
  m = tar.size();
  for (int i = 1; i <= m; ++i) t[i] = tar[i - 1] - 'a';
  ZF();
  for (int i = 0; i <= m; ++i) {
    ns = 0;
    for (int j = 1; j <= i + 1; ++j) {
      nt = min(i - j + 1, pn[j]);
      if (j + nt - 1 == i && !f[i][t[nt + 1]]) {
        f[i][t[nt + 1]] = nt + 1;
        s[i][t[nt + 1]] = ns;
      }
      ns += nt;
    }
    for (int j = 0; j <= S; ++j) {
      if (!f[i][j]) s[i][j] = ns;
      // log("F %d %d=%d,S=%d\n", i, j, f[i][j], s[i][j]);
    }
  }
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j <= m && j <= i; ++j) {
      // dp[i][j];
      for (int k = 0; k < S; ++k) Upd(dp[i + 1][f[j][k]], dp[i][j] + s[j][k]);
    }
  }
  for (int i = 0; i <= m && i <= n; ++i) ans = max(ans, dp[n][i] + s[i][S]);
  cout << ans << "\n";
}
accuracy: 1
time_ms: 70
memory_kb: 33880
final_rank: 7

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

struct Z {
    int n;
    string s;
    vector<int> z;
    Z(const string& t) {
        s = t;
        init();
    }
    void init() {
        n = s.size();
        z = vector<int>(n, 0);
        z[0] = n;
        for(int i = 1, j = 0; i < n;) {
            while(i + j < n && s[i + j] == s[j]) ++j;
            z[i] = j;
            if(j) {
                int k = 1;
                while(i + k < n && k + z[k] < j) {
                    z[i + k] = z[k];
                    k++;
                }
                i += k;
                j -= k;
            } else {
                i++;
            }
        }
    }
    int operator[](int i) const { return z[i]; }
};

int main() {
    string s;
    cin >> s;
    int n;
    cin >> n;

    vector g(s.size() + 1, vector(26, pair<int, int>(0, 0)));

    string res = s + "$" + s[0];
    reverse(all(res));
    g[0][s[0] - 'a'] = {1, 1};

    for(int i = 1; i < s.size() + 1; i++) {
        res[0] = s[i - 1];
        res = 'a' + res;

        rep(j, 26) {
            res[0] = char('a' + j);
            Z z(res);
            rep(k, res.size() - s.size()) {
                if(z[res.size() - 1 - k] == k + 1) {
                    g[i][j].second++;
                    g[i][j].first = max(g[i][j].first, (int)k + 1);
                }
            }
        }
    }

    vector<vector<int>> dp(n + 1, vector<int>(s.size() + 1, -1e8));
    dp[0][0] = 0;

    rep(i, n) {
        rep(j, s.size() + 1) {
            rep(k, 26) {
                dp[i + 1][g[j][k].first] =
                    max(dp[i + 1][g[j][k].first], dp[i][j] + g[j][k].second);
            }
        }
    }

    int ans = 0;
    rep(i, s.size() + 1) { ans = max(ans, dp[n][i]); }
    cout << ans << endl;
}
accuracy: 1
time_ms: 470
memory_kb: 19220
final_rank: 11

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

struct Z{
    int n;
    string s;
    vector<int>z;
    Z(const string& t){
        s = t;
        init();
    }
    void init(){
        n = s.size();
        z = vector<int>(n,0);
        z[0] = n;
        for(int i = 1,j = 0;i<n;){
            while(i+j < n && s[i+j] == s[j])++j;
            z[i] = j;
            if(j){
                int k = 1;
                while(i+k<n&&k+z[k]<j){
                    z[i+k] = z[k];
                    k++;
                }
                i += k;
                j -= k;
            }else{
                i++;
            }
        }
    }
    int operator[](int i)const {return z[i];}
};

int main(){
    string s;
    cin >> s;
    int n;
    cin >> n;
    
    vector g(s.size()+1,vector(26,pair<int,int>(0,0)));

    string res = s + "$" + s[0];
    reverse(all(res));
    g[0][s[0]-'a'] = {1,1};

    for(int i = 1;i <s.size()+1; i++){
        res[0] = s[i-1];
        res = 'a' + res ;

        rep(j,26){
            res[0] = char('a' + j);
            Z z(res);
            rep(k,res.size() - s.size()){
                if(z[res.size() - 1 - k] == k + 1){
                    g[i][j].second++;
                    g[i][j].first = max(g[i][j].first, (int)k+1);
                }
            }
        }
    }
    

    vector<vector<int>> dp(n+1,vector<int>(s.size() + 1, -1e8));
    dp[0][0] = 0;


    rep(i,n){
        rep(j, s.size()+1){
            rep(k, 26){
                dp[i+1][g[j][k].first] = max(dp[i+1][g[j][k].first], dp[i][j] + g[j][k].second);
            }
        }
    }

    int ans = 0;
    rep(i,s.size()){
        ans = max(ans, dp[n][i]);
    }
    cout << ans << endl;
}
accuracy: 0.05405405405405406
time_ms: 460
memory_kb: 18980
final_rank: 16

code_snippet: #include<bits/stdc++.h>
using namespace std;

const int INF=1<<30;

namespace Lib{
    template<class T>
    vector<int>z_algorithm(const vector<T>&A){
        int n=A.size();
        vector<int>z(n);
        int i=1,j=0;
        while(i<n){
            while(i+j<n&&A[j]==A[i+j])j+=1;
            z[i]=j;
            if(j==0){
                i+=1;
                continue;
            }
            int k=1;
            while(i+k<n&&k+z[k]<j)z[i+k]=z[k],k+=1;
            i+=k,j-=k;
        }
        z[0]=n;
        return z;
    }
}

using ll=long long;
const ll MOD=998244353,r=237187909;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    string T;
    int N;
    cin>>T>>N;
    int M=T.size();
    vector longest(M+1,vector<int>(26)),counting(M+1,vector<int>(26));
    vector<ll>R(2010);
    R[0]=1;
    for(int i=1;i<2010;i++){
        R[i]=(R[i-1]*r)%MOD;
    }
    for(int j=0;j<=M;j++){
        for(int c=0;c<26;c++){
            string s="";
            if(j>0)s=T.substr(0,j);
            s+=char('a'+c);
            int sl=s.size();
            ll a=0,b=0;
            int p=sl-1,q=0;
            while(p>=0&&q<M){
                a=(s[p]*R[sl-1-p]+a)%MOD;
                b=(r*b+T[q])%MOD;
                if(a==b){
                    counting[j][c]++;
                    longest[j][c]=max(longest[j][c],q+1);
                }
                p--;
                q++;
            }
        }
    }
    vector dp(N+1,vector<int>(M+1,-INF));
    dp[0][0]=0;
    for(int i=0;i<N;i++){
        for(int j=0;j<=M;j++){
            for(int c=0;c<26;c++){
                dp[i+1][longest[j][c]]=max(dp[i+1][longest[j][c]],dp[i][j]+counting[j][c]);
            }
        }
    }
    int ans=-INF;
    for(int i=0;i<=M;i++){
        ans=max(ans,dp[N][i]);
    }
    cout<<ans<<"\n";
}
accuracy: 1
time_ms: 300
memory_kb: 19368
final_rank: 9

code_snippet: #include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

int main() {
	// step #1. input
	string S; int M;
	cin >> S >> M;
	int N = S.size();

	// step #2. compute length of LCP
	vector<vector<int> > lcp(N + 1, vector<int>(N + 1, 0));
	for (int i = N - 1; i >= 0; i--) {
		for (int j = N - 1; j >= 0; j--) {
			if (S[i] == S[j]) {
				lcp[i][j] = lcp[i + 1][j + 1] + 1;
			}
		}
	}

	// step #3. compute next state
	vector<vector<int> > next_state(N + 1, vector<int>(26, 0));
	for (int i = 0; i <= N; i++) {
		for (int j = 0; j < 26; j++) {
			for (int k = (i != N ? i : i - 1); k >= 0; k--) {
				if (lcp[0][i - k] >= k && int(S[k] - 'a') == j) {
					next_state[i][j] = k + 1;
					break;
				}
			}
		}
	}
	
	// step #4. compute sub-scores
	vector<vector<int> > subscore(N + 1, vector<int>(26, 0));
	for (int i = 0; i <= N; i++) {
		for (int j = 0; j < 26; j++) {
			for (int k = 0; k < (i + 1) - next_state[i][j]; k++) {
				subscore[i][j] += min(lcp[0][k], i - k);
			}
		}
	}

	// step #5. dynamic programming
	const int INF = 1012345678;
	vector<vector<int> > dp(M + 1, vector<int>(N + 1, -INF));
	dp[0][0] = 0;
	for (int i = 0; i < M; i++) {
		for (int j = 0; j <= N; j++) {
			for (int k = 0; k < 26; k++) {
				dp[i + 1][next_state[j][k]] = max(dp[i + 1][next_state[j][k]], dp[i][j] + subscore[j][k]);
			}
		}
	}

	// step #6. calculate answer
	int answer = 0;
	for (int i = 0; i <= N; i++) {
		int subanswer = dp[M][i];
		for (int j = 0; j < i; j++) {
			subanswer += min(lcp[0][j], i - j);
		}
		answer = max(answer, subanswer);
	}

	// step #7. output
	cout << answer << endl;

	return 0;
}
accuracy: 1
time_ms: 220
memory_kb: 35040
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
#define inf 1000000007
#define MP make_pair
#define MT make_tuple
#define PB push_back
#define fi first
#define se second
#define rep(i,n) for(int i = 0; i < (int)(n); ++i)
#define rrep(i,n) for(int i = (int)n-1; i >= 0; --i)
#define srep(i,a,b) for(int i = (int)a; i < (int)(b); ++i)
#define all(x) (x).begin(),(x).end()
#define SUM(v) accumulate(all(v), 0LL)
#define MIN(v) *min_element(all(v))
#define MAX(v) *max_element(all(v))
#define lb(c, x) distance((c).begin(), lower_bound(all(c), (x)))
#define ub(c, x) distance((c).begin(), upper_bound(all(c), (x)))
#define UNIQUE(x) sort(all(x)), x.erase(unique(all(x)), x.end())
#define SZ(c) (int)(c).size()
template<typename T>
ostream& operator << (ostream& os, vector<T>& vec) {
    os << "{";
    for (int i = 0; i<(int)vec.size(); i++) {
        os << vec[i] << (i + 1 == (int)vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
// pair出力
template<typename T, typename U>
ostream& operator << (ostream& os, pair<T, U> pair_var) {
    os << "(" << pair_var.first << ", " << pair_var.second << ")";
    return os;
}
// map出力
template<typename T, typename U>
ostream& operator << (ostream& os, 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;
}
// set 出力
template<typename T>
ostream& operator << (ostream& os, 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;
}
// tuple 出力
template<int N,class Tuple>
void out(ostream &os,const Tuple &t){}
template<int N,class Tuple,class H,class ...Ts>
void out(ostream &os,const Tuple &t){
    if(N)os<<", ";
    os<<get<N>(t);
    out<N+1,Tuple,Ts...>(os,t);
}
template<class ...Ts>
ostream& operator<<(ostream &os, const tuple<Ts...> &t){
    os<<"(";
    out<0,tuple<Ts...>,Ts...>(os,t);
    os<<")";
    return os;
}
#define overload2(_1, _2, name, ...) name
#define vec(type, name, ...) vector<type> name(__VA_ARGS__)
#define VEC(type, name, size)                                                                                                                                  \
    vector<type> name(size);                                                                                                                                   \
    IN(name)
#define vv(type, name, h, ...) vector<vector<type>> name(h, vector<type>(__VA_ARGS__))
#define VV(type, name, h, w)                                                                                                                                   \
    vector<vector<type>> name(h, vector<type>(w));                                                                                                             \
    IN(name)
#define vvv(type, name, h, w, ...) vector<vector<vector<type>>> name(h, vector<vector<type>>(w, vector<type>(__VA_ARGS__)))
#define vvvv(type, name, a, b, c, ...)                                                                                                                         \
    vector<vector<vector<vector<type>>>> name(a, vector<vector<vector<type>>>(b, vector<vector<type>>(c, vector<type>(__VA_ARGS__))))
#define INT(...)                                                                                                                                               \
    int __VA_ARGS__;                                                                                                                                           \
    IN(__VA_ARGS__)
#define LL(...)                                                                                                                                                \
    ll __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__)
int scan() { return getchar(); }
void scan(int &a) { cin >> a; }
void scan(long long &a) { cin >> a; }
void scan(char &a) { cin >> a; }
void scan(double &a) { cin >> a; }
void scan(string &a) { cin >> a; }
template <class T, class S> void scan(pair<T, S> &p) { scan(p.first), scan(p.second); }
template <class T> void scan(vector<T> &);
template <class T> void scan(vector<T> &a) {
    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...);
}
const string YESNO[2] = {"NO", "YES"};
const string YesNo[2] = {"No", "Yes"};
const string yesno[2] = {"no", "yes"};
void YES(bool t = 1) { cout << YESNO[t] << endl; }
void NO(bool t = 1) { YES(!t); }
void Yes(bool t = 1) { cout << YesNo[t] << endl; }
void No(bool t = 1) { Yes(!t); }
void yes(bool t = 1) { cout << yesno[t] << endl; }
void no(bool t = 1) { yes(!t); }
#ifdef LOCAL
void debug_out() { cerr << endl; }
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
    cerr << " " << H;
    debug_out(T...);
}
#define dbg(...) \
    cerr << __LINE__ << " [" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " " << #x << " = " << (x) << endl
#else
#define dbg(...) (void(0))
#define dump(x) (void(0))
#endif
template<typename A, typename T>
std::enable_if_t<std::is_convertible<T, A>::value> fill(A& array, const T& val)
{
    array = val;
}
template<typename A, typename T>
std::enable_if_t<!std::is_convertible<T, A>::value> fill(A& array, const T& val)
{
    for (auto& a : array) {
        fill(a, val);
    }
}
template <typename T, typename S> T ceil(T x, S y) {
    assert(y);
    return (y < 0 ? ceil(-x, -y) : (x > 0 ? (x + y - 1) / y : x / y));
}
template <typename T, typename S> T floor(T x, S y) {
    assert(y);
    return (y < 0 ? floor(-x, -y) : (x > 0 ? x / y : x / y - (x % y == 0 ? 0 : 1)));
}
vector<int> iota(int n) {vector<int> a(n);iota(all(a), 0);return a;}
template <class T> T POW(T x, int n) {T res = 1;for(; n; n >>= 1, x *= x){if(n & 1) res *= x;}return res;}
ll pow2(int i) { return 1LL << i; }
int topbit(signed t) { return t == 0 ? -1 : 31 - __builtin_clz(t); }
int topbit(ll t) { return t == 0 ? -1 : 63 - __builtin_clzll(t); }
int lowbit(signed a) { return a == 0 ? 32 : __builtin_ctz(a); }
int lowbit(ll a) { return a == 0 ? 64 : __builtin_ctzll(a); }
// int allbit(int n) { return (1 << n) - 1; }
ll allbit(ll n) { return (1LL << n) - 1; }
int popcount(signed t) { return __builtin_popcount(t); }
int popcount(ll t) { return __builtin_popcountll(t); }
bool ispow2(int i) { return i && (i & -i) == i; }


template <class S> void fold_in(vector<S> &v) {}
template <typename Head, typename... Tail, class S> void fold_in(vector<S> &v, Head &&a, Tail &&...tail) {
    for(auto e : a) v.emplace_back(e);
    fold_in(v, tail...);
}
template <class S> void renumber(vector<S> &v) {}
template <typename Head, typename... Tail, class S> void renumber(vector<S> &v, Head &&a, Tail &&...tail) {
    for(auto &&e : a) e = lb(v, e);
    renumber(v, tail...);
}
template <class S, class... Args> void zip(vector<S> &head, Args &&...args) {
    vector<S> v;
    fold_in(v, head, args...);
    sort(all(v)), v.erase(unique(all(v)), v.end());
    renumber(v, head, args...);
}
template<class T> inline bool chmax(T &a, T b){
    if(a<b){
        a = b;
        return true;
    }
    return false;
}
template<class T> inline bool chmin(T &a, T b){
    if(a>b){
        a = b;
        return true;
    }
    return false;
}


class mp
{
public:
    string pattern;
    int plen;
    vector<int> table;
    mp(const string& s) : pattern(s), plen((int)pattern.size()), table(plen + 1){
        table[0] = -1;
        int j = -1;
        for(int i = 0; i < plen; ++i){
            while(j >= 0 && pattern[i] != pattern[j]){
                j = table[j];
            }
            table[i+1] = ++j;
        }
    }
    void search(const string& text, vector<int>& res){
        int head = 0, j = 0, tlen = (int)text.size();
        while(head + j < tlen){
            if(pattern[j] == text[head + j]) {
                if(++j == plen){
                    res.push_back(head);
                    head = head + j - table[j];
                    j = table[j];
                }
            }else{
                head = head + j - table[j];
                if(j) j = table[j];
            }
        }
    }
};

void z_algorithm(const string& S, vector<int>& res)
{
    int sz = (int)S.size();
    res.resize(sz, sz);
    int i = 1, j = 0;
    while(i < sz){
        while(i+j < sz && S[j] == S[i+j]) j++;
        res[i] = j;
        if(j == 0){
            i++;
            continue;
        }
        int k = 1;
        while(i+k < sz && k+res[k] < j){
            res[i+k] = res[k], k++;
        }
        i += k; j -= k;
    }
}

int dp[5010][3010];
int val[3010];

int main(){
    STR(s);
    INT(n);
    mp X(s);
    auto table = X.table;
    dbg(table);
    fill(dp,-inf);
    dp[0][0] = 0;
    int L = s.size();
    for(int i=1;i<=L;i++){
        string t = s.substr(0,i);
        vector<int> P;
        z_algorithm(t,P);
        int LCP = table[i];
        dbg(i,i-LCP);
        
        for(int j=0;j<=min(i-LCP,i-1);j++){
            val[i] += P[j];
        }
    }
    for(int i=0;i<=n;i++){
        for(int len = 0;len<=L;len++){
            
            // i から始まり len だけすでに決まっている
            dbg(i,len,dp[i][len]);
            // 1文字伸ばす
            chmax(dp[i][len+1],dp[i][len]);
            
            // 1 step 進める
            if(len>=1){
                int LCP = table[len];
                int ni = i+len-LCP;
                int V = val[len] - LCP;
                dbg(i,len,"->",ni,LCP,V);
                chmax(dp[ni][LCP],dp[i][len] + V);
            }
        }
    }
    int res = dp[n][0];
    cout << res << endl;
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 62428
final_rank: 8

code_snippet: #pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<unordered_set>
#include<utility>
#include<cassert>
#include<complex>
#include<numeric>
#include<array>
#include<chrono>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
constexpr ll mod = 998244353;
//constexpr ll mod = 1000000007;
const ll INF = mod * mod;
typedef pair<int, int>P;

#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;

template<typename T>
void chmin(T& a, T b) {
	a = min(a, b);
}
template<typename T>
void chmax(T& a, T b) {
	a = max(a, b);
}
template<typename T>
void cinarray(vector<T>& v) {
	rep(i, v.size())cin >> v[i];
}
template<typename T>
void coutarray(vector<T>& v) {
	rep(i, v.size()) {
		if (i > 0)cout << " "; cout << v[i];
	}
	cout << "\n";
}
ll mod_pow(ll x, ll n, ll m = mod) {
	if (n < 0) {
		ll res = mod_pow(x, -n, m);
		return mod_pow(res, m - 2, m);
	}
	if (abs(x) >= m)x %= m;
	if (x < 0)x += m;
	//if (x == 0)return 0;
	ll res = 1;
	while (n) {
		if (n & 1)res = res * x % m;
		x = x * x % m; n >>= 1;
	}
	return res;
}
struct modint {
	int n;
	modint() :n(0) { ; }
	modint(ll m) {
		if (m < 0 || mod <= m) {
			m %= mod; if (m < 0)m += mod;
		}
		n = m;
	}
	operator int() { return n; }
};
bool operator==(modint a, modint b) { return a.n == b.n; }
bool operator<(modint a, modint b) { return a.n < b.n; }
modint operator+=(modint& a, modint b) { a.n += b.n; if (a.n >= mod)a.n -= mod; return a; }
modint operator-=(modint& a, modint b) { a.n -= b.n; if (a.n < 0)a.n += mod; return a; }
modint operator*=(modint& a, modint b) { a.n = ((ll)a.n * b.n) % mod; return a; }
modint operator+(modint a, modint b) { return a += b; }
modint operator-(modint a, modint b) { return a -= b; }
modint operator*(modint a, modint b) { return a *= b; }
modint operator^(modint a, ll n) {
	if (n == 0)return modint(1);
	modint res = (a * a) ^ (n / 2);
	if (n % 2)res = res * a;
	return res;
}

ll inv(ll a, ll p) {
	return (a == 1 ? 1 : (1 - p * inv(p % a, a)) / a + p);
}
modint operator/(modint a, modint b) { return a * modint(inv(b, mod)); }
modint operator/=(modint& a, modint b) { a = a / b; return a; }
const int max_n = 1 << 20;
modint fact[max_n], factinv[max_n];
void init_f() {
	fact[0] = modint(1);
	for (int i = 0; i < max_n - 1; i++) {
		fact[i + 1] = fact[i] * modint(i + 1);
	}
	factinv[max_n - 1] = modint(1) / fact[max_n - 1];
	for (int i = max_n - 2; i >= 0; i--) {
		factinv[i] = factinv[i + 1] * modint(i + 1);
	}
}
modint comb(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[b] * factinv[a - b];
}
modint combP(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[a - b];
}

ll gcd(ll a, ll b) {
	a = abs(a); b = abs(b);
	if (a < b)swap(a, b);
	while (b) {
		ll r = a % b; a = b; b = r;
	}
	return a;
}
typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-8;
const ld pi = acosl(-1.0);
template<typename T>
void addv(vector<T>& v, int loc, T val) {
	if (loc >= v.size())v.resize(loc + 1, 0);
	v[loc] += val;
}
/*const int mn = 100005;
bool isp[mn];
vector<int> ps;
void init() {
	fill(isp + 2, isp + mn, true);
	for (int i = 2; i < mn; i++) {
		if (!isp[i])continue;
		ps.push_back(i);
		for (int j = 2 * i; j < mn; j += i) {
			isp[j] = false;
		}
	}
}*/

//[,val)
template<typename T>
auto prev_itr(set<T>& st, T val) {
	auto res = st.lower_bound(val);
	if (res == st.begin())return st.end();
	res--; return res;
}

//[val,)
template<typename T>
auto next_itr(set<T>& st, T val) {
	auto res = st.lower_bound(val);
	return res;
}
using mP = pair<modint, modint>;


int dx[4] = { 1,0,-1,0 };
int dy[4] = { 0,1,0,-1 };
//-----------------------------------------

struct AhoCorasick {
	static const int SIZE = 27;
	struct State {
		int index, next[SIZE];
		//vector<int> accept;
		State(int index) : index(index) {
			for (int i = 0; i < SIZE; i++)next[i] = -1;
		}
	};
	vector<State> pma;
	//vector<int> lens;

	AhoCorasick(const vector<string>& str, char base_c = 'a') {
		pma.clear();
		pma.push_back(State(0));
		//lens.clear();
		rep(i, str.size()) {
			int t = 0;
			for (char c : str[i]) {
				if (pma[t].next[c - base_c] == -1) {
					int m = pma.size();
					pma[t].next[c - base_c] = m;
					pma.push_back(State(m));
				}
				t = pma[t].next[c - base_c];
			}
			//pma[t].accept.push_back(lens.size());
			//lens.push_back(str[i].size());
		}
		queue<int> que;
		for (int c = 0; c < SIZE - 1; c++) {
			if (pma[0].next[c] != -1) {
				pma[pma[0].next[c]].next[SIZE - 1] = 0;
				que.push(pma[0].next[c]);
			}
			else {
				pma[0].next[c] = 0;
			}
		}
		while (!que.empty()) {
			int t = que.front();
			que.pop();
			for (int c = 0; c < SIZE - 1; c++) {
				if (pma[t].next[c] != -1) {
					que.push(pma[t].next[c]);
					int r = pma[t].next[SIZE - 1];
					while (pma[r].next[c] == -1) r = pma[r].next[SIZE - 1];
					pma[pma[t].next[c]].next[SIZE - 1] = pma[r].next[c];
					//for (int i : pma[pma[r].next[c]].accept)
					//	pma[pma[t].next[c]].accept.push_back(i);
				}
			}
		}
	}
	int sub(int index, int c) {
		return pma[index].next[c] != -1 ?
			pma[index].next[c] :
			pma[index].next[c] = sub(pma[index].next[SIZE - 1], c);
	}
	int query(int m) {
		vector<int> ad(pma.size());
		for (int i = 1; i < pma.size(); i++) {
			ad[i] = 1;
			ad[i] += ad[pma[i].next[26]];
		}
		vector<int> dp(pma.size(), -mod);
		dp[0] = 0;
		rep(_, m) {
			vector<int> ndp(pma.size(), -mod);
			rep(i, dp.size()) {
				rep(j, 26) {
					int nid = sub(i, j);
					chmax(ndp[nid], dp[i] + ad[nid]);
				}
			}
			swap(dp, ndp);
		}
		int res = 0; rep(i, dp.size())chmax(res, dp[i]);
		return res;
	}
	/*vector<int> query(string& t) {
		int index = 0;
		vector<int> ret(lens.size(), -1);
		rep(i, t.size()) {
			int c = t[i];
			index = sub(index, c);
			for (int j : pma[index].accept) {
				if (ret[j] != -1) continue;
				ret[j] = i - lens[j] + 1;
			}
		}
		return ret;
	}*/
};


void solve() {
	string s; cin >> s;
	int n = s.size();
	int m; cin >> m;
	vector<string> ss = { s };
	AhoCorasick aho(ss);
	int ans = aho.query(m);
	cout << ans << "\n";
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout << fixed << setprecision(10);
	//init_f();
	//init();
	//while(true)
	//expr();
	//int t; cin >> t; rep(i, t)
	solve();
	return 0;
}
accuracy: 1
time_ms: 130
memory_kb: 11788
final_rank: 4

code_snippet: #include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
#define _GLIBCXX_DEBUG
using namespace std;
using std::cout;
using std::cin;
using std::endl;
using ll=long long;
using ld=long double;
ll ILL=1167167167167167167;
const int INF=2100000000;
const ll mod=998244353;
#define rep(i,a) for (int i=0;i<a;i++)
#define all(p) p.begin(),p.end()
template<class T> using _pq = priority_queue<T, vector<T>, greater<T>>;
template<class T> ll LB(vector<T> &v,T a){return lower_bound(v.begin(),v.end(),a)-v.begin();}
template<class T> ll UB(vector<T> &v,T a){return upper_bound(v.begin(),v.end(),a)-v.begin();}
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> void So(vector<T> &v) {sort(v.begin(),v.end());}
template<class T> void Sore(vector<T> &v) {sort(v.begin(),v.end(),[](T x,T y){return x>y;});}
void yneos(bool a){if(a) cout<<"Yes\n"; else cout<<"No\n";}
template<class T> void vec_out(vector<T> &p){for(int i=0;i<(int)(p.size());i++){if(i) cout<<" ";cout<<p[i];}cout<<"\n";}


void solve();
// oddloop
int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	
	int t=1;
	//cin>>t;
	rep(i,t) solve();
}

void solve(){
	string S;
	cin>>S;
	int M=S.size();
	S+="#";
	int N;
	cin>>N;
	vector<int> match(M);
	rep(i,M){
		rep(j,M-i){
			if(S[j]==S[j+i]) match[i]++;
			else break;
		}
		//cout<<match[i]<<endl;
	}
	int V=26;
	vector<pair<int,int>> to(V*(M+1),{-1,0});
	rep(i,M+1) rep(j,V){
		int ind=i*V+j;
		rep(k,i){
			if(match[k]>=i-k&&(int)(S[i-k]-'a')==j){
				to[ind].first=i+1-k;
				break;
			}else{
				to[ind].second+=min(match[k],i-k);
			}
		}
		if(to[ind].first==-1&&j==(int)(S[0]-'a')){
			to[ind].first=1;
		}else if(to[ind].first==-1) to[i*V+j].first=0;
	}
	vector<int> dp(M+1,-INF);
	dp[0]=0;
	rep(roop,N){
		vector<int> n_dp(M+1,-INF);
		rep(i,M+1) rep(j,V){
			//if(dp[i]==-INF) break;
			chmax(n_dp[to[i*V+j].first],dp[i]+to[i*V+j].second);
		}
		swap(dp,n_dp);
	}
	/*rep(i,M){
		rep(j,V){
			cout<<to[i*V+j]<<" ";
		}
		cout<<"\n";
	}*/
	int ans=0;
	rep(i,M+1){
		rep(j,i){
			dp[i]+=min(i-j,match[j]);
		}
		chmax(ans,dp[i]);
	}
	cout<<ans<<"\n";
}
accuracy: 1
time_ms: 140
memory_kb: 3468
final_rank: 3

code_snippet: #include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <array>
using namespace std;

int main(){
	string s;
	int m;
	cin >> s >> m;
	int n = s.size();
	vector<int> score(n + 1);
	vector<array<int,26>> to(n + 1);
	{
		vector<int> mp(n + 1, -1);
		int j = -1;
		for(int i = 1; i <= n; ++i){
			char c = s[i - 1];
			while(j >= 0 && s[j] != c){ j = mp[j]; }
			mp[i] = ++j;
			score[i] = score[j] + 1;
			to[i - 1][c - 'a'] = i;
			for(int k = 0; k < 26; ++k){
				to[i][k] = to[j][k];
			}
		}
	}
	
	const int INF = 1010101010;
	vector<int> dp1(n + 1, -INF), dp2;
	dp1[0] = 0;
	for(int i = 0; i < m; ++i){
		dp2.assign(n + 1, -INF);
		for(int j = 0; j <= n; ++j){
			if(dp1[j] < 0){ continue; }
			for(int k = 0; k < 26; ++k){
				int t = to[j][k];
				dp2[t] = max(dp2[t], dp1[j] + score[t]);
			}
		}
		dp1.swap(dp2);
	}
	int ans = *max_element(dp1.begin(), dp1.end());
	cout << ans << '\n';
}
accuracy: 1
time_ms: 70
memory_kb: 3488
final_rank: 1