import sys # 再帰制限の緩和 sys.setrecursionlimit(5000) def main(): # 高速I/O: 一括読み込み input_data = sys.stdin.read().split() if not input_data: return n_str = input_data[0] length_n = len(n_str) # ターゲット比較用の数値リスト(毎回文字をint変換するコストを省く) target_digits = [int(c) for c in n_str] # DFS用のカウント配列 counts = [0] * 10 # 答えの格納用(リストにして参照渡し可能にする) # best_ans[0] に現在の暫定最小解を保持 best_ans = [None] # ----------------------------------------------------- # 内部関数: 桁数分布から最小の数値を構築 # ----------------------------------------------------- def solve_recursive(idx, tight, current_counts): if idx == length_n: return [] start = target_digits[idx] if tight else 0 # 0-9のループ for d in range(start, 10): if current_counts[d] > 0: current_counts[d] -= 1 next_tight = tight and (d == start) if not next_tight: # 制約が外れたら残りは辞書順最小(昇順)で埋める res = [str(d)] # 0から9まで順に残りの個数分追加 for k in range(10): c = current_counts[k] if c > 0: res.append(str(k) * c) current_counts[d] += 1 # backtrack return res # 制約が続く場合 res = solve_recursive(idx + 1, next_tight, current_counts) if res is not None: current_counts[d] += 1 # backtrack return [str(d)] + res current_counts[d] += 1 # backtrack return None def find_smallest(current_counts, total_digits, target_str_len): # ケース1: 桁数がターゲットより多い場合 -> 最小の非ゼロを先頭、残りを昇順 if total_digits > target_str_len: for d in range(1, 10): if current_counts[d] > 0: current_counts[d] -= 1 res = [str(d)] for k in range(10): c = current_counts[k] if c > 0: res.append(str(k) * c) current_counts[d] += 1 # backtrack return "".join(res) return None # ケース2: 桁数が同じ場合 -> target以上になる最小の並びを探す res_list = solve_recursive(0, True, current_counts) if res_list is not None: return "".join(res_list) return None # ----------------------------------------------------- # 内部関数: セグメント整合性チェック (最深部) # ----------------------------------------------------- def check_and_update(cnt, L): # 配列アクセスを減らすためローカル変数に展開 c0, c1, c2, c3, c4, c5, c6, c7, c8, c9 = cnt # パリティチェック (s2 + s4) % 2 != 0 なら不可 # s2 = L - c2 # s4 = c0 + c2 + c6 + c8 # sum_check = L + c0 + c6 + c8 (mod 2) if (L + c0 + c6 + c8) & 1: return # 基本となる base の計算 # s2 = L - c2 # s4 = c0 + c2 + c6 + c8 # base = (s2 + s4) // 2 # 展開して計算: base = (L + c0 + c6 + c8) >> 1 # 各数字の必要数を計算し、持っている個数(cnt)と比較 # 計算順序を工夫して早期returnを狙う # s4 は既出 s4 = c0 + c2 + c6 + c8 one = base - s4 if one < 0 or one > c1: return s3 = c0 + c2 + c3 + c5 + c6 + c8 + c9 nine = s3 - base if nine < 0 or nine > c9: return s1 = c0 + c1 + c2 + c3 + c4 + c7 + c8 + c9 zero = s1 - one - base if zero < 0 or zero > c0: return s5 = c0 + c4 + c5 + c6 + c8 + c9 seven = base - (s5 - zero + one) if seven < 0 or seven > c7: return s0 = c0 + c2 + c3 + c5 + c6 + c7 + c8 + c9 six = s0 - zero - base if six < 0 or six > c6: return # 最後の整合性チェック # 変数定義に使わなかった独立な式 s6 について検証が必要 # s6 + zero == base s6 = c2 + c3 + c4 + c5 + c6 + c8 + c9 if s6 + zero != base: return # ここまで到達すれば有効な構成 candidate = find_smallest(cnt, L, length_n) if candidate is not None: # 暫定解との比較 curr_best = best_ans[0] if curr_best is None: best_ans[0] = candidate else: # 文字列長、次いで辞書順比較 len_cand = len(candidate) len_best = len(curr_best) if len_cand < len_best: best_ans[0] = candidate elif len_cand == len_best and candidate < curr_best: best_ans[0] = candidate # ----------------------------------------------------- # DFS # ----------------------------------------------------- def dfs(digit, remaining, counts, L): if digit == 9: counts[9] = remaining check_and_update(counts, L) counts[9] = 0 # backtrack return # counts[digit] を 0 から remaining まで試す for i in range(remaining + 1): counts[digit] = i dfs(digit + 1, remaining - i, counts, L) counts[digit] = 0 # backtrack # ----------------------------------------------------- # メインループ # ----------------------------------------------------- # 長さ L を Nの長さ から 20 まで探索 for l in range(length_n, 21): best_ans[0] = None dfs(0, l, counts, l) if best_ans[0] is not None: print(best_ans[0]) break if __name__ == '__main__': main()