Problem:
Reversible Compression
Data compression is an essential technology in our information society. It is to encode a given string into a (preferably) more compact code string so that it can be stored and/or transferred efficiently.
You are asked to design a novel compression algorithm such that even a code string is reversed it can be decoded into the given string.
Currently, you are considering the following specification as a candidate.
A given string is a sequence of decimal digits, namely, $0$, $1$, $2$, $3$, $4$, $5$, $6$, $7$, $8$, and $9$.
A code string is a sequence of code words, and a code word consists of two decimal digits
A
and
L
. So, a code string is a sequence of even number of decimal digits.
A code string
A
$_1$
L
$_1$ ...
A
$_k$
L
$_k$ is decoded into a string by the following procedure. Here, for brevity, a decimal digit (
A
$_i$ or
L
$_i$) is also treated as the single digit decimal integer it represents.
1. $i \leftarrow 1$
 2. while ($i$ is not greater than $k$) {
 3.     if (A$_i$ is zero) { output L$_i$ }
 4.     else if (L$_i$ is zero) { do nothing }
 5.     else if (A$_i$ is larger than the number of digits output so far) { raise an error }
 6.     else {
 7.         repeat L$_i$ times {
 8.             output the A$_i$-th of the already output digits counted backwards
 9.         }
10.     }
11.     $i \leftarrow i + 1$
12. }
For example, a code string
000125
is decoded into a string
0101010
as follows:
The first code word
00
outputs
0
.
The second code word
01
outputs
1
.
The first digit
2
of the last code word
25
means that the second digit in the already decoded digits, counted backwards, should be output. This should be repeated five times. For the first repetition, the decoded digits so far are
0
and
1
, and thus the second last digit is
0
, which is output. For the second repetition, digits decoded so far are
0
,
1
, and
0
, and the second last is
1
, which is output. Repeating this three more times outputs
0
,
1
, and
0
.
A sequence of code words that raises no error is a valid code string. A valid code string is said
to be
reversible
when its reverse is also valid and both the original and its reverse are decoded into the same string.
For example, the code string
000125
is not reversible, because its reverse,
521000
, raises an error and thus is not valid. The code string
0010
is not reversible though its reverse is valid. It is decoded into
0
, but its reverse
0100
is decoded into
10
. On the other hand,
0015599100
is reversible, because this and its reverse,
0019955100
, are both decoded into
00000000000000000
.
You want to evaluate the performance of this compression method when applied to a variety of cases. Your task is to write a program that, for an arbitrary given digit string, finds the shortest reversible code string that is decoded into the given string.
Input
The input consists of a single line containing a non-empty string $s$ of decimal digits. The length of $s$ does not exceed $500$.
Output
Output th
...(truncated)

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll INF = 1LL << 60;
#define rep(i, a) for(ll i = 0; i < (a); i++)
#define all(a) begin(a), end(a)
// #define sz(a) (a).size()
bool chmin(auto& a, auto b) { return a > b ? a = b, 1 : 0; }
bool chmax(auto& a, auto b) { return a < b ? a = b, 1 : 0; }
#define out(a) cout << (a) << endl
using vll = vector<ll>;
using vvll = vector<vll>;
using pll = pair<ll, ll>;

int main()
{
    string S; cin >> S;
    ll N = S.size();
    auto rS = S;
    reverse(all(rS));
    vvll dist(N + 1, vll(N + 1, INF));
    vector<vector<pair<pll, pll>>> from(N + 1, vector<pair<pll, pll>>(N + 1));
    queue<pll> q;
    q.emplace(0, 0);
    dist[0][0] = 0;
    while(!q.empty())
    {
        auto [a, b] = q.front(); q.pop();
        vector<pll> ok;
        rep(i, 10LL) rep(j, 10LL)
        {
            if(i == 0)
            {
                if(a < N)
                {
                    if(S[a] - '0' == j)
                    {
                        ok.push_back({i, j});
                    }
                }
            }
            else if(j == 0)
            {
                ok.push_back({i, j});
            }
            else
            {
                bool can = true;
                rep(k, j)
                {
                    if(!(0 <= a - i + k && a - i + k < N && a + k < N))
                    {
                        can = false;
                        break;
                    }
                    if(S[a - i + k] != S[a + k])
                    {
                        can = false;
                        break;
                    }
                }
                if(can)
                {
                    ok.push_back({i, j});
                }
            }
        }
        vector<pll> nxt;
        for(auto [j, i] : ok)
        {
            if(i == 0)
            {
                if(b < N)
                {
                    if(S[N - b - 1] - '0' == j)
                    {
                        nxt.push_back({j, i});
                    }
                }
            }
            else if(j == 0)
            {
                nxt.push_back({j, i});
            }
            else
            {
                bool can = true;
                rep(k, j)
                {
                    if(!(0 <= (N - b - 1) - i - k && (N - b - 1) - i - k < N && 0 <= (N - b - 1) - k && (N - b - 1) - k < N))
                    {
                        can = false;
                        break;
                    }
                    if(S[(N - b - 1) - i - k] != S[(N - b - 1) - k])
                    {
                        can = false;
                        break;
                    }
                }
                if(can)
                {
                    nxt.push_back({j, i});
                }
            }
        }
        for(auto [i, j] : nxt)
        {
            ll na = a, nb = b;
            if(i == 0)
            {
                na++;
                if(j == 0)
                {
                    nb++;
                }
            }
            else if(j == 0)
            {
                nb++;
            }
            else
            {
                na += j;
                nb += i;
            }
            if(dist[na][nb] < INF) continue;
            // cout << a << " " << b << " " << na << " " << nb << " " << i << " " << j << endl;
            dist[na][nb] = dist[a][b] + 1;
            from[na][nb] = {{a, b}, {i, j}};
            q.emplace(na, nb);
        }
    }
    string ans = "";
    ll na = N, nb = N;
    while(na > 0 || nb > 0)
    {
        auto [ab, ij] = from[na][nb];
        auto [a, b] = ab;
        auto [i, j] = ij;
        ans.push_back(j + '0');
        ans.push_back(i + '0');
        na = a;
        nb = b;
    }
    reverse(all(ans));
    out(ans);
}
accuracy: 1
time_ms: 320
memory_kb: 13568
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
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; }
#define vi vector<int>
#define vl vector<ll>
#define vii vector<pair<int,int>>
#define vll vector<pair<ll,ll>>
#define vvi vector<vector<int>>
#define vvl vector<vector<ll>>
#define vvii vector<vector<pair<int,int>>>
#define vvll vector<vector<pair<ll,ll>>>
#define vst vector<string>
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pb push_back
#define all(x) (x).begin(),(x).end()
#define mkunique(x) sort(all(x));(x).erase(unique(all(x)),(x).end())
#define fi first
#define se second
#define mp make_pair
#define si(x) int(x.size())
const int mod=998244353,MAX=505,INF=15<<26;

int dp[MAX][MAX];
pii par[MAX][MAX];
vector<pair<short,short>> rG[MAX][MAX];
pair<short,short> G[MAX][MAX][10][10];

int main(){
    
    std::ifstream in("text.txt");
    std::cin.rdbuf(in.rdbuf());
    cin.tie(0);
    ios::sync_with_stdio(false);
    
    string S;cin>>S;
    int N=si(S);
    for(int i=0;i<=N;i++){
        for(int j=0;j<=N;j++){
            dp[i][j]=INF;
        }
    }
    
    auto f=[&](int a,int x,int y){
        if(x==0){
            if(a<N&&S[a]==char('0'+y)){
                return a+1;
            }else{
                return -1;
            }
        }else if(y==0){
            return a;
        }else if(x>a){
            return -1;
        }else{
            if(a+y<=N){
                for(int i=0;i<y;i++){
                    if(S[a+i-x]!=S[a+i]) return -1;
                }
                return a+y;
            }else{
                return -1;
            }
        }
    };
    
    auto g=[&](int a,int x,int y){
        if(x==0){
            if(a<N&&S[N-1-a]==char('0'+y)){
                return a+1;
            }else{
                return -1;
            }
        }else if(y==0){
            return a;
        }else if(a+y>N){
            return -1;
        }else{
            if(x>N-(a+y)){
                return -1;
            }else{
                for(int i=0;i<y;i++){
                    if(S[N-(a+y)+i-x]!=S[N-(a+y)+i]) return -1;
                }
                return a+y;
            }
        }
    };
    
    for(int a=0;a<=N;a++){
        for(int b=0;b<=N;b++){
            for(int x=0;x<10;x++){
                for(int y=0;y<10;y++){
                    int na=f(a,x,y);
                    int nb=g(b,y,x);
                    if(na!=-1&&nb!=-1){
                        G[a][b][x][y]=mp((short)na,(short)nb);
                        rG[na][nb].pb({(short)a,(short)b});
                    }else{
                        G[a][b][x][y]=mp((short)-1,(short)-1);
                    }
                }
            }
        }
    }
    queue<pii> Q;
    dp[N][N]=0;
    Q.push(mp(N,N));
    
    while(!Q.empty()){
        auto [na,nb]=Q.front();Q.pop();
        if(na==0&&nb==0) break;
        for(auto [a,b]:rG[na][nb]){
            if(chmin(dp[a][b],dp[na][nb]+1)) Q.push(mp(a,b));
        }
    }
    
    string ans;
    
    int a=0,b=0;
    while(1){
        if(a==N&&b==N) break;
        bool done=false;
        for(int x=0;x<10;x++){
            for(int y=0;y<10;y++){
                auto [na,nb]=G[a][b][x][y];
                if(na==-1) continue;
                if(dp[a][b]==dp[na][nb]+1){
                    a=na;
                    b=nb;
                    ans+=char('0'+x);
                    ans+=char('0'+y);
                    done=true;
                    break;
                }
            }
            if(done) break;
        }
    }
    cout<<ans<<endl;
}
accuracy: 1
time_ms: 290
memory_kb: 237012
final_rank: 17

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

