Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

ゴルフ

クロセは超一流の腕を持ったバトルプログラマーであり，プログラミングコンテスト界隈でその名を知らぬ者はいない．
アルゴリズム，データマイニング，ハッキング，AI，……ありとあらゆる大会を総なめにしてきた．
そんなクロセが次の目標に据えた競技は，「コードゴルフ」である．

コードゴルフとは，与えられた問題に対し正答を返すプログラムの「ソースコードの短さ」を競う競技である．
コードゴルフにおいては，異なるプログラミング言語間で公平な比較が難しいため，使用言語が限定されることが多い．
クロセが次に狙っている大会「ICPC (International Competition of Program Compactness)」では，
「AJAGOL」と呼ばれるプログラミング言語のみが使用できるルールとなっている．
コードを1バイトでも短くするため，クロセが初めに注目したのは，「定数宣言」の短縮だった．

AJAGOLはいにしえの36bitアーキテクチャに最適化して設計された伝統ある言語である．
整数を表現するために36bit符号無し整数型が用意されており，$0$ 以上 $2^{36}-1$ 以下の整数を扱うことができる．
さて，AJAGOLの定数は通常，数字[0-9]を任意の個数用いた十進数で宣言される．
また，演算子として以下の表の演算子を用いることができる．

優先順位

演算子

結合性

意味

1

( , )

-

括弧

2

^

右結合

冪乗: a^b := $a^b$

3

*

左結合

乗算: a*b := $a \times b$

3

/

左結合

除算: a/b := $ \lfloor a \div b \rfloor$

4

+

左結合

加算: a+b := $a + b$

4

-

左結合

減算: a-b := $a - b$

ここで，優先順位の値が小さい演算ほど優先的に計算され，同じ値のときには結合性に従った順序で計算される．
例えば "2^2^3+8/3*2" という計算式は，2^2^3+8/3*2 = 2^8+8/3*2 = 256+8/3*2 = 256+2*2 = 256+4 = 260 という順序で計算される．
また，演算途中の値が $[0, 2^{36}-1]$ に収まらない計算やゼロ除算，ゼロのゼロ乗は，AJAGOLでは実行時エラーとなるため避ける必要がある．
例えば "2^36-100"，"1111/0"，"(2-2)^0" などは実行時エラーとなる．

超一流のバトルプログラマーであるクロセは，これらの演算子を用いることにより，通常よりも短い定数宣言が可能であることを見抜いた．
例えば，117649は言わずと知れた $7^6$ であるが，AJAGOLの冪乗演算子を用いることで "7^6" と3バイトで書くことができる．
これは通常の "117649" という宣言で必要となる6バイトよりも3バイト短い．
よって，AJAGOLによるコードゴルフでは，117649を定数として用いたい場合には "7^6" と宣言するのが基本となる．

定数宣言の短縮はコードゴルフにおいて最も基本的なテクニックの1つであるが，あくまで小手先のテクニックとも言える．
このようなところに多大な時間を掛けていては，本質的なコードの短縮に時間を割けなくなってしまう．
そこでクロセは，非負整数を十進数で入力したとき，それを表現するAJAGOL定数宣言として最も短いものを調べることにした．

Input

入力は複数のデータセットからなる．
各データセットは整数 $N$ ($0 \leq N \leq 2^{36}-1$) を含む1行で与えられる．
入力の終了は $-1$ のみを含む1行で表される．

Output

各データセットに対し，与えられた整数 $N$ を表現する最も短いAJAGOL定数宣言の長さを1行で出力せよ．

Sample Input

117649
1
125000
1610612736
68719476636
-1

Output for Sample Input

3
1
4
6
11

Solution in C++14 (judge verdict: Time Limit Exceeded)

//
// Problem: Golf
// Solution by: MORI Shingo
// Prune Search
//
// implement 65min
// debug ?h
// 
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <math.h>
#include <assert.h>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <set>
#include <numeric>

using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
static const long double EPS = 1e-9;
static const long double PI = acos(-1.0);

#define REP(i, n) for (ll i = 0; i < (ll)(n); i++)
#define FOR(i, s, n) for (ll i = (s); i < (ll)(n); i++)
#define FOREQ(i, s, n) for (ll i = (s); i <= (ll)(n); i++)
#define FORIT(it, c) for (__typeof((c).begin())it = (c).begin(); it != (c).end(); it++)
#define MEMSET(v, h) memset((v), h, sizeof(v))

