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

int power[2011][2011], divis[2011][2011], mod = 2011;

void init() {
	for (int i = 0; i < 2011; i++) {
		power[i][0] = 1; for (int j = 1; j < 2011; j++) power[i][j] = (power[i][j - 1] * i) % mod;
	}
	for (int i = 0; i < 2011 * 2011; i++) divis[i / 2011][i % 2011] = -1;
	for (int i = 0; i < 2011; i++) {
		for (int j = 0; j < 2011; j++) {
			if (divis[(i * j) % mod][i] == -1) divis[(i * j) % mod][i] = j;
		}
	}
}

int modpow(int a, int b) { return power[a][b]; }
int Div(int a, int b) { return divis[a][b]; }

int solve(vector<string> A) {
	/*cout << endl;
	for (int i = 0; i < A.size(); i++) cout << A[i] << endl;
	cout << endl;*/

	// ---------------------------------------- Step 1: 式を圧縮する ---------------------------------
	int px = (1 << 30), py = (1 << 30), qx = 0, qy = 0;
	for (int i = 0; i < A.size(); i++) {
		for (int j = 0; j < A[0].size(); j++) {
			if (A[i][j] == '.') continue;
			px = min(px, i); py = min(py, j);
			qx = max(qx, i); qy = max(qy, j);
		}
	}

	// ---------------------------------------- Step 2: パースする -----------------------------------
	vector<string>B;
	for (int i = px; i <= qx; i++) B.push_back(A[i].substr(py, qy - py + 1));

	int BASE = 0, H = B.size(), W = B[0].size();
	for (int i = 0; i < H; i++) {
		if (B[i][0] != '.') { BASE = i; }
	}

	if (H == 1 && W == 1) return (B[0][0] - '0');

	vector<pair<int, int>>vec; int depth = 0; bool IsDiv = false;
	for (int i = 0; i < W; i++) {
		if (B[BASE][i] == '(') depth++;
		if (B[BASE][i] == ')') depth--;
		if (depth == 0) {
			if (B[BASE][i] == '+') vec.push_back(make_pair(i, 1));
			if (B[BASE][i] == '-' && (i != W - 1 && B[BASE][i + 1] != '-') && (i != 0 && B[BASE][i - 1] != '-')) {
				bool ok = false;
				if (i == 0) ok = true;
				if (i >= 2) {
					if (B[BASE][i - 2] == '+') ok = true;
					if (B[BASE][i - 2] == '*') ok = true;
					if (B[BASE][i - 2] == '-' && (i == 2 || B[BASE][i - 3] != '-')) ok = true;
				}
				if (ok == false) vec.push_back(make_pair(i, 2));
			}
			if (B[BASE][i] == '-') IsDiv = true;
		}
	}

	// ---------------------------------------- Step 3: '+', '-' が存在する場合 ----------------------
	if (vec.size() >= 1) {
		vector<pair<int, int>>vec3;
		vec3.push_back(make_pair(-1, 1));
		for (int i = 0; i < vec.size(); i++) vec3.push_back(vec[i]);
		vec3.push_back(make_pair(W, 1));

		bool ok = false; int res = 0;
		for (int i = 1; i < vec3.size(); i++) {
			if (vec3[i].first - vec3[i - 1].first == 2) {
				if (vec3[i].second == 2) ok ^= true;
			}
			else {
				vector<string>A3;
				for (int j = 0; j < H; j++) A3.push_back(B[j].substr(vec3[i - 1].first + 1, (vec3[i].first - 1) - (vec3[i - 1].first + 1) + 1));

				int rem = solve(A3);
				if (ok == false) res += rem; else res -= rem;
				res += mod; res %= mod;

				if (vec3[i].second == 1) ok = false;
				else ok = true;
			}
		}
		return res;
	}

	// ---------------------------------------- Step 3.5: マイナスの処理 -----------------------------
	if (B[BASE][0] == '-' && (W >= 2 && B[BASE][1] == '.')) {
		vector<string>A4;
		for (int i = 0; i < H; i++) A4.push_back(B[i].substr(1, W - 1));
		int p1 = solve(A4);
		return (mod - p1) % mod;
	}

	// ---------------------------------------- Step 4: パース 2 個目 --------------------------------
	vector<int>vec2; depth = 0;
	for (int i = 0; i < W; i++) {
		if (B[BASE][i] == '(') depth++;
		if (B[BASE][i] == ')') depth--;
		if (B[BASE][i] == '*' && depth == 0) vec2.push_back(i);
	}

	// ---------------------------------------- Step 5: '*' が存在する場合 ---------------------------
	if (vec2.size() >= 1) {
		vector<int>vec3; vec3.push_back(-1);
		for (int i = 0; i < vec2.size(); i++) vec3.push_back(vec2[i]);
		vec3.push_back(W);

		int muls = 1;
		for (int i = 0; i < vec3.size() - 1; i++) {
			vector<string>A5;
			for (int j = 0; j < H; j++) A5.push_back(B[j].substr(vec3[i] + 1, (vec3[i + 1] - 1) - (vec3[i] + 1) + 1));
			int ret = solve(A5); muls *= ret; muls %= mod;
		}
		return muls;
	}

	// ---------------------------------------- Step 6: '/' が存在する場合 ---------------------------
	if (IsDiv == true) {
		vector<string>A6a, A6b;
		for (int i = 0; i < BASE; i++) A6a.push_back(B[i]);
		for (int i = BASE + 1; i < H; i++) A6b.push_back(B[i]);

		int v1 = solve(A6a), v2 = solve(A6b);
		int rets = Div(v1, v2);
		return rets;
	}

	// ---------------------------------------- Step 7: '(' が存在する場合 ---------------------------
	if (B[BASE][0] == '(' && B[BASE][W - 1] == ')') {
		vector<string> A7;
		for (int i = 0; i < H; i++) A7.push_back(B[i].substr(1, W - 2));
		return solve(A7);
	}

	// ---------------------------------------- Step 8: その他の場合（累乗） -------------------------
	int pows = (B[BASE - 1][W - 1] - '0');
	vector<string>A8;
	for (int i = 0; i < H; i++) A8.push_back(B[i].substr(0, W - 1));
	int C8 = solve(A8);
	return modpow(C8, pows);
}

int main() {
	init();
	while (true) {
		int n; cin >> n; if (n == 0) break;
		vector<string>vec;
		for (int i = 0; i < n; i++) { string str; cin >> str; vec.push_back(str); }

		cout << solve(vec) << endl;
	}
	return 0;
}


Measured memory_bytes: 34660