void solve(){
    string s; cin >> s;
    int n = ssize(s);
    array<vector<ll>, 10> sd;
    for(int l = 1; l < 10; l++) {
        if(l > n) continue;
        sd[l].resize(n-l+1);
        for(int i = 0; i <= n-l; i++) {
            for(int j = 0; j < l; j++) {
                sd[l][i] *= 10;
                sd[l][i] += s[i+j] - '0';
            }
        }
    }
    constexpr int INF = 100000;
    vector dp(n+1, vector<int>(n+1, INF));
    vector prev(n+1, vector<tuple<char, char>>(n+1)); // a, l, i, j
    vector<pair<int, int>> nxt;
    dp[n][0] = 0;
    nxt.emplace_back(n, 0);
    while(1) {
        vector<pair<int, int>> nnxt;
        for(auto [i, j] : nxt) {
            int c = dp[i][j];
            for(int a = 0; a < 10; a++) for(int l = 0; l < 10; l++) {
                int ni = (a == 0 ? i-1 : i-l);
                int nj = (l == 0 ? j+1 : j+a);
                if(ni < 0) continue;
                if(nj > n) continue;
                auto gen = [&](int u, int a, int l) -> bool {
                    if(a == 0) {
                        return s[u]-'0' == l;
                    }
                    if(l == 0) return true;
                    int j = u-a;
                    if(j < 0) return false;
                    if(u+l > n) return false;
                    return sd[l][j] == sd[l][u];
                };
                if(!gen(ni, a, l)) continue;
                if(!gen(j, l, a)) continue;
                if(auto nprev = make_tuple(a, l); dp[ni][nj] > c+1 || (dp[ni][nj] == c+1 && prev[ni][nj] > nprev)) {
                    dp[ni][nj] = c+1;
                    prev[ni][nj] = nprev;
                    nnxt.emplace_back(ni, nj);
                }
            }
        }
        if(dp[0][n] < INF) {
            string ans;
            int i = 0, j = n;
            int c = dp[0][n];
            while(c--) {
                auto [a, l] = prev[i][j];
                ans.push_back('0' + a);
                ans.push_back('0' + l);
                i = (a == 0 ? i+1 : i+l);
                j = (l == 0 ? j-1 : j-a);
            }
            cout << ans << '\n';
            return;
        }
        ranges::sort(nnxt);
        nnxt.erase(ranges::unique(nnxt).begin(), nnxt.end());
        nxt.swap(nnxt);
    }
}

int main() {
    solve();
}
accuracy: 1
time_ms: 110
memory_kb: 6264
final_rank: 4

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

int main(){
    string S;
    cin>>S;
    int N=S.size();
    vector<vector<string>> DP(N+1,vector<string>(N+1,"?"));
    DP[0][0]="";
    for(int i=0;i<=N;i++){
        for(int j=0;j<=N;j++){
            if(DP[i][j]=="?")continue;
            for(int a=0;a<10;a++){
                for(int l=0;l<10;l++){
                    bool OK=1;
                    int ni=i,nj=j;
                    if(a==0){
                        if(S[i]!='0'+l)OK=0;
                        ni++;
                    }
                    else if(l!=0){
                        if(i<a||i+l>N){
                            OK=0;
                        }
                        else for(int k=0;k<l;k++){
                            if(ni-a<0||ni>=N){
                                OK=0;
                                break;
                            }
                            if(S[ni-a]!=S[ni])OK=0;
                            ni++;
                        }
                    }
                    if(l==0){
                        if(S[N-1-j]!='0'+a)OK=0;
                        nj++;
                    }
                    else if(a!=0){
                        // if(N-j<l||j+a>N)OK=0;
                        for(int k=0;k<a;k++){
                            if((N-nj-1)-l<0){
                                OK=0;
                                break;
                            }
                            if(S[(N-nj-1)]!=S[(N-nj-1)-l])OK=0;
                            nj++;
                        }
                    }
                    if(!OK)continue;
                    if(DP[ni][nj]!="?"&&DP[i][j].size()+2>DP[ni][nj].size())continue;
                    // cout<<i<<" "<<j<<" "<<a<<" "<<l<<" "<<ni<<" "<<nj<<" "<<OK<<endl;
                    string NS=DP[i][j];
                    NS.push_back('0'+a);
                    NS.push_back('0'+l);
                    if(DP[ni][nj]=="?"||DP[ni][nj].size()>NS.size()||(DP[ni][nj].size()==NS.size()&&DP[ni][nj]>NS)){
                        DP[ni][nj]=NS;
                    }
                }
            }
            if(j!=N){
              string NNS=".";
              swap(DP[i][j],NNS);
            }
        }
        if(i!=N){
          vector<string> NDP;
          swap(DP[i],NDP);
        }
    }
    cout<<DP[N][N]<<endl;
}
accuracy: 1
time_ms: 580
memory_kb: 13824
final_rank: 11

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

struct Node {
    int len;
    int lasta;
    int lastb;
    int preva;
    int prevb;
};

bool operator<(Node l, Node r){
    if(l.len != r.len) return l.len < r.len;
    if(l.lastb != r.lastb) return l.lastb < r.lastb;
    if(l.lasta != r.lasta) return l.lasta < r.lasta;
    return false;
}

string solve(string S){
    int N = S.size();
    vector<vector<Node>> dp(N+1, vector<Node>(N+1, { 1001001001, 0, 0, 0, 0 }));
    dp[0][N] = {0,0,0,0,0};
    auto check = [&](int a, int b, Node v){
        if(v < dp[a][b]) dp[a][b] = v;
    };
    for(int a=0; a<=N; a++) for(int b=N; b>=0; b--){
        int nxlen = dp[a][b].len + 1;
        if(a != N && S[a] != '0'){
            check(a+1, b, {nxlen, 0, S[a]-'0', a, b});
        }
        if(b != 0 && S[b-1] != '0'){
            check(a, b-1, {nxlen, S[b-1]-'0', 0, a, b});
        }
        if(a != N && b != 0 && S[a] == '0' && S[b-1] == '0'){
            check(a+1, b-1, {nxlen, 0, 0, a, b});
        }
        for(int c=1; c<=9; c++) for(int d=1; d<=9; d++){
            if(a+d > N) continue;
            if(b-c-d+1 < 0) continue;
            if(a-c < 0) continue;
            bool ok = true;
            for(int x=0; x<d; x++) if(S[a-c+x] != S[a+x]) ok = false;
            for(int x=0; x<c; x++) if(S[b-1-d-x] != S[b-1-x]) ok = false;
            if(ok) check(a+d, b-c, { nxlen, c, d, a, b });
        }
    }
    string ans;
    int a = N, b = 0;
    while(a != 0 || b != N){
        auto [l,c,d,pa,pb] = dp[a][b];
        ans.push_back(d+'0');
        ans.push_back(c+'0');
        a = pa; b = pb;
    }
    return ans;
}


int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    string S; cin >> S;
    auto ans = solve(S);
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 130
memory_kb: 8112
final_rank: 5

code_snippet: #include<bits/stdc++.h>
using namespace std;
string S;
int N;
int calc_forward(int i,int a,int l){
  if(a==0){
    if(i<N&&S[i]-'0'==l)return 1;
    return -1;
  }else if(l==0){
    return 0;
  }else{
    if(i<a)return -1;
    if(N<i+l)return -1;
    for(int k=0;k<l;++k){
      if(S[i-a+k]!=S[i+k])return -1;
    }
    return l;
  }
}
int calc_backward(int i,int a,int l){
  if(a==0){
    if(i<N&&S[N-1-i]-'0'==l)return 1;
    return -1;
  }else if(l==0){
    return 0;
  }else{
    int input_num=N-i-l;
    if(input_num<a)return -1;
    for(int k=0;k<l;++k){
      if(S[input_num-a+k]!=S[input_num+k])return -1;
    }
    return l;
  }
}
int main(){
  cin.tie(0)->sync_with_stdio(0);
  cin>>S;
  N=S.size();
  vector<vector<int>>dp(N+1,vector<int>(N+1,1<<30));
  dp[0][0]=0;
  for(int i=0;i<=N;++i){
    for(int j=0;j<=N;++j){
      for(int k=0;k<=99;++k){
        int a=k/10,l=k%10;
        int x=calc_forward(i,a,l);
        int y=calc_backward(j,l,a);
        if(x==-1||y==-1)continue;
        dp[i+x][j+y]=min(dp[i+x][j+y],dp[i][j]+2);
      }
    }
  }
  //cout<<dp[N][N]<<endl;
  string ans;
  int px=N,py=N;
  while(px!=0||py!=0){
    for(int k=0;k<=99;++k){
      int a=k/10,l=k%10;
      int x=calc_backward(N-px,l,a);
      int y=calc_forward(N-py,a,l);
      if(x==-1||y==-1)continue;
      if(dp[px][py]-2==dp[px-x][py-y]){
        ans+='0'+a;
        ans+='0'+l;
        px-=x,py-=y;
        break;
      }
    }
  }
  cout<<ans<<endl;
}
accuracy: 1
time_ms: 240
memory_kb: 4108
final_rank: 8

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