const char op[4] = { '+', '-', '*', '/' };
ll calc(char c, ll lhs, ll rhs) {
  if (c == '+') { return lhs + rhs; }
  if (c == '-') { return lhs - rhs; }
  if (c == '*') { return lhs * rhs; }
  if (c == '/') { return lhs / rhs; }
  assert(false);
  return -1;
}
ll findAns(char c, ll lhs, ll n) {
  assert(lhs > 0);
  if (c == '+') { return n - lhs; }
  if (c == '-') { return lhs - n; }
  if (c == '*') {
    ll v = n / lhs;
    if (lhs * v != n) { return -1; }
    return v;
  }
  if (c == '/') {
    ll v = lhs / n;
    if (v == 0 || lhs / v != n) { return -1; }
    return v;
  }
  assert(false);
  return -1;
}

ll Len(ll v) {
  if (v == 0) { return 1; }
  ll ret = 0;
  while (v > 0) { v /= 10; ret++; }
  return ret;
}
ll MaxValue(ll len) {
  ll ret = 0;
  REP(i, len) { ret = ret * 10 + 9; }
  return ret;
}

struct Str {
  string str;
  ll len;
  ll v;
  Str() {;}
  Str(const char *src, ll v) : v(v) {
    str = src;
    len = strlen(src);
  }
  bool operator<(const Str &rhs) const {
    return len < rhs.len;
  }
};


map<ll, Str> power;
vector<Str> sorted_power;
char str[100];
ll n;
ll ans;
char ans_str[100];
const ll MIN_N = 0;
//const ll MAX_N = (1LL << 31) - 1;
const ll MAX_N = 68719476735LL;
//const ll MAX_N = 99999999999LL;

