Problem:
小野小町の編集合戦

近所に住む秋田博士は在野の歴史研究家であり, 最近小野小町に関する新たな古文書を発見したそうだ.

小野小町が交際を望む深草少将に100夜欠かさず通い続けることを条件に出したという伝説は広く知られているが, 彼の主張によると, この発見により新たに, 2人は毎晩とあるゲームをしていたことがわかったという.

そのルールは以下の通りである.

最初に召使が編集回数と有効な数式を決める

深草少将, 小野小町, 深草少将, 小野小町,... という順に交互に数式を編集する

深草少将と小野小町が合わせて召使が決めた回数の編集を行うとゲームは終了する

1回の数式の編集において, 数式に 1 文字追加, または数式から 1 文字削除のいずれかができる

数式が無効になるような編集をしてはならない

有効な数式の詳しい定義は下記を見てほしい.

このゲームにおいて, 最終的な数式の計算結果が大きいほど,
深草少将の通うべき日数を減らしてあげることになっていたらしい.
すなわち, 深草少将は結果を最大化させることが目的であり,
小野小町は最小化させることが目的である.

ところで, 古文書には召使が決めた編集回数と数式については記録が残っていたのであるが,
肝心の結果の方は虫食いにより読めなくなってしまっていた.
博士は結果に興味を持ち, 自力で計算してみようと思ったものの, ゲーム理論が得意でない彼には難しすぎたため, とりあえず近所のあなたに助けを求めてきたようだ.
そこであなたはプログラムを書いて彼に協力することにした.

平安時代に現代的な数式があったということに胡散臭さを感じるかもしれないが, 近所付き合いという大義の前に, そのような些事を気にするべきではないのだ.

有効な数式の定義

このゲームにおける有効な数式とは, "(", ")", "*", "+", "-", "&", "^", "|", "0" - "9" の 18 種類の文字のみからなる空でない文字列であり,
さらに, 有限個の項を2項演算子で結合したものである.
書き下すと,

[項][2項演算子][項][2項演算子]...[2項演算子][項]

のようになる.

項とは, "("[有効な数式]")" のようにカッコで挟まれた有効な数式, または正の整数である.
正の整数は, 先頭に "0" を持たない, 数字のみからなる文字列である.

最後に, 2項演算子とは, "*", "+", "-", "&", "^", "|" のいずれかちょうど 1 文字である.
詳しい定義は下記を見てほしい.

以上の規則から,

"1+-1" のように2文字あるので有効な2項演算子でないもの,

"+1" のように項を2項演算子で結合したものでないもの,

"2)", "(3" のようにカッコの対応がとれていないので有効な項でないもの,

"0", "01" のように 0 で始まり有効な正の整数の表現でないもの

などは, 無効な数式であるとみなされる.

一方で,

"(1+2)" のように最も外側にカッコが付いているもの,

"((1+2))*3" のように2重にカッコが付いているもの,

"(1)+3" のように括弧内に数しかないもの,

"(1*2)+3" のように2項演算子の優先順位と同じになるもの,

などは, 冗長ではあるが, 上の規則の下では受理され, 有効な数式とみなされることに注意してほしい.

2項演算子の種類

このゲームにおいて, 2項演算子は "*", "+", "-", "&", "^", "|" の 6 種類がある.
それぞれ, 乗算, 加算, 減算, ビットごとの論理積, ビットごとの排他的論理和, ビットごとの論理和である.
なお, ビット演算を考えるとき, 負の数は十分大きな桁数の2の補数で表現されていると見なされる. すなわち, 普通の符号付き整数型で計算すると考えてもよい.

また, 優先順位は高い方から,

*

+, -

&

^

|

の順である.

なお, + より * の方が優先順位が高いとは,

2*4+3*5

のような式において * のほうが先に計算されるという意味であり, 言い換えると,

(2*4)+(3*5)

となるということである.

また, すべての2項演算子は左結合であるとする.
これは,

2^4^3^5

のような式において左から順に計算するという意味であり, 言い換えると,