#define foa(s, v) for(auto& s : v)
#define rng(i, l, r) for(int i = int(l); i < int(r); i++)
#define rep(i, n) rng(i, 0, n)
#define sz(x) int(x.size())
#define all(x) begin(x), end(x)

template <class T>
bool chmax(T& a, T b) {
	return a < b ? a = b, true : false;
}
template <class T>
bool chmin(T& a, T b) {
	return a > b ? a = b, true : false;
}
using ll = long long;

#ifdef LOCAL
#define debug(x) cerr << __LINE__ << ", " << #x << ": " << x << "\n"
#else
#define debug(x) (void(0))
#endif

template <class T>
ostream& operator<<(ostream& os, vector<T> v) {
	os << "{ ";
	foa(t, v) os << t << ", ";
	os << "}";
	return os;
}

using ll = long long;
using vi = vector<int>;

string str;

void solve() {
	vector<int> trg;
	foa(c, str) trg.push_back(c - '0');
	const int len = sz(str);

	debug(trg);

	auto idx = [&](int x, int y) { return x * (len + 1) + y; };

	const int v = idx(len, len) + 1;

	auto proceed = [&](int pos, int a, int el) -> int {
		if(a == 0) {
			if(pos >= len || trg[pos] != el) return -1;
			return pos + 1;
		}
		if(el == 0) { return pos; }
		if(a > pos) return -1;
		rep(lp, el) {
			int nxt = trg[pos - a];
			if(pos < len && nxt == trg[pos])
				pos++;
			else
				return -1;
		}
		return pos;
	};

	auto backward = [&](int pos, int a, int el) -> int {
		auto nxt_chr = [&]() -> int {
			if(pos <= 0) return -1;
			return trg[pos - 1];
		};

		if(a == 0) { return (nxt_chr() == el) ? pos - 1 : -1; }
		if(el == 0) return pos;

		rep(lp, el) {
			int old = pos - 1 - a;
			if(old < 0 || nxt_chr() != trg[old]) return -1;
			pos--;
		}

		return pos;
	};

	vector<vector<int>> out(v, vi(100, -1));

	for(int s = len; s >= 0; s--) {
		for(int t = 0; t <= len; t++) {
			const int from_idx = idx(s, t);

			rep(num, 100) {
				int a = num / 10;
				int el = num % 10;

				int ns = proceed(s, a, el);
				int nt = backward(t, el, a);

				if(s == 0 && t == len && num == 1) {
					debug(ns);
					debug(nt);
				}

				if(ns == -1) continue;
				if(nt == -1) continue;

				int to_idx = idx(ns, nt);

				out[from_idx][num] = to_idx;
			}
		}
	}

	vector<int> dist_to_goal(v, int(1e9));
	const int start = idx(0, len);
	const int goal = idx(len, 0);
	dist_to_goal[goal] = 0;

	for(int s = len; s >= 0; s--) {
		rep(t, len + 1) {
			const int frm = idx(s, t);
			rep(num, 100) {
				int to = out[frm][num];
				if(to == -1) continue;
				chmin(dist_to_goal[frm], dist_to_goal[to] + 1);
			}
		}
	}

	string ans;
	int cur = start;
	while(cur != goal) {
		rep(num, 100) {
			int to = out[cur][num];
			if(to == -1) continue;
			if(dist_to_goal[to] + 1 == dist_to_goal[cur]) {
				ans += '0' + num / 10;
				ans += '0' + num % 10;
				cur = to;
				break;
			}
		}
	}
	cout << ans << endl;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	while(cin >> str) solve();
}
accuracy: 1
time_ms: 230
memory_kb: 112020
final_rank: 13

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

#define foa(s, v) for(auto& s : v)
#define rng(i, l, r) for(int i = int(l); i < int(r); i++)
#define rep(i, n) rng(i, 0, n)
#define sz(x) int(x.size())
#define all(x) begin(x), end(x)

template <class T>
bool chmax(T& a, T b) {
	return a < b ? a = b, true : false;
}
template <class T>
bool chmin(T& a, T b) {
	return a > b ? a = b, true : false;
}
using ll = long long;

#ifdef LOCAL
#define debug(x) cerr << __LINE__ << ", " << #x << ": " << x << "\n"
#else
#define debug(x) (void(0))
#endif

template <class T>
ostream& operator<<(ostream& os, vector<T> v) {
	os << "{ ";
	foa(t, v) os << t << ", ";
	os << "}";
	return os;
}

using ll = long long;
using vi = vector<int>;

string str;

void solve() {
	vector<int> trg;
	foa(c, str) trg.push_back(c - '0');
	const int len = sz(str);

	debug(trg);

	auto idx = [&](int x, int y) { return x * (len + 1) + y; };

	const int v = idx(len, len) + 1;

	auto proceed = [&](int pos, int a, int el) -> int {
		if(a == 0) {
			if(pos >= len || trg[pos] != el) return -1;
			return pos + 1;
		}
		if(el == 0) { return pos; }
		if(a > pos) return -1;
		rep(lp, el) {
			int nxt = trg[pos - a];
			if(pos < len && nxt == trg[pos])
				pos++;
			else
				return -1;
		}
		return pos;
	};

	auto backward = [&](int pos, int a, int el) -> int {
		auto nxt_chr = [&]() -> int {
			if(pos <= 0) return -1;
			return trg[pos - 1];
		};

		if(a == 0) { return (nxt_chr() == el) ? pos - 1 : -1; }
		if(el == 0) return pos;

		rep(lp, el) {
			int old = pos - 1 - a;
			if(old < 0 || nxt_chr() != trg[old]) return -1;
			pos--;
		}

		return pos;
	};

	vector<vector<int>> out(v, vi(100, -1));

	for(int s = len; s >= 0; s--) {
		for(int t = 0; t <= len; t++) {
			const int from_idx = idx(s, t);

			rep(num, 100) {
				int a = num / 10;
				int el = num % 10;

				int ns = proceed(s, a, el);
				int nt = backward(t, el, a);

				if(s == 0 && t == len && num == 1) {
					debug(ns);
					debug(nt);
				}

				if(ns == -1) continue;
				if(nt == -1) continue;

				int to_idx = idx(ns, nt);

				out[from_idx][num] = to_idx;
			}
		}
	}

	vector<int> dist_to_goal(v, int(1e9));
	const int start = idx(0, len);
	const int goal = idx(len, 0);
	dist_to_goal[goal] = 0;

	for(int s = len; s >= 0; s--) {
		rep(t, len + 1) {
			const int frm = idx(s, t);
			rep(num, 100) {
				int to = out[frm][num];
				if(to == -1) continue;
				chmin(dist_to_goal[frm], dist_to_goal[to] + 1);
			}
		}
	}

	string ans;
	int cur = start;
	while(cur != goal) {
		rep(num, 100) {
			int to = out[cur][num];
			if(to == -1) continue;
			if(dist_to_goal[to] + 1 == dist_to_goal[cur]) {
				ans += '0' + num / 10;
				ans += '0' + num % 10;
				cur = to;
			}
		}
	}
	cout << ans << endl;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	while(cin >> str) solve();
}
accuracy: 0.044444444444444446
time_ms: 200
memory_kb: 111816
final_rank: 20

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

int main(){
    string S;
    cin>>S;
    int N=S.size();
    vector<vector<string>> DP(N+1,vector<string>(N+1,"?"));
    DP[0][0]="";
    for(int i=0;i<=N;i++){
        for(int j=0;j<=N;j++){
            if(DP[i][j]=="?")continue;
            for(int a=0;a<10;a++){
                for(int l=0;l<10;l++){
                    bool OK=1;
                    int ni=i,nj=j;
                    if(a==0){
                        if(S[i]!='0'+l)OK=0;
                        ni++;
                    }
                    else if(l!=0){
                        if(i<a||i+l>N){
                            OK=0;
                        }
                        else for(int k=0;k<l;k++){
                            if(ni-a<0||ni>=N){
                                OK=0;
                                break;
                            }
                            if(S[ni-a]!=S[ni])OK=0;
                            ni++;
                        }
                    }
                    if(l==0){
                        if(S[N-1-j]!='0'+a)OK=0;
                        nj++;
                    }
                    else if(a!=0){
                        // if(N-j<l||j+a>N)OK=0;
                        for(int k=0;k<a;k++){
                            if((N-nj-1)-l<0){
                                OK=0;
                                break;
                            }
                            if(S[(N-nj-1)]!=S[(N-nj-1)-l])OK=0;
                            nj++;
                        }
                    }
                    if(!OK)continue;
                    if(DP[ni][nj]!="?"&&DP[i][j].size()+2>DP[ni][nj].size())continue;
                    // cout<<i<<" "<<j<<" "<<a<<" "<<l<<" "<<ni<<" "<<nj<<" "<<OK<<endl;
                    string NS=DP[i][j];
                    NS.push_back('0'+a);
                    NS.push_back('0'+l);
                    if(DP[ni][nj]=="?"||DP[ni][nj].size()>NS.size()||(DP[ni][nj].size()==NS.size()&&DP[ni][nj]>NS)){
                        DP[ni][nj]=NS;
                    }
                }
            }
            if(j!=N){
              string NNS=".";
              swap(DP[i][j],NNS);
            }
        }
        if(i!=N){
          vector<string> NDP;
          swap(DP[i],NDP);
        }
    }
    cout<<DP[N][N]<<endl;
}
accuracy: 1
time_ms: 770
memory_kb: 13548
final_rank: 15

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