int main() {
  // Init
  REP(i, sqrt(MAX_N) + 1) {
    ll v = i;
    FOR(j, 2, 100) {
      v *= i;
      if (v > MAX_N) { break; }
      snprintf(str, 99, "%lld", v);
      int l = strlen(str);
      snprintf(str, 99, "%lld^%lld", i, j);
      if (l <= (int)strlen(str) || (power.count(v) && power[v].len <= (int)strlen(str))) {
        continue;
      }
      power[v] = Str(str, v);
    }
  }
  FORIT(it, power) {
    // cout << it->first << " " << it->second.str << endl;
    sorted_power.push_back(it->second);
  }
  sort(sorted_power.begin(), sorted_power.end());

  // calc start
  // FOREQ(n, 0, MAX_N) {
  while (scanf("%lld", &n) > 0 && n != -1) {
    ans = Len(n);
    assert(ans <= 11);
    assert(0 <= n && n <= MAX_N);
    snprintf(ans_str, 99, "%lld", n);
    if (power.count(n)) {
      ans = min(ans, power[n].len);
      snprintf(ans_str, 99, "%s", power[n].str.c_str());
    }
    if (ans <= 4) { goto end; }

    // a^b+-*/c
    // c-/a^b is not needed
    FORIT(it, sorted_power) {
      if (it->len + 2 >= ans) { break; }
      REP(o, 4) {
        ll c = findAns(op[o], it->v, n);
        ll sum = it->len + 1 + Len(c);
        if (0 < c && c <= MAX_N && sum < ans) {
          assert(calc(op[o], it->v, c) == n);
          ans = sum;
          snprintf(ans_str, 99, "%s%c%lld", it->str.c_str(), op[o], c);
        }
      }
    }

    // a^b+-*/c^d
    FORIT(it1, sorted_power) {
      if (it1->len + 4 >= ans) { break; }
      FORIT(it2, sorted_power) {
        ll sum = it1->len + it2->len + 1;
        if (sum >= ans) { break; }
        REP(o, 4) {
          ll v = calc(op[o], it1->v, it2->v);
          if (v == n && sum < ans) {
            ans = sum;
            snprintf(ans_str, 99, "%s%c%s", it1->str.c_str(), op[o], it2->str.c_str());
          }
        }
      }
    }

    // a^b*/c+-*/d
    // (a^b+-c)+-*/d
    FORIT(it, sorted_power) {
      if (it->len + 4 >= ans) { break; }
      FOR(o1, 0, 4) {
        ll bracket = o1 < 2 ? 2 : 0;
        ll restLen = ans - 1 - (it->len + 3 + bracket);
        ll upper = MaxValue(restLen);
        FOREQ(c, 1, upper) {
          ll v = calc(op[o1], it->v, c);
          if (v <= 0 || MAX_N < v) { continue; }
          REP(o2, 4) {
            ll d = findAns(op[o2], v, n);
            ll sum = it->len + Len(c) + Len(d) + 2 + bracket;
            if (sum < ans && 0 < d && d < MAX_N && calc(op[o2], v, d) == n) {
              ans = sum;
              if (bracket) {
                snprintf(ans_str, 99, "(%s%c%lld)%c%lld", it->str.c_str(), op[o1], c, op[o2], d);
              } else {
                snprintf(ans_str, 99, "%s%c%lld%c%lld", it->str.c_str(), op[o1], c, op[o2], d);
              }
            }
          }
        }
      }
    }

    // a^b+-*/c^d+-*/e
    // e+-*/a^b+-*/c^d is not needed
    FORIT(it1, sorted_power) {
      if (it1->len + 4 >= ans) { break; }
      FORIT(it2, sorted_power) {
        if (it1->len + it2->len + 3 >= ans) { break; }
        ll restLen = ans - 1 - (it1->len + it2->len + 2);
        ll upper = MaxValue(restLen);
        FOREQ(e, 1, upper) {
          ll sum = it1->len + it2->len + Len(e)+ 2;
          if (sum >= ans) { break; }
          REP(o1, 4) {
            REP(o2, 4) {
              ll v;
              if (o1 < 2 && op[o2] >= 2) {
                ll rhs = calc(op[o2], it2->v, e);
                if (rhs < 0 || MAX_N < rhs) { continue; }
                v = calc(op[o1], it1->v, rhs);
              } else {
                ll lhs = calc(op[o1], it1->v, it2->v);
                if (lhs < 0 || MAX_N < lhs) { continue; }
                v = calc(op[o2], lhs, e);
              }
              if (v == n) {
                ans = sum;
                snprintf(ans_str, 99, "%s%c%s%c%lld", it1->str.c_str(), op[o1], it2->str.c_str(), op[o2], e);
              }
            }
          }
        }
      }
    }

    // a^b+-*/e+-*/c^d
    FORIT(it1, sorted_power) {
      if (it1->len + 4 >= ans) { break; }
      FORIT(it2, sorted_power) {
        if (it1->len + it2->len + 3 >= ans) { break; }
        ll restLen = ans - 1 - (it1->len + it2->len + 2);
        ll upper = MaxValue(restLen);
        FOREQ(e, 1, upper) {
          ll sum = it1->len + it2->len + Len(e)+ 2;
          if (sum >= ans) { break; }
          REP(o1, 4) {
            REP(o2, 4) {
              ll v;
              if (o1 < 2 && op[o2] >= 2) {
                ll rhs = calc(op[o2], e, it2->v);
                if (rhs < 0 || MAX_N < rhs) { continue; }
                v = calc(op[o1], it1->v, rhs);
              } else {
                ll lhs = calc(op[o1], it1->v, e);
                if (lhs < 0 || MAX_N < lhs) { continue; }
                v = calc(op[o2], lhs, it2->v);
              }
              if (v == n) {
                ans = sum;
                snprintf(ans_str, 99, "%s%c%lld%c%s", it1->str.c_str(), op[o1], e, op[o2], it2->str.c_str());
              }
            }
          }
        }
      }
    }

    // a^b*/c*/d+-*/e
    FORIT(it, sorted_power) {
      if (it->len + 6 >= ans) { break; }
      ll restLen1 = ans - 1 - (it->len + 5);
      ll upper1 = MaxValue(restLen1);
      FOR(o1, 2, 4) {
        FOREQ(c, 1, upper1) {
          ll v1 = calc(op[o1], it->v, c);
          ll restLen2 = ans - 1 - (it->len + Len(c) + 4);
          ll upper2 = MaxValue(restLen2);
          if (v1 <= 0 ||  MAX_N <= v1) { continue; }
          FOR(o2, 2, 4) {
            FOREQ(d, 1, upper2) {
              ll v2 = calc(op[o2], v1, d);
              if (v2 <= 0 ||  MAX_N <= v2) { continue; }
              FOR(o3, 0, 4) {
                ll e = findAns(op[o3], v2, n);
                ll sum = it->len + Len(c) + Len(d) + Len(e) + 3;
                if (0 < e && e <= MAX_N && sum < ans && calc(op[o3], v2, e) == n) {
                  ans = sum;
                  snprintf(ans_str, 99, "%s%c%lld%c%lld%c%lld", it->str.c_str(), op[o1], c, op[o2], d, op[o3], e);
                }
              }
            }
          }
        }
      }
    }
end:
    printf("%lld\n", ans);
    // printf("%lld %s\n", ans, ans_str);
  }
}