// 2011アジア地区予選 H : ASCII Expression #include #include #include using namespace std; const int MOD = 2011; int parseArea(vector &vs, int top, int bottom, int left, int right); int parseExpr(vector &vs, int &pos, int line, int top, int bottom, int left, int right); int parseTerm(vector &vs, int &pos, int line, int top, int bottom, int left, int right); int parseFactor(vector &vs, int &pos, int line, int top, int bottom, int left, int right); int parsePowexpr(vector &vs, int &pos, int line, int top, int bottom, int left, int right); int parsePrimary(vector &vs, int &pos, int line, int top, int bottom, int left, int right); int parseFraction(vector &vs, int &pos, int line, int top, int bottom, int left, int right); int modpow(int a, int p){ if(p==0) return 1; int res = modpow(a, p/2); res = (res*res)%MOD; if(p%2==1) res = (res*a)%MOD; return res; } int inv(int x){ return modpow(x, MOD-2); } int parseArea(vector &vs, int top, int bottom, int left, int right){ for( ; ;left++){ bool flag = true; for(int i=top;i<=bottom;i++) if(vs[i][left]!='.') flag = false; if(!flag) break; } for( ; ;right--){ bool flag = true; for(int i=top;i<=bottom;i++) if(vs[i][right]!='.') flag = false; if(!flag) break; } for(int i=top;i<=bottom;i++){ int pos = left; if(vs[i][left]!='.') return parseExpr(vs, pos, i, top, bottom, left, right); } return 0; } // expr : term (+-) term (+-) ... (+-) term int parseExpr(vector &vs, int &pos, int line, int top, int bottom, int left, int right){ int res = parseTerm(vs, pos, line, top, bottom, left, right); while(pos <= right && (vs[line][pos]=='+' || vs[line][pos]=='-')){ bool add = vs[line][pos] == '+'; pos += 2; // "+."または"-."の分をすすめる int x = parseTerm(vs, pos, line, top, bottom, left, right); if(add) res = (res+x)%MOD; else res = (res+MOD-x)%MOD; } return res; } // term : factor * factor * ... * factor int parseTerm(vector &vs, int &pos, int line, int top, int bottom, int left, int right){ int res = parseFactor(vs, pos, line, top, bottom, left, right); while(pos <= right && vs[line][pos]=='*'){ pos += 2; // "*." の分をすすめる int x = parseFactor(vs, pos, line, top, bottom, left, right); res = (res*x)%MOD; } return res; } // factor : powexpr | fraction | -.factor int parseFactor(vector &vs, int &pos, int line, int top, int bottom, int left, int right){ if(vs[line][pos]!='-') return parsePowexpr(vs, pos, line, top, bottom, left, right); if(vs[line][pos+1]=='-') return parseFraction(vs, pos, line, top, bottom, left, right); pos += 2; // "-." の分をすすめる return MOD - parseFactor(vs, pos, line, top, bottom, left, right); } int parsePowexpr(vector &vs, int &pos, int line, int top, int bottom, int left, int right){ int res = parsePrimary(vs, pos, line, top, bottom, left, right); if(left<=pos-1&&pos-1<=right&&top<=line-1&&line-1<=bottom&&isdigit(vs[line-1][pos-1])){ res = modpow(res, vs[line-1][pos-1]-'0'); pos++; // 指数の分をすすめる } return res; } // primary : (.expr.) | digit int parsePrimary(vector &vs, int &pos, int line, int top, int bottom, int left, int right){ int res = 0; if(isdigit(vs[line][pos])){ res = vs[line][pos]-'0'; pos += 2; // 数字+'.' の分をすすめる } else { // if(vs[line][pos] == '(') pos += 2; // '(.' の分を進める res = parseExpr(vs, pos, line, top, bottom, left, right); pos += 2; // ').' の分を進める } return res; } int parseFraction(vector &vs, int &pos, int line, int top, int bottom, int left, int right){ int end = pos; while(end <= right && vs[line][end]=='-') end++; int x = parseArea(vs, top, line-1, pos, end-1); int y = parseArea(vs, line+1, bottom, pos, end-1); pos = end+1; return (x*inv(y))%MOD; } int main(){ int n; while(cin >> n, n){ vector vs(n); for(int i=0;i> vs[i]; cout << parseArea(vs, 0, n-1, 0, vs[0].size()-1) << endl; } }