int main(){
    string S;
    cin>>S;
    int N=S.size();
    vector<vector<string>> DP(N+1,vector<string>(N+1,"?"));
    DP[0][0]="";
    for(int i=0;i<=N;i++){
        for(int j=0;j<=N;j++){
            if(DP[i][j]=="?")continue;
            for(int a=0;a<10;a++){
                for(int l=0;l<10;l++){
                    bool OK=1;
                    int ni=i,nj=j;
                    if(a==0){
                        if(S[i]!='0'+l)OK=0;
                        ni++;
                    }
                    else if(l!=0){
                        if(i<a||i+l>N){
                            OK=0;
                        }
                        else for(int k=0;k<l;k++){
                            if(ni-a<0||ni>=N){
                                OK=0;
                                break;
                            }
                            if(S[ni-a]!=S[ni])OK=0;
                            ni++;
                        }
                    }
                    if(l==0){
                        if(S[N-1-j]!='0'+a)OK=0;
                        nj++;
                    }
                    else if(a!=0){
                        // if(N-j<l||j+a>N)OK=0;
                        for(int k=0;k<a;k++){
                            if((N-nj-1)-l<0){
                                OK=0;
                                break;
                            }
                            if(S[(N-nj-1)]!=S[(N-nj-1)-l])OK=0;
                            nj++;
                        }
                    }
                    if(!OK)continue;
                    // cout<<i<<" "<<j<<" "<<a<<" "<<l<<" "<<ni<<" "<<nj<<" "<<OK<<endl;
                    if(DP[ni][nj]=="?"||DP[ni][nj].size()>DP[i][j].size()+2){
                        DP[ni][nj]=DP[i][j];
                        DP[ni][nj].push_back('0'+a);
                        DP[ni][nj].push_back('0'+l);
                    }

                }
            }
        }
    }
    cout<<DP[N][N]<<endl;

}
accuracy: 0.06666666666666667
time_ms: 270
memory_kb: 48592
final_rank: 19

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
 */

pair<int,int> f(int i, int j, int k, int l) {
    int ni, nj;
    if (k == 0) ni = i + 1;
    else ni = i + l;
    if (l == 0) nj = j - 1;
    else nj = j - k;
    return {ni,nj};
}

pair<int,int> g(int i, int j, int k, int l) {
    int pi, pj;
    if (k == 0) pi = i - 1;
    else pi = i - l;
    if (l == 0) pj = j + 1;
    else pj = j + k;
    return {pi, pj};
}

int main() {
    int N;
    string _;
    cin >> _;
    N = _.size();
    vector<int> S(N);
    rep(i,0,N) S[i] = _[i] - '0';
    static bool A[501][501][10][10] = {};
    static bool B[501][501][10][10] = {};
    rep(i,0,N+1) rep(j,0,N+1) rep(k,0,10) rep(l,0,10) A[i][j][k][l] = B[i][j][k][l] = false;
    rep(i,0,N+1) {
        rep(j,0,N+1) {
            rep(k,0,10) {
                rep(l,0,10) {
                    auto [ni,nj] = f(i,j,k,l);
                    if (ni > N || nj < 0) continue;
                    bool check = true;
                    if (k == 0) {
                        if (S[i] != l) check = false;
                    }
                    else {
                        if (l != 0) {
                            if (i - k < 0) check = false;
                            else {
                                rep(m,0,l) {
                                    if (S[i+m] != S[i-k+(m%k)]) check = false;
                                }
                            }
                        }
                    }
                    if (l == 0) {
                        if (S[nj] != k) check = false;
                    }
                    else {
                        if (k != 0) {
                            if (nj - l < 0) check = false;
                            else {
                                rep(m,0,k) {
                                    if (S[nj+m] != S[nj-l+(m%l)]) check = false;
                                }
                            }
                        }
                    }
                    if (check) A[i][j][k][l] = B[ni][nj][k][l] = true;
                }
            }
        }
    }
    vector<vector<int>> DP(N+1,vector<int>(N+1,inf));
    DP[N][0] = 0;
    rrep(i,0,N+1) {
        rep(j,0,N+1) {
            rep(k,0,10) {
                rep(l,0,10) {
                    if (B[i][j][k][l]) {
                        auto [pi,pj] = g(i,j,k,l);
                        chmin(DP[pi][pj], DP[i][j] + 1);
                    }
                }
            }
        }
    }
    string ANS = "";
    int CX = 0, CY = N;
    while(1) {
        if (CX == N && CY == 0) break;
        bool check = false;
        rep(i,0,10) {
            rep(j,0,10) {
                if (!A[CX][CY][i][j]) continue;
                auto [NX,NY] = f(CX,CY,i,j);
                if (DP[NX][NY] == DP[CX][CY] - 1) {
                    ANS += (char)(i+'0');
                    ANS += (char)(j+'0');
                    CX = NX, CY = NY;
                    check = true;
                    break;
                }
            }
            if (check) break;
        }
    }
    cout << ANS << endl;
}
accuracy: 1
time_ms: 480
memory_kb: 53536
final_rank: 14

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

vector<vector<int> > G[509];
vector<vector<int> > RG[509];
long long dp[509][509];

int main() {
	// step #1. input
	string S;
	cin >> S;
	int N = S.size();
	
	// step #2. enumerate transition
	for (int i = 0; i <= N; i++) {
		if (i >= 1) {
			G[i].push_back({ 0, int(S[i - 1] - '0'), i - 1 });
			RG[i - 1].push_back({ 0, int(S[i - 1] - '0'), i });
		}	
		for (int a = 1; a <= 9; a++) {
			for (int l = 0; l <= 9; l++) {
				G[i].push_back({ a, l, i - l });
				RG[i - l].push_back({ a, l, i });
				if (i - l - 1 - a < 0 || S[i - l - 1 - a] != S[i - l - 1]) {
					break;
				}
			}
		}
	}
	
	// step #3. dynamic programming
	const int INF = 1012345678;
	dp[N][0] = 0;
	for (int i = N; i >= 0; i--) {
		for (int j = 0; j <= N; j++) {
			if (i != N || j != 0) {
				dp[i][j] = (1LL << 62);
			}
			for (vector<int> ea : RG[i]) {
				int pl = lower_bound(G[j].begin(), G[j].end(), vector<int>({ ea[1], ea[0], -(1 << 30) })) - G[j].begin();
				if (pl != int(G[j].size()) && G[j][pl][0] == ea[1] && G[j][pl][1] == ea[0]) {
					dp[i][j] = min(dp[i][j], (((dp[ea[2]][G[j][pl][2]] >> 48) + 1) << 48) | ((1LL * ea[0]) << 36) | ((1LL * ea[1]) << 24) | ((1LL * ea[2]) << 12) | G[j][pl][2]);
				}
			}
		}
	}
	
	// step #4. reconstruction of dp
	int ca = 0, cb = N;
	string answer;
	while (ca != N || cb != 0) {
		long long val = dp[ca][cb];
		vector<int> v(5);
		for (int i = 0; i < 5; i++) {
			v[i] = ((val >> (12 * (4 - i))) & 4095);
		}
		answer += char(v[1] + '0');
		answer += char(v[2] + '0');
		ca = v[3];
		cb = v[4];
	}
	
	// step #5. output
	cout << answer << endl;
	
	return 0;
}
accuracy: 1
time_ms: 920
memory_kb: 11284
final_rank: 16

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

int N;
int dp[709][709];
int pre[709][709];
int pre_i[709][709];
int pre_j[709][709];
string S;

int main() {
	// Input
	cin >> S;
	N = S.size();
	
	// Dynamic Programming: Init
	for (int i = 0; i <= N; i++) {
		for (int j = 0; j <= N; j++) {
			dp[i][j] = (1 << 30);
			pre[i][j] = -1;
		}
	}
	dp[0][N] = 0;
	
	// Dynamic Programming
	for (int i = 0; i <= N; i++) {
		for (int j = N; j >= 0; j--) {
			if (dp[i][j] == (1 << 30)) continue;
			
			for (int k = 0; k < 100; k++) {
				int pos1 = (k / 10), nex_i = i;
				int pos2 = (k % 10), nex_j = j;
				
				// Check if left-part is consistent
				bool flag1 = true;
				if (pos1 == 0) {
					if (i == N) flag1 = false;
					else if (S[i] != ('0' + pos2)) flag1 = false;
					nex_i = i + 1;
				}
				else {
					if (i + pos2 > N) flag1 = false;
					else {
						for (int t = 0; t < pos2; t++) {
							int idx = (i + t) - pos1;
							if (idx < 0) { flag1 = false; break; }
							else if (S[i + t] != S[idx]) { flag1 = false; break; }
						}
					}
					nex_i = i + pos2;
				}
				
				// Check if right-part is consistent
				bool flag2 = true;
				if (pos2 == 0) {
					if (j == 0) flag2 = false;
					else if (S[j-1] != ('0' + pos1)) flag2 = false;
					nex_j = j - 1;
				}
				else {
					for (int t = 0; t < pos1; t++) {
						int idx = (j - t - 1) - pos2;
						if (idx < 0) { flag2 = false; break; }
						else if (S[j - t - 1] != S[idx]) { flag2 = false; break; }
					}
					nex_j = j - pos1;
				}
				
				// If All True
				if (flag1 == true && flag2 == true) {
					int val = pos2 * 10 + pos1;
					if (dp[nex_i][nex_j] > dp[i][j] + 1) {
						dp[nex_i][nex_j] = dp[i][j] + 1;
						pre[nex_i][nex_j] = val;
						pre_i[nex_i][nex_j] = i;
						pre_j[nex_i][nex_j] = j;
					}
					else if (dp[nex_i][nex_j] == dp[i][j] + 1 && pre[nex_i][nex_j] > val) {
						pre[nex_i][nex_j] = val;
						pre_i[nex_i][nex_j] = i;
						pre_j[nex_i][nex_j] = j;
					}
				}
			}
		}
	}
	/*for (int i = 0; i <= N; i++) {
		for (int j = 0; j <= N; j++) {
			printf("% 3d", min(99, dp[i][j]));
		}
		cout << endl;
	}*/
	
	// Find Answer
	int ci = N, cj = 0; string Answer = "";
	while (ci != 0 || cj != N) {
		string str = to_string(pre[ci][cj]);
		if (str.size() == 1) str = "0" + str;
		Answer += str;
		int nex_i = pre_i[ci][cj];
		int nex_j = pre_j[ci][cj];
		ci = nex_i;
		cj = nex_j;
	}
	
	// Output
	cout << Answer << endl;
	return 0;
}
accuracy: 1
time_ms: 190
memory_kb: 10220
final_rank: 7

code_snippet: #pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define pb(...) emplace_back(__VA_ARGS__)
#define mp(a, b) make_pair(a, b)
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define rep(i, n) for (int i = 0; i < (n); i++)
#define rep2(i, n) for (int i = (int)n - 1; i >= 0; i--)
#define REP(i, l, r) for (int i = l; i < (r); i++)
#define REP2(i, l, r) for (int i = (int)r - 1; i >= (l); i--)
#define siz(x) (ll) x.size()
template <class T>
using rque = priority_queue<T, vector<T>, greater<T>>;

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

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

template <class T>
void print(vector<T> a) {
    if (a.empty())
        cout << '\n';
    else {
        for (int i = 0; i < a.size(); i++)
            cout << a[i] << (i + 1 == a.size() ? '\n' : ' ');
    }
}

// __int128_t gcd(__int128_t a, __int128_t b) {
//     if (a == 0)
//         return b;
//     if (b == 0)
//         return a;
//     __int128_t cnt = a % b;
//     while (cnt != 0) {
//         a = b;
//         b = cnt;
//         cnt = a % b;
//     }
//     return b;
// }

long long extGCD(long long a, long long b, long long &x, long long &y) {
    if (b == 0) {
        x = 1;
        y = 0;
        return a;
    }
    long long d = extGCD(b, a % b, y, x);
    y -= a / b * x;
    return d;
}

struct UnionFind {
    vector<int> data;
    int num;

    UnionFind(int sz) {
        data.assign(sz, -1);
        num = sz;
    }

    bool unite(int x, int y) {
        x = find(x), y = find(y);
        if (x == y)
            return (false);
        if (data[x] > data[y])
            swap(x, y);
        data[x] += data[y];
        data[y] = x;
        num--;
        return (true);
    }

    int find(int k) {
        if (data[k] < 0)
            return (k);
        return (data[k] = find(data[k]));
    }

    int size(int k) {
        return (-data[find(k)]);
    }

    bool same(int x, int y) {
        return find(x) == find(y);
    }

    int operator[](int k) {
        return find(k);
    }
};

template <int mod>
struct Mod_Int {
    int x;

    Mod_Int() : x(0) {
    }

    Mod_Int(long long y) : x(y >= 0 ? y % mod : (mod - (-y) % mod) % mod) {
    }

    static int get_mod() {
        return mod;
    }

    Mod_Int &operator+=(const Mod_Int &p) {
        if ((x += p.x) >= mod)
            x -= mod;
        return *this;
    }

    Mod_Int &operator-=(const Mod_Int &p) {
        if ((x += mod - p.x) >= mod)
            x -= mod;
        return *this;
    }

    Mod_Int &operator*=(const Mod_Int &p) {
        x = (int)(1LL * x * p.x % mod);
        return *this;
    }

    Mod_Int &operator/=(const Mod_Int &p) {
        *this *= p.inverse();
        return *this;
    }

    Mod_Int &operator++() {
        return *this += Mod_Int(1);
    }

    Mod_Int operator++(int) {
        Mod_Int tmp = *this;
        ++*this;
        return tmp;
    }

    Mod_Int &operator--() {
        return *this -= Mod_Int(1);
    }

    Mod_Int operator--(int) {
        Mod_Int tmp = *this;
        --*this;
        return tmp;
    }

    Mod_Int operator-() const {
        return Mod_Int(-x);
    }

    Mod_Int operator+(const Mod_Int &p) const {
        return Mod_Int(*this) += p;
    }

    Mod_Int operator-(const Mod_Int &p) const {
        return Mod_Int(*this) -= p;
    }

    Mod_Int operator*(const Mod_Int &p) const {
        return Mod_Int(*this) *= p;
    }

    Mod_Int operator/(const Mod_Int &p) const {
        return Mod_Int(*this) /= p;
    }

    bool operator==(const Mod_Int &p) const {
        return x == p.x;
    }

    bool operator!=(const Mod_Int &p) const {
        return x != p.x;
    }

    Mod_Int inverse() const {
        assert(*this != Mod_Int(0));
        return pow(mod - 2);
    }

    Mod_Int pow(long long k) const {
        Mod_Int now = *this, ret = 1;
        for (; k > 0; k >>= 1, now *= now) {
            if (k & 1)
                ret *= now;
        }
        return ret;
    }

    friend ostream &operator<<(ostream &os, const Mod_Int &p) {
        return os << p.x;
    }

    friend istream &operator>>(istream &is, Mod_Int &p) {
        long long a;
        is >> a;
        p = Mod_Int<mod>(a);
        return is;
    }
};

ll mpow2(ll x, ll n, ll mod) {
    ll ans = 1;
    x %= mod;
    while (n != 0) {
        if (n & 1)
            ans = ans * x % mod;
        x = x * x % mod;
        n = n >> 1;
    }
    ans %= mod;
    return ans;
}

ll modinv2(ll a, ll mod) {
    ll b = mod, u = 1, v = 0;
    while (b) {
        ll t = a / b;
        a -= t * b;
        swap(a, b);
        u -= t * v;
        swap(u, v);
    }
    u %= mod;
    if (u < 0)
        u += mod;
    return u;
}

ll devide_int(ll a, ll b) {
    return (a >= 0 ? a / b : (a - b + 1) / b);
}

constexpr int mod = 1000000007;
// constexpr int mod = 998244353;
// constexpr int mod = 31607;
using mint = Mod_Int<mod>;

mint mpow(mint x, ll n) {
    bool rev = n < 0;
    n = abs(n);
    mint ans = 1;
    while (n != 0) {
        if (n & 1)
            ans *= x;
        x *= x;
        n = n >> 1;
    }
    return (rev ? ans.inverse() : ans);
}

// ----- library -------
// ----- library -------

int main() {
    ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    cout << fixed << setprecision(15);

    const int q = (1 << 10) - 1;
    string x;
    cin >> x;
    int n = x.length();
    vector<int> s(n + 1, -1), t(n + 1, -1);
    rep(i, n) s[i] = x[n - 1 - i] - '0', t[i] = x[i] - '0';
    vector<vector<pair<int, int>>> dp(n + 1, vector<pair<int, int>>(n + 1, {1e9, 1e9}));
    vector<vector<int>> last(n + 1, vector<int>(n + 1)), ope(n + 1, vector<int>(n + 1));
    dp[0][0] = {0, 0};
    rep(i, n + 1) rep(j, n + 1) rep(ca, 10) rep(cl, 10) {
        int ni = i, nj = j, a = ca, l = cl;
        if (!a) {
            if (s[i] != l)
                continue;
            ni++;
        } else if (l) {
            if (i + l + a > n)
                continue;
            bool flag = false;
            rep(m, l) {
                if (s[i + m] != s[i + m + a]) {
                    flag = true;
                    break;
                }
            }
            if (flag)
                continue;
            ni += l;
        }
        swap(a, l);
        if (!a) {
            if (t[j] != l)
                continue;
            nj++;
        } else if (l) {
            if (j < a)
                continue;
            bool flag = false;
            rep(m, l) {
                if (t[j + m] != t[j + m - a]) {
                    flag = true;
                    break;
                }
            }
            if (flag)
                continue;
            nj += l;
        }
        if(chmin(dp[ni][nj], {dp[i][j].first + 1, ca << 10 | cl}))
            last[ni][nj] = i << 10 | j, ope[ni][nj] = ca << 10 | cl;
    }
    string ans;
    int ni = n, nj = n;
    while (ni || nj) {
        int nl = last[ni][nj], no = ope[ni][nj];
        ans += (char)('0' + (no / 1024)), ans += (char)('0' + (no % 1024));
        ni = nl / 1024, nj = nl % 1024;
    }
    cout << ans << endl;
}
accuracy: 1
time_ms: 140
memory_kb: 7012
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < n; i++)
#define rep2(i, x, n) for (int i = x; i <= n; i++)
#define rep3(i, x, n) for (int i = x; i >= n; i--)
#define each(e, v) for (auto &e : v)
#define pb push_back
#define eb emplace_back
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define sz(x) (int)x.size()
using ll = long long;
using pii = pair<int, int>;
using pil = pair<int, ll>;
using pli = pair<ll, int>;
using pll = pair<ll, ll>;

template <typename T>
bool chmax(T &x, const T &y) {
    return (x < y) ? (x = y, true) : false;
}

template <typename T>
bool chmin(T &x, const T &y) {
    return (x > y) ? (x = y, true) : false;
}

template <typename T>
int flg(T x, int i) {
    return (x >> i) & 1;
}

template <typename T>
void print(const vector<T> &v, T x = 0) {
    int n = v.size();
    for (int i = 0; i < n; i++) cout << v[i] + x << (i == n - 1 ? '\n' : ' ');
    if (v.empty()) cout << '\n';
}

template <typename T>
void printn(const vector<T> &v, T x = 0) {
    int n = v.size();
    for (int i = 0; i < n; i++) cout << v[i] + x << '\n';
}

template <typename T>
int lb(const vector<T> &v, T x) {
    return lower_bound(begin(v), end(v), x) - begin(v);
}

template <typename T>
int ub(const vector<T> &v, T x) {
    return upper_bound(begin(v), end(v), x) - begin(v);
}

template <typename T>
void rearrange(vector<T> &v) {
    sort(begin(v), end(v));
    v.erase(unique(begin(v), end(v)), end(v));
}

template <typename T>
vector<int> id_sort(const vector<T> &v, bool greater = false) {
    int n = v.size();
    vector<int> ret(n);
    iota(begin(ret), end(ret), 0);
    sort(begin(ret), end(ret), [&](int i, int j) { return greater ? v[i] > v[j] : v[i] < v[j]; });
    return ret;
}

template <typename S, typename T>
pair<S, T> operator+(const pair<S, T> &p, const pair<S, T> &q) {
    return make_pair(p.first + q.first, p.second + q.second);
}

template <typename S, typename T>
pair<S, T> operator-(const pair<S, T> &p, const pair<S, T> &q) {
    return make_pair(p.first - q.first, p.second - q.second);
}

template <typename S, typename T>
istream &operator>>(istream &is, pair<S, T> &p) {
    S a;
    T b;
    is >> a >> b;
    p = make_pair(a, b);
    return is;
}

template <typename S, typename T>
ostream &operator<<(ostream &os, const pair<S, T> &p) {
    return os << p.first << ' ' << p.second;
}

struct io_setup {
    io_setup() {
        ios_base::sync_with_stdio(false);
        cin.tie(NULL);
        cout << fixed << setprecision(15);
    }
} io_setup;

const int inf = (1 << 30) - 1;
const ll INF = (1LL << 60) - 1;
const int MOD = 1000000007;
// const int MOD = 998244353;

int main() {
    string S;
    cin >> S;
    int N = sz(S);

    vector<int> v(N);
    rep(i, N) v[i] = S[i] - '0';

    vector<vector<int>> dp(N + 1, vector<int>(N + 1, inf));
    vector<vector<pii>> pre1(N + 1, vector<pii>(N + 1, pii(-1, -1))), pre2(N + 1, vector<pii>(N + 1, pii(-1, -1)));
    dp[0][0] = 0;

    rep(i, N + 1) rep(j, N + 1) {
        rep(s, 10) rep(t, 10) {
            int pi, pj;
            {
                int a = s, l = t;
                if (a == 0) {
                    if (i == 0) continue;
                    pi = i - 1;
                    if (v[N - i] != l) continue;
                } else if (l == 0) {
                    pi = i;
                } else {
                    if (i < l) continue;
                    pi = i - l;
                    if (N - i - a < 0) continue;
                    if (S.substr(N - i - a, l) != S.substr(N - i, l)) continue;
                }
            }
            {
                int a = t, l = s;
                if (a == 0) {
                    if (j == 0) continue;
                    pj = j - 1;
                    if (v[j - 1] != l) continue;
                } else if (l == 0) {
                    pj = j;
                } else {
                    if (j < l) continue;
                    pj = j - l;
                    if (j < a + l) continue;
                    if (S.substr(j - a - l, l) != S.substr(j - l, l)) continue;
                }
            }
            if (chmin(dp[i][j], dp[pi][pj] + 2)) {
                pre1[i][j] = pii(s, t);
                pre2[i][j] = pii(pi, pj);
            }
        }
    }

    int i = N, j = N;
    assert(dp[N][N] < inf / 2);
    // cout << dp[N][N] << '\n';
    string ans;

    while (i != 0 || j != 0) {
        auto [a, l] = pre1[i][j];
        ans += char('0' + a);
        ans += char('0' + l);
        auto [pi, pj] = pre2[i][j];
        i = pi, j = pj;
    }

    cout << ans << '\n';
}
accuracy: 1
time_ms: 570
memory_kb: 8064
final_rank: 10

code_snippet: #pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define pb(...) emplace_back(__VA_ARGS__)
#define mp(a, b) make_pair(a, b)
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define rep(i, n) for (int i = 0; i < (n); i++)
#define rep2(i, n) for (int i = (int)n - 1; i >= 0; i--)
#define REP(i, l, r) for (int i = l; i < (r); i++)
#define REP2(i, l, r) for (int i = (int)r - 1; i >= (l); i--)
#define siz(x) (ll) x.size()
template <class T>
using rque = priority_queue<T, vector<T>, greater<T>>;

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

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

template <class T>
void print(vector<T> a) {
    if (a.empty())
        cout << '\n';
    else {
        for (int i = 0; i < a.size(); i++)
            cout << a[i] << (i + 1 == a.size() ? '\n' : ' ');
    }
}

// __int128_t gcd(__int128_t a, __int128_t b) {
//     if (a == 0)
//         return b;
//     if (b == 0)
//         return a;
//     __int128_t cnt = a % b;
//     while (cnt != 0) {
//         a = b;
//         b = cnt;
//         cnt = a % b;
//     }
//     return b;
// }

long long extGCD(long long a, long long b, long long &x, long long &y) {
    if (b == 0) {
        x = 1;
        y = 0;
        return a;
    }
    long long d = extGCD(b, a % b, y, x);
    y -= a / b * x;
    return d;
}

struct UnionFind {
    vector<int> data;
    int num;

    UnionFind(int sz) {
        data.assign(sz, -1);
        num = sz;
    }

    bool unite(int x, int y) {
        x = find(x), y = find(y);
        if (x == y)
            return (false);
        if (data[x] > data[y])
            swap(x, y);
        data[x] += data[y];
        data[y] = x;
        num--;
        return (true);
    }

    int find(int k) {
        if (data[k] < 0)
            return (k);
        return (data[k] = find(data[k]));
    }

    int size(int k) {
        return (-data[find(k)]);
    }

    bool same(int x, int y) {
        return find(x) == find(y);
    }

    int operator[](int k) {
        return find(k);
    }
};

template <int mod>
struct Mod_Int {
    int x;

    Mod_Int() : x(0) {
    }

    Mod_Int(long long y) : x(y >= 0 ? y % mod : (mod - (-y) % mod) % mod) {
    }

    static int get_mod() {
        return mod;
    }

    Mod_Int &operator+=(const Mod_Int &p) {
        if ((x += p.x) >= mod)
            x -= mod;
        return *this;
    }

    Mod_Int &operator-=(const Mod_Int &p) {
        if ((x += mod - p.x) >= mod)
            x -= mod;
        return *this;
    }

    Mod_Int &operator*=(const Mod_Int &p) {
        x = (int)(1LL * x * p.x % mod);
        return *this;
    }

    Mod_Int &operator/=(const Mod_Int &p) {
        *this *= p.inverse();
        return *this;
    }

    Mod_Int &operator++() {
        return *this += Mod_Int(1);
    }

    Mod_Int operator++(int) {
        Mod_Int tmp = *this;
        ++*this;
        return tmp;
    }

    Mod_Int &operator--() {
        return *this -= Mod_Int(1);
    }

    Mod_Int operator--(int) {
        Mod_Int tmp = *this;
        --*this;
        return tmp;
    }

    Mod_Int operator-() const {
        return Mod_Int(-x);
    }

    Mod_Int operator+(const Mod_Int &p) const {
        return Mod_Int(*this) += p;
    }

    Mod_Int operator-(const Mod_Int &p) const {
        return Mod_Int(*this) -= p;
    }

    Mod_Int operator*(const Mod_Int &p) const {
        return Mod_Int(*this) *= p;
    }

    Mod_Int operator/(const Mod_Int &p) const {
        return Mod_Int(*this) /= p;
    }

    bool operator==(const Mod_Int &p) const {
        return x == p.x;
    }

    bool operator!=(const Mod_Int &p) const {
        return x != p.x;
    }

    Mod_Int inverse() const {
        assert(*this != Mod_Int(0));
        return pow(mod - 2);
    }

    Mod_Int pow(long long k) const {
        Mod_Int now = *this, ret = 1;
        for (; k > 0; k >>= 1, now *= now) {
            if (k & 1)
                ret *= now;
        }
        return ret;
    }

    friend ostream &operator<<(ostream &os, const Mod_Int &p) {
        return os << p.x;
    }

    friend istream &operator>>(istream &is, Mod_Int &p) {
        long long a;
        is >> a;
        p = Mod_Int<mod>(a);
        return is;
    }
};

ll mpow2(ll x, ll n, ll mod) {
    ll ans = 1;
    x %= mod;
    while (n != 0) {
        if (n & 1)
            ans = ans * x % mod;
        x = x * x % mod;
        n = n >> 1;
    }
    ans %= mod;
    return ans;
}

ll modinv2(ll a, ll mod) {
    ll b = mod, u = 1, v = 0;
    while (b) {
        ll t = a / b;
        a -= t * b;
        swap(a, b);
        u -= t * v;
        swap(u, v);
    }
    u %= mod;
    if (u < 0)
        u += mod;
    return u;
}

ll devide_int(ll a, ll b) {
    return (a >= 0 ? a / b : (a - b + 1) / b);
}

constexpr int mod = 1000000007;
// constexpr int mod = 998244353;
// constexpr int mod = 31607;
using mint = Mod_Int<mod>;

mint mpow(mint x, ll n) {
    bool rev = n < 0;
    n = abs(n);
    mint ans = 1;
    while (n != 0) {
        if (n & 1)
            ans *= x;
        x *= x;
        n = n >> 1;
    }
    return (rev ? ans.inverse() : ans);
}

// ----- library -------
// ----- library -------

int main() {
    ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    cout << fixed << setprecision(15);

    string x;
    cin >> x;
    int n = x.length();
    vector<int> s(n + 1, -1), t(n + 1, -1);
    rep(i, n) s[i] = x[n - 1 - i] - '0', t[i] = x[i] - '0';
    vector<vector<int>> dp(n + 1, vector<int>(n + 1, 1e9)), last(n + 1, vector<int>(n + 1)), ope(n + 1, vector<int>(n + 1));
    dp[0][0] = 0, last[0][0] = -1;
    rep(i, n + 1) rep(j, n + 1) rep(ca, 10) rep(cl, 10) {
        int ni = i, nj = j, a = ca, l = cl;
        if (!a) {
            if (s[i] != l)
                continue;
            ni++;
        } else if (l) {
            if (i + l + a > n)
                continue;
            bool flag = false;
            rep(m, l) {
                if (s[i + m] != s[i + m + a]) {
                    flag = true;
                    break;
                }
            }
            if (flag)
                continue;
            ni += l;
        }
        swap(a, l);
        if (!a) {
            if (t[j] != l)
                continue;
            nj++;
        } else if (l) {
            if (j < a)
                continue;
            bool flag = false;
            rep(m, l) {
                if (t[j + m] != t[j + m - a]) {
                    flag = true;
                    break;
                }
            }
            if (flag)
                continue;
            nj += l;
        }
        if (chmin(dp[ni][nj], dp[i][j] + 1))
            last[ni][nj] = (i << 10) | j, ope[ni][nj] = (ca << 10 | cl);
    }
    string ans;
    int ni = n, nj = n;
    while (ni || nj) {
        int nl = last[ni][nj], no = ope[ni][nj];
        ans += (char)('0' + (no / 1024)), ans += (char)('0' + (no % 1024));
        ni = nl / 1024, nj = nl % 1024;
    }
    reverse(all(ans));
    cout << ans << endl;
}
accuracy: 0.06666666666666667
time_ms: 120
memory_kb: 5872
final_rank: 18

code_snippet: #pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#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;
}


int hs[511][511];
int dp[501][501];
pair<int,int> pre[501][501];
vector<pair<int,int> > g[501][501];
bool flag[501][501];
int main(){
    STR(s);
    fill(dp,inf);
    queue<pair<int,int> > q;
    int n = s.size();
    q.push(MP(0,n));
    for(int i=0;i<n;i++){
        int t = 0;
        for(int j=0;j<10;j++){
            if(i+j>=n)break;
            t += s[i+j]-'0';
            hs[i][i+j+1] = t;
            if(j!=9)t *= 10;
        }
    }

    dp[0][n] = 0;
    while(!q.empty()){
        auto [L,R] = q.front();
        dbg(L,R);
        q.pop();
        int cost = dp[L][R];
        for(int x = 0;x<10;x++){
            for(int y=0;y<10;y++){
                int nL = L,nR = R;
                if(x==0){
                    if(L>=n)continue;
                    if(s[L]!='0'+y)continue;
                    nL++;
                }else{
                    if(y==0){
                        
                    }else{
                        if(L-x<0)continue;
                        if(L+y>n)continue;
                        if(hs[L-x][L-x+y]!=hs[L][L+y])continue;
                        // [L-x,L-x+y) == [L,L+y)
                        // L -> L+y
                        nL += y;
                    }
                }
                if(y==0){
                    if(R==0)continue;
                    if(s[R-1]!='0'+x)continue;
                    nR--;
                }else{
                    if(x==0){

                    }else{
                        if(R-x-y<0)continue;
                        if(R>n)continue;
                        if(hs[R-x][R]!=hs[R-x-y][R-y])continue;
                        // [R-x,R) == [R-x-y,R-y)
                        // R -> R-x
                        nR -= x;
                    }
                }
                if(chmin(dp[nL][nR],cost+1)){
                    g[nL][nR].push_back({L,R});
                    q.push({nL,nR});
                    dbg(L,R,nL,nR,x,y);
                }else if(dp[nL][nR]==cost+1){
                    g[nL][nR].push_back({L,R});
                }
            }
        }
    }
    dbg(dp[n][0]);
    q.push({n,0});
    flag[n][0] = true;
    while(!q.empty()){
        auto [x,y] = q.front();
        q.pop();
        for(auto [nx,ny]:g[x][y]){
            if(!flag[nx][ny]&&dp[nx][ny] == dp[x][y]-1){
                flag[nx][ny] = true;
                q.push(MP(nx,ny));
            }
        }
    }
    dbg(flag[0][n]);
    int L = 0;
    int R = n;
    vector<pair<int,int> >res;
    while(L!=n||R!=0){
        dbg(L,R);
        bool ok = 0;
        for(int x = 0;x<10;x++){
            for(int y=0;y<10;y++){
                int nL = L,nR = R;
                if(x==0){
                    if(L>=n)continue;
                    if(s[L]!='0'+y)continue;
                    nL++;
                }else{
                    if(y==0){
                        
                    }else{
                        if(L-x<0)continue;
                        if(L+y>n)continue;
                        if(hs[L-x][L-x+y]!=hs[L][L+y])continue;
                        // [L-x,L-x+y) == [L,L+y)
                        // L -> L+y
                        nL += y;
                    }
                }
                if(y==0){
                    if(R==0)continue;
                    if(s[R-1]!='0'+x)continue;
                    nR--;
                }else{
                    if(x==0){

                    }else{
                        if(R-x-y<0)continue;
                        if(R>n)continue;
                        if(hs[R-x][R]!=hs[R-x-y][R-y])continue;
                        // [R-x,R) == [R-x-y,R-y)
                        // R -> R-x
                        nR -= x;
                    }
                }
                if(dp[nL][nR] == dp[L][R]+1&&flag[nL][nR]){
                    res.push_back({x,y});
                    ok = 1;
                    L = nL;
                    R = nR;
                    break;
                }
            }
            if(ok)break;
        }
    }
    for(auto [x,y]:res){
        cout << x << y;
    }
    cout << endl;
    return 0;
}
accuracy: 1
time_ms: 170
memory_kb: 126728
final_rank: 12