((2^4)^3)^5

となるということである.

Input

入力は複数のデータセットから構成される. 各データセットは1回のゲームで召使が決めた編集回数と数式を表し, その形式は以下の通りである.

N Expression

N は召使が決めた編集回数であり, 1 ≤ N ≤ 11 と仮定してよい.
また, Expression は召使が決めた数式であり, "(", ")", "*", "+", "-", "&", "^", "|", "0" - "9" の 18 種類の文字のみからなる, 7 文字以下の空でない文字列として与えられる.
なお, 上で定義した有効な数式のみが与えられ, 無効な数式が与えられることはないと仮定してよい.

入力の終わりは,

0 #

で表される.

なお, データセットは 99 個以下であると仮定してよい.

Output

各データセットに対して, 両者が最善を尽くしたときの最終的な数式の計算結果を 1 行で出力せよ.
それ以外の余計な文字を出力してはならない.

Sample Input

1 1
2 2
3 1+2*3-4
3 1|2^3&4
3 (1+2)*3
3 1-1-1-1
0 #

Output for Sample Input

91
2
273
93
279
88

Solution in C++ (judge verdict: Accepted)

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

#define rep(i, n)       rep2 (i, 0, n)
#define rep2(i, m, n)   for (int i = m; i < int(n); ++i)

typedef long long ll;

int cur, sz;
string str;

ll parse_num() {
    int a = 0;
    if (cur >= sz || !isdigit(str[cur]) || str[cur] == '0') throw "invalid";
    while (cur < sz && isdigit(str[cur]))
        a = a * 10 + (str[cur++] - '0');
    return a;
}
ll parse_or();
ll parse_fact() {
    if (cur < sz && str[cur] == '(') {
        ++cur;
        int a = parse_or();
        if (cur >= sz || str[cur++] != ')') throw "invalid";
        return a;
    }
    return parse_num();
}
ll parse_term() {
    ll a = parse_fact();
    while (cur < sz && str[cur] == '*') ++cur, a *= parse_fact();
    return a;
}
ll parse_plus() {
    ll a = parse_term();
    while (cur < sz && (str[cur] == '+' || str[cur] == '-')) {
        char op = str[cur++];
        ll b = parse_term();
        op == '+' ? a += b : a -= b;
    }
    return a;
}
ll parse_and() {
    ll a = parse_plus();
    while (cur < sz && str[cur] == '&') ++cur, a &= parse_plus();
    return a;
}
ll parse_xor() {
    ll a = parse_and();
    while (cur < sz && str[cur] == '^') ++cur, a ^= parse_and();
    return a;
}
ll parse_or() {
    ll a = parse_xor();
    while (cur < sz && str[cur] == '|') ++cur, a |= parse_xor();
    return a;
}
ll parse() {
    cur = 0;
    sz = str.size();
    ll a = parse_or();
    if (cur < sz) throw "invalid";
    return a;
}

vector<string> next() {
    vector<string> res;
    string tmp, ch = "0123456789*+-&^|";
    rep (i, str.size() + 1) {
        tmp = str;
        tmp.insert(i, 1, ' ');
        rep (j, 16) { tmp[i] = ch[j]; res.push_back(tmp); }
    }
    rep (i, str.size()) {
        tmp = str;
        tmp.erase(i, 1);
        res.push_back(tmp);
    }
    return res;
}

int main()
{
    int n;
    while (cin >> n >> str, n) {
        ll a = -1e18;
        vector<string> v = next();
        if (n % 2 == 1) {
            rep (i, v.size()) {
                str = v[i];
                try { a = max(a, parse()); } catch (...) {}
            }
        } else {
            rep (i, v.size()) {
                str = v[i];
                try { parse(); } catch (...) { continue; }
                ll b = 1e18;
                vector<string> w = next();
                rep (j, w.size()) {
                    str = w[j];
                    try { b = min(b, parse()); } catch (...) {}
                }
                a = max(a, b);
            }
        }
        cout << a << endl;
    }
}