code_snippet: #pragma GCC optimize("Ofast")
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <queue>
#include <cstdio>
#include <ctime>
#include <assert.h>
#include <chrono>
#include <random>
#include <numeric>
#include <set>
#include <deque>
#include <stack>
#include <sstream>
#include <utility>
#include <cstring>
#include <unordered_map>
#include <unordered_set>
#include <tuple>
#include <array>
#include <bitset>
using namespace std;
typedef long long int ll;
typedef unsigned long long ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) {
    return (ull)rng() % B;
}
inline ll time() {
    return static_cast<long double>(chrono::duration_cast<chrono::nanoseconds>(chrono::steady_clock::now().time_since_epoch()).count()) * 1e-9;
}

const int N = 501;
const int inf = 1e9;
int len[N][N];
pair<int,int> dp[N][N];
pair<int,int> pre[N][N];
bool valid_pre[N][10][10];
bool valid_bac[N][10][10];

void init(string s){
    int n = s.size();
    for(int i=0;i<=n;i++){
        for(int a=0;a<10;a++){
            for(int l=0;l<10;l++){
                if(a == 0){
                    if(i+1<=n and s[i]-'0' == l){
                        valid_pre[i][a][l] = 1;
                    }
                }
                else if(l == 0){
                    valid_pre[i][a][l] = 1;
                }
                else{
                    if(a <= i and i+l<=n){
                        bool ok = true;
                        for(int j=0;j<l;j++){
                            if(s[i+j] != s[i+j-a]){
                                ok = false; break;
                            }
                        }
                        if(ok){
                            valid_pre[i][a][l] = 1;
                        }
                    }
                }
            }
        }
    }

    for(int i=0;i<=n;i++){
        for(int a=0;a<10;a++){
            for(int l=0;l<10;l++){
                if(l == 0){
                    if(i+1<=n and s[n-1-i]-'0' == a){
                        valid_bac[i][a][l] = 1;
                    }
                }
                else if(a == 0){
                    valid_bac[i][a][l] = 1;
                }
                else{
                    if(i+a <= n and n-1-i-a+1 >= l){
                        bool ok = true;
                        for(int j=0;j<a;j++){
                            if(s[n-1-i-j] != s[n-1-i-j-l]){
                                ok = false; break;
                            }
                        }
                        if(ok){
                            valid_bac[i][a][l] = 1;
                        }
                    }
                }
            }
        }
    }

    for(int i=0;i<=n;i++){
        for(int j=0;j<=n;j++){
            len[i][j] = inf;
        }
    }
    len[0][0] = 0;
}

int add(int &a,int &l){
    if(a == 0)return 1;
    else return l;
}

void solve(string s){
    int n = s.size();
    queue<pair<int,int>> q;
    q.push({0,0});
    while(q.size()){
        auto p = q.front(); q.pop();
        int x = p.first, y = p.second;
        if(x == n and y == n)break;
        // cout << x << " " << y << " " << dp[x][y] << endl;
        for(int a=0;a<10;a++){
            for(int l=0;l<10;l++){
                if(valid_pre[x][a][l] and valid_bac[y][a][l]){
                    int nx = x+add(a,l);
                    int ny = y+add(l,a);
                    if(len[nx][ny] == inf){
                        len[nx][ny] = len[x][y]+1;
                        dp[nx][ny] = {a,l};
                        pre[nx][ny] = {x,y};
                        q.push({nx,ny});
                    }
                }
            }
        }
    }
}

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    string s; cin >> s;
    int n = s.size();
    init(s);
    solve(s);
    string res = "";
    pair<int,int> cur = {n,n};
    while(cur.first != 0 or cur.second != 0){
        res += (char)dp[cur.first][cur.second].second + '0';
        res += (char)dp[cur.first][cur.second].first + '0';
        cur = pre[cur.first][cur.second];
    }
    reverse(res.begin(), res.end());
    cout << res << endl;
}
accuracy: 1
time_ms: 30
memory_kb: 8520
final_rank: 3

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

int main(){
    cin.tie(0);
    ios::sync_with_stdio(0);
    
    string s; cin >> s;
    int n = (int)s.size();
    vector<vector<vector<int>>> nt(n + 1, vector<vector<int>>(10, vector<int>(10, -1)));
    vector<vector<vector<int>>> pr(n + 1, vector<vector<int>>(10, vector<int>(10, -1)));
    for(int i = 0; i <= n; i++) {
        for(int A = 0; A <= 9; A++) {
            for(int L = 0; L <= 9; L++) {
                if(A == 0) {
                    if(i + 1 <= n && s[i] == L + '0') {
                        nt[i][A][L] = i + 1;
                    }
                } else if(L == 0) {
                    nt[i][A][L] = i;
                } else if(A <= i) {
                    if(i + L <= n && s.substr(i, L) == s.substr(i - A, L)) {
                        nt[i][A][L] = i + L;
                    }
                }
            }
        }
    }

    for(int i = 0; i <= n; i++) {
        for(int A = 0; A <= 9; A++) {
            for(int L = 0; L <= 9; L++) {
                if(nt[i][A][L] != -1) {
                    pr[nt[i][A][L]][A][L] = i;
                }
            }
        }
    }

    // dp[i][j] := 前からi文字目まで, 後ろからj文字目まで一致
    vector<vector<int>> dp(n + 1, vector<int>(n + 1, 1e9));
    dp[0][n] = 0;
    for(int i = 0; i <= n; i++) {
        for(int j = n; j >= 0; j--) {
            for(int L = 0; L <= 9; L++) {
                for(int A = 0; A <= 9; A++) {
                    int ni = nt[i][A][L], nj = pr[j][L][A];
                    if(ni != -1 && nj != -1) {
                        dp[ni][nj] = min(dp[ni][nj], dp[i][j] + 1);
                    }
                }
            }
        }
    }

    string ans = "";
    int i = n, j = 0;
    while(i != 0 || j != n) {
        int dp_mi = 1e9;
        int ni = -1, nj = -1, nA = -1, nL = -1;
        for(int L = 0; L <= 9; L++) {
            for(int A = 0; A <= 9; A++) {
                int pi = pr[i][A][L], pj = nt[j][L][A];
                if(pi != -1 && pj != -1) {
                    if(dp_mi > dp[pi][pj]) {
                        dp_mi = dp[pi][pj];
                        ni = pi; nj = pj; nA = A;  nL = L;
                    }
                }
            }
        }
        i = ni; j = nj;
        ans += (char)(nL + '0');
        ans += (char)(nA + '0');
    }
    cout << ans << endl;
}
accuracy: 1
time_ms: 30
memory_kb: 4896
final_rank: 1

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

int main(){
    cin.tie(0);
    ios::sync_with_stdio(0);
    
    string s; cin >> s;
    int n = (int)s.size();
    vector<vector<vector<int>>> nt(n + 1, vector<vector<int>>(10, vector<int>(10, -1)));
    vector<vector<vector<int>>> pr(n + 1, vector<vector<int>>(10, vector<int>(10, -1)));
    for(int i = 0; i <= n; i++) {
        for(int A = 0; A <= 9; A++) {
            for(int L = 0; L <= 9; L++) {
                if(A == 0) {
                    if(i + 1 <= n && s[i] == L + '0') {
                        nt[i][A][L] = i + 1;
                    }
                } else if(L == 0) {
                    nt[i][A][L] = i;
                } else if(A <= i) {
                    if(i + L <= n && s.substr(i, L) == s.substr(i - A, L)) {
                        nt[i][A][L] = i + L;
                    }
                }
            }
        }
    }

    for(int i = 0; i <= n; i++) {
        for(int A = 0; A <= 9; A++) {
            for(int L = 0; L <= 9; L++) {
                if(nt[i][A][L] != -1) {
                    pr[nt[i][A][L]][A][L] = i;
                }
            }
        }
    }

    // dp[i][j] := 前からi文字目まで, 後ろからj文字目まで一致
    vector<vector<int>> dp(n + 1, vector<int>(n + 1, 1e9));
    dp[0][n] = 0;
    for(int i = 0; i <= n; i++) {
        for(int j = n; j >= 0; j--) {
            for(int L = 0; L <= 9; L++) {
                for(int A = 0; A <= 9; A++) {
                    int ni = nt[i][A][L], nj = pr[j][L][A];
                    if(ni != -1 && nj != -1) {
                        dp[ni][nj] = min(dp[ni][nj], dp[i][j] + 1);
                    }
                }
            }
        }
    }

    string ans = "";
    int i = n, j = 0;
    while(i != 0 || j != n) {
        int dp_mi = 1e9;
        int ni = -1, nj = -1, nA = -1, nL = -1;
        for(int L = 0; L <= 9; L++) {
            for(int A = 0; A <= 9; A++) {
                int pi = pr[i][A][L], pj = nt[j][L][A];
                if(pi != -1 && pj != -1) {
                    if(dp_mi > dp[pi][pj]) {
                        dp_mi = dp[pi][pj];
                        ni = pi; nj = pj; nA = A;  nL = L;
                    }
                }
            }
        }
        i = ni; j = nj;
        ans += (char)(nL + '0');
        ans += (char)(nA + '0');
    }
    cout << ans << endl;
}
accuracy: 1
time_ms: 30
memory_kb: 4900
final_rank: 2