Problem:
有限体電卓
0以外のすべての実数の逆数は実数になりますが、整数の逆数が整数になるとは限りません。Ｃ言語などで 3.0/2.0*2.0 = 3.0 なのに 3/2*2 = 2 になってしまうのはこのためです。ですが、素数で割った余りが等しい整数を同じものとみなすと、0以外のすべての整数が逆数をもつようにできます。
整数 x と y を p で割った余りが等しいとき、x ≡ y (mod p) と書きます。p が素数のとき、このような x と y を同じものとみなすなら、すべての整数 n は0から p−1 までのどれかの整数 x に対して x ≡ n (mod p) となるので、けっきょく { 0, 1, 2, ..., p−1 } という集合だけからなる世界を考えればよいことがわかります。
この世界での加減乗除は以下のようになります。
加算 x+y の値は、x+y ≡ z (mod p) となる 0 から p−1 までの数 z になります。
減算 x−yの値は、y+m ≡ 0 (mod p) となる 0 から p−1 までの数 m（これが  y に相当します）について、x−y ≡ x + m (mod p) となることから得られます。たとえば、p = 5のとき、4+1 ≡ 0 (mod 5) となります。このとき、2−4 ≡ 2+1 ≡ 3 (mod 5) より、2−4の値は3になります。
乗算 x*y の値は、x*y ≡ z (mod p) となる 0 から p−1 までの数 z になります。
除算 x/y の値は、y*d ≡ 1 (mod p)となる 0 から p−1 までの数 d （これがyの逆数になります）について、x/y ≡ x*d (mod p) となることから得られます。たとえば、p = 5 のとき、2*3 ≡ 1 (mod 5) より 3 は 2 の逆数になります。このとき、1/2 ≡ 1*3 ≡ 3 (mod 5) より、1/2 の値は 3 になります。
このようにして加減乗除の四則演算がすべて0からp−1の範囲に収まります。このとき、集合 { 0,1,...,p−1 } を p の有限体といいます。この有限体の中で、加減乗除、0 から p−1 までの数、カッコを使って 算術式を構成することができます。
p の有限体の 0 以外のすべての要素が逆数をもつことは、フェルマーの小定理と呼ばれる有名な定理 a
p−1
≡ 1 (mod p) からわかります（ただし、p は素数、a と p は互いに素）。p の有限体のすべての要素 x は p と互いに素なので、この定理から x*x
p-2
≡ 1 (mod p) となり x
p-2
が x の逆数になるからです。
では、素数と式が与えられたときに、その素数の有限体で式を計算する電卓プログラムを作成してください。
入力
入力は複数のデータセットからなる。入力の終わりは0の後にコロンが１つ続くだけの行 0: で示される。各データセットは以下の形式で与えられる。
p:exp
データセットは１行であり、p (2 ≤ p ≤ 46000) は素数、exp は算術式を示す。exp は加減乗除（それぞれ +, -, *, /）とカッコ、0 から p−1 までの数から構成される。演算子、数、カッコなどの前後には1つ以上の空白が現れる可能性がある。exp の長さは 100,000 を超えない。
データセットの数は 1000 を超えない。
出力
データセットごとに、計算結果を出力する。出力形式は以下の通りである。
exp = val (mod p)
val は、p の有限体での算術式 exp の計算結果である。ただし、0 での除算が含まれるときは NG と出力する。また、exp に現れる加減乗除、カッコ、数の前後には空白を空けないこと。ただし、= の前後には空白を一つずつ空ける。また、valと開きカッコの間、modとp の間にも空白を一つずつ空ける。
入力例
5: 2 - 3
17: 1 + 3 * (2 + 3 / 5 * 2) + 7
11: 1 / 8 - 5 - 8 * 2
19: 8 / (2 - 3 * 7)
1153: 10 * 3 / 7 + ( 50 + 81 / 22 ) + 11
0:
出力例
2-3 = 4 (mod 5)
1+3*(2+3/5*2)+7 = 4 (mod 17)
1/8-5-8*2 = 8 (mod 11)
NG
10*3/7+(50+81/22)+11 = 915 (mod 1153)

Submitted solutions:

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define FOR(i,s,t) for(int i = s; i < t ; ++i)
#define ALL(a) a.begin(),a.end()
#define SORT(a) sort(ALL(a))
#define UNIQ(a) a.erase(unique(ALL(a)),a.end())
#define debug(a) cerr<<#a":="<<a<<endl;
#define SZ(a) (int)a.size()
using LL = long long; template<class T> using V = vector <T>; template <class T> using VV = V<V<T>>;


LL powmod(LL a, LL x, LL mod) {
	LL ret = 1;
	while (x) {
		if (x % 2) {
			ret *= a;
			ret %= mod;
		}
		a *= a;
		a %= mod;
		x >>= 1;
	}
	return ret;
}
string spa(const string &s) {
	string ret = "";
	FOR(i, 0, SZ(s)) {
		if (s[i] != ' ') {
			ret += string(1, s[i]);
		}
	}
	return ret;
}
LL getnum(string & s, int &i) {
	LL ret = 0;
	while (isdigit(s[i])) {
		ret *= 10;
		ret += s[i] - '0';
		i++;
	}

	return ret;
}

int flag;

LL expr0(string&, int&, LL);
LL expr1(string&, int&, LL);
LL expr2(string&, int&, LL);

LL expr0(string& s, int& i, LL mod) {
	LL ret = expr1(s, i, mod);
	while (s[i] == '+' || s[i] == '-') {
		if (s[i] == '+')ret += expr1(s, ++i, mod);
		if(s[i]=='-')ret -= expr1(s, ++i, mod);
		ret += mod;
		ret %= mod;
	}
	return ret;
}
LL expr1(string& s, int& i, LL mod) {
	LL ret = expr2(s, i, mod);
	while (s[i] == '*' || s[i] == '/') {
		if (s[i] == '*')ret *= expr2(s, ++i, mod);
		if (s[i] == '/') {
			LL si = expr2(s, ++i, mod);

			if (si%mod == 0) {
				flag = 1;
			}
			else {
				ret *= powmod(si, mod - 2,mod);
			}
		}
		ret %= mod;
	}
	return ret;
}
LL expr2(string& s, int& i, LL mod) {
	if (s[i] == '(') {
		i++;
		LL num = expr0(s, i, mod);
		i++;
		return num;
	}
	else {
		return getnum(s, i) % mod;
	}

}


int main() {

	string s;
	while (getline(cin,s), s[0] != '0') {
		string t = spa(s);
		int i = 0;
		LL mod = getnum(t, i);
		i++;
		t = t.substr(i);
		string sub = t;
		i = 0;
		flag = 0;
		LL ans = expr0(t, i,mod);
		if (flag) {
			cout << "NG" << endl;
		}
		else {
			cout << sub ;
			cout << " = " << ans << " (mod " << mod << ")" << endl;
		}

	}

	return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3416
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
// #include<atcoder/all>
// using mint = atcoder::modint998244353;
using ld = long double;
#define fi first
#define se second
#define all(x) x.begin(),x.end()
#define rep(i,n) for(int i=0;i<(int)(n);++i)
template<typename T>bool chmin(T&a,T b){return b<a?(a=b,1):0;}
template<typename T>bool chmax(T&a,T b){return b>a?(a=b,1):0;}

long mod;
bool ok;
long POW(long x, long n){
    long res=1;
    x%=mod;
    while(n){
        if(n&1){
            res*=x;
            res%=mod;
        }
        x*=x;
        x%=mod;
        n>>=1L;
    }
    return res;
}

typedef string::const_iterator State;

long expression(State &begin);


long number(State &begin){
    long ret=0;
    while((isdigit(*begin))){
        ret*=10;
        ret+=*begin-'0';
        ret%=mod;
        begin++;
    }
    return ret;
}

long factor(State &begin){
    if(*begin=='('){
        begin++;
        long ret=expression(begin);
        begin++;
        return ret;
    }
    else return number(begin);
}

long term(State &begin){
    long ret=factor(begin);
    for(;;){
        if(*begin=='*'){
            begin++;
            ret*=factor(begin);
            ret%=mod;
        }
        else if(*begin=='/'){
            begin++;
            long a=factor(begin);
            if(a==0){
                ok=0;
                a=1;
            }
            else{
                ret*=POW(a, mod-2);
                ret%=mod;
            }
        }
        else break;
    }
    return ret;
}

long expression(State &begin){
    long ret=term(begin);
    for(;;){
        if(*begin=='+'){
            begin++;
            ret+=term(begin);
            ret%=mod;
        }
        else if(*begin=='-'){
            begin++;
            ret-=term(begin);
            ret+=mod;
            ret%=mod;
        }
        else break;
    }
    return ret;
}

long f(string S){
    State begin=S.begin();
    return expression(begin);
}



int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    for(string t;getline(cin,t),t[0]!='0';){
        
        int id=find(all(t), ':')-t.begin();
        mod=stoi(t.substr(0, id));

        string s=t.substr(id+1, ssize(t)-id-1);
        s.erase(remove(all(s), ' '),s.end());

        ok=1;
        int ans=f(s)%mod;
        if(!ok) cout<<"NG\n";
        else cout<<s<<" = "<<ans<<" (mod "<<mod<<")\n";
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3712
final_rank: 2

code_snippet: /// 生成AI不使用 / Not using generative AI

// #pragma GCC target ("avx")
// #pragma GCC optimize("Ofast")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")

#ifdef MARC_LOCAL
#define _GLIBCXX_DEBUG
#endif

#ifdef ATCODER
#include <atcoder/all>
using namespace atcoder;
#endif

#include <bits/stdc++.h>
using namespace std;

//#define int long long
using ll = long long; using vll = vector<ll>; using vvll = vector<vll>; using vvvll = vector<vvll>; using vvvvll = vector<vvvll>;
using vi = vector<int>; using vvi = vector<vi>; using vvvi = vector<vvi>; using vvvvi = vector<vvvi>;
using ld = long double; using vld = vector<ld>; using vvld = vector<vld>; using vd = vector<double>;
using vc = vector<char>; using vvc = vector<vc>; using vs = vector<string>;
using vb = vector<bool>; using vvb = vector<vb>; using vvvb = vector<vvb>;
using pii = pair<int, int>; using pcc = pair<char, char>; using pll = pair<ll, ll>; using pli = pair<ll, int>; using pdd = pair<double, double>; using pldld = pair<ld,ld>;
using vpii = vector<pii>; using vvpii = vector<vpii>; using vpll = vector<pll>; using vvpll = vector<vpll>; using vpldld = vector<pldld>;
using ui = unsigned int; using ull = unsigned long long;
using i128 = __int128; using f128 = __float128;
template<class T> using pqg = priority_queue<T, vector<T>, greater<T>>;
#define vec(type, name, ...) vector<type> name(__VA_ARGS__)
#define vv(type, name, h, ...) vector<vector<type> > name(h, vector<type>(__VA_ARGS__))
#define vvv(type, name, h, w, ...) vector<vector<vector<type> > > name(h, vector<vector<type> >(w, vector<type>(__VA_ARGS__)))
#define vvvv(type, name, a, b, c, ...) vector<vector<vector<vector<type> > > > name(a, vector<vector<vector<type> > >(b, vector<vector<type> >(c, vector<type>(__VA_ARGS__))))

#define overload4(a,b,c,d,name,...) name
#define rep1(n) for(ll i = 0; i < (ll)n; i++)
#define rep2(i,n) for(ll i = 0; i < (ll)n; i++)
#define rep3(i,a,b) for (ll i = a; i < (ll)b; i++)
#define rep4(i,a,b,c) for (ll i = a; i < (ll)b; i += (ll)c)
#define rep(...) overload4(__VA_ARGS__,rep4,rep3,rep2,rep1)(__VA_ARGS__)
#define repback1(n) for (ll i = (ll)n-1; i >= 0; i--)
#define repback2(i,n) for (ll i = (ll)n-1; i >= 0; i--)
#define repback3(i,a,b) for (ll i = (ll)b-1; i >= (ll)a; i--)
#define repback4(i,a,b,c) for (ll i = (ll)b-1; i >= (ll)a; i -= (ll)c)
#define repback(...) overload4(__VA_ARGS__,repback4,repback3,repback2,repback1)(__VA_ARGS__)
#define all(x) (x).begin(), (x).end()
#define include(y, x, H, W) (0 <= (y) && (y) < (H) && 0 <= (x) && (x) < (W))
#define inrange(x, down, up) ((down) <= (x) && (x) <= (up))
#define pb push_back
#define eb emplace_back
#define fir first
#define sec second
#define TIMER_START TIME_START = clock()
#ifdef MARC_LOCAL
// https://trap.jp/post/1224/
#define debug1(x) cout << "debug L" << __LINE__ <<": " << (#x) << ": " << (x) << endl
#define debug2(x, y) cout << "debug L" << __LINE__ <<": " << (#x) << ": " << (x) << ", " << (#y) << ": " << (y) << endl
#define debug3(x, y, z) cout << "debug L" << __LINE__ <<": " << (#x) << ": " << (x) << ", " << (#y) << ": " << (y) << ", " << (#z) << ": " << (z) << endl
#define debug4(x, y, z, w) cout << "debug L" << __LINE__ <<": " << (#x) << ": " << (x) << ", " << (#y) << ": " << (y) << ", " << (#z) << ": " << (z) << ", " << (#w) << ": " << (w) << endl
#define debug5(x, y, z, w, v) cout << "debug L" << __LINE__ <<": " << (#x) << ": " << (x) << ", " << (#y) << ": " << (y) << ", " << (#z) << ": " << (z) << ", " << (#w) << ": " << (w) << ", " << (#v) << ": " << (v) << endl
#define debug6(x, y, z, w, v, u) cout << "debug L" << __LINE__ <<": " << (#x) << ": " << (x) << ", " << (#y) << ": " << (y) << ", " << (#z) << ": " << (z) << ", " << (#w) << ": " << (w) << ", " << (#v) << ": " << (v) << ", " << (#u) << ": " << (u) << endl
#define overload6(a, b, c, d, e, f, g,...) g
#define debug(...) overload6(__VA_ARGS__, debug6, debug5, debug4, debug3, debug2, debug1)(__VA_ARGS__)
#define debuga cerr << __LINE__ << endl
#define debugnl cout << endl
#define Case(i) cout << "Case #" << (i) << ": "
#define TIMECHECK cerr << 1000.0 * static_cast<double>(clock() - TIME_START) / CLOCKS_PER_SEC << "ms" << endl
#define LOCAL 1
#else
#define debug1(x) void(0)
#define debug2(x, y) void(0)
#define debug3(x, y, z) void(0)
#define debug4(x, y, z, w) void(0)
#define debug5(x, y, z, w, v) void(0)
#define debug6(x, y, z, w, v, u) void(0)
#define debug(...) void(0)
#define debuga void(0)
#define debugnl void(0)
#define Case(i) void(0)
#define TIMECHECK void(0)
#define LOCAL 0
#endif

//mt19937_64 rng(0);
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
clock_t TIME_START;
const long double pi = 3.141592653589793238462643383279L;
const long long INFL = 1000000000000000000ll;
const long long INFLMAX = numeric_limits< long long >::max(); // 9223372036854775807
const int INF = 1000000000;
const int INFMAX = numeric_limits< int >::max(); // 2147483647
const long double INFD = numeric_limits<ld>::infinity();
const long double EPS = 1e-10;
const int mod1 = 1000000007;
const int mod2 = 998244353;
const vi dx1 = {1,0,-1,0};
const vi dy1 = {0,1,0,-1};
const vi dx2 = {0, 1, 1, 1, 0, -1, -1, -1};
const vi dy2 = {1, 1, 0, -1, -1, -1, 0, 1};
constexpr char nl = '\n';
constexpr char bl = ' ';

std::ostream &operator<<(std::ostream &dest, __int128_t value) { std::ostream::sentry s(dest); if (s) {__uint128_t tmp = value < 0 ? -value : value; char buffer[128]; char *d = std::end(buffer); do {--d;*d = "0123456789"[tmp % 10];tmp /= 10;} while (tmp != 0);if (value < 0) {--d;*d = '-';}int len = std::end(buffer) - d;if (dest.rdbuf()->sputn(d, len) != len) {dest.setstate(std::ios_base::badbit);}}return dest; }
__int128 parse(string &s) { __int128 ret = 0; for (int i = 0; i < (int)s.length(); i++) if ('0' <= s[i] && s[i] <= '9') ret = 10 * ret + s[i] - '0'; return ret; } // for __int128 (https://kenkoooo.hatenablog.com/entry/2016/11/30/163533)
template<class T> ostream& operator << (ostream& os, vector<T>& vec) { os << "["; for (int i = 0; i<(int)vec.size(); i++) { os << vec[i] << (i + 1 == (int)vec.size() ? "" : ", "); } os << "]"; return os; } /// vector 出力
template<class T, class U> ostream& operator << (ostream& os, pair<T, U>& pair_var) { os << "(" << pair_var.first << ", " << pair_var.second << ")"; return os; } // pair 出力
template<class T, class U> ostream& operator << (ostream& os, map<T, U>& map_var) { os << "{"; for (auto itr = map_var.begin(); itr != map_var.end(); itr++) { os << "(" << itr->first << ", " << itr->second << ")"; itr++; if(itr != map_var.end()) os << ", "; itr--; } os << "}"; return os; } // map出力
template<class T> ostream& operator << (ostream& os, set<T>& set_var) { os << "{"; for (auto itr = set_var.begin(); itr != set_var.end(); itr++) { os << *itr; ++itr; if(itr != set_var.end()) os << ", "; itr--; } os << "}"; return os; } /// set 出力

bool equals(long double a, long double b) { return fabsl(a - b) < EPS; }
template<class T> int sign(T a) { return equals(a, 0) ? 0 : a > 0 ? 1 : -1; }
long double radian_to_degree(long double r) { return (r * 180.0 / pi); }
long double degree_to_radian(long double d) { return (d * pi / 180.0); }

int popcnt(unsigned long long a){ return __builtin_popcountll(a); } // ll は 64bit対応！
int MSB1(unsigned long long x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); } // MSB(1), 0-indexed ( (0, 1, 2, 3, 4) -> (-1, 0, 1, 1, 2) )
int LSB1(unsigned long long x) { return (x == 0 ? -1 : __builtin_ctzll(x)); } // LSB(1), 0-indexed ( (0, 1, 2, 3, 4) -> (-1, 0, 1, 0, 2) )
long long maskbit(int n) { return (1LL << n) - 1; }
bool bit_is1(long long x, int i) { return ((x>>i) & 1); }
string charrep(int n, char c) { return std::string(n, c); }
template<class T> T square(T x) { return (x) * (x); }
template<class T>void UNIQUE(T& A) {sort(all(A)); A.erase(unique(all(A)), A.end());}
template<class T>bool chmax(T& a, const T& b) { if (a < b) { a = b; return 1; } return 0; }
template<class T>bool chmin(T& a, const T& b) { if (b < a) { a = b; return 1; } return 0; }
template<class T, class U> bool chmin(T& a, const U& b){ return chmin(a, (T)b); }
template<class T, class U> bool chmax(T& a, const U& b){ return chmax(a, (T)b); }
void YESNO(bool b) {if(b){cout<<"YES"<<'\n';} else{cout<<"NO"<<'\n';}} void YES() {YESNO(true);} void NO() {YESNO(false);}
void yesno(bool b) {if(b){cout<<"yes"<<'\n';} else{cout<<"no"<<'\n';}} void yes() {yesno(true);} void no() {yesno(false);}
void YesNo(bool b) {if(b){cout<<"Yes"<<'\n';} else{cout<<"No"<<'\n';}} void Yes() {YesNo(true);} void No() {YesNo(false);}
void POSIMPOS(bool b) {if(b){cout<<"POSSIBLE"<<'\n';} else{cout<<"IMPOSSIBLE"<<'\n';}}
void PosImpos(bool b) {if(b){cout<<"Possible"<<'\n';} else{cout<<"Impossible"<<'\n';}}
void posimpos(bool b) {if(b){cout<<"possible"<<'\n';} else{cout<<"impossible"<<'\n';}}
void FIRSEC(bool b) {if(b){cout<<"FIRST"<<'\n';} else{cout<<"SECOND"<<'\n';}}
void firsec(bool b) {if(b){cout<<"first"<<'\n';} else{cout<<"second"<<'\n';}}
void FirSec(bool b) {if(b){cout<<"First"<<'\n';} else{cout<<"Second"<<'\n';}}
void AliBob(bool b) {if(b){cout<<"Alice"<<'\n';} else{cout<<"Bob"<<'\n';}}
void TakAok(bool b) {if(b){cout<<"Takahashi"<<'\n';} else{cout<<"Aoki"<<'\n';}}
int GetTime() {return 1000.0*static_cast<double>(clock() - TIME_START) / CLOCKS_PER_SEC;}
ll myRand(ll B) {return (unsigned long long)rng() % B;}
template<class T> void print(const T& x, const char endch = '\n') { cout << x << endch; }

template<class T> T ceil_div(T x, T y) { assert(y); return (x > 0 ? (x + y - 1) / y : x / y); }
template<class T> T floor_div(T x, T y) { assert(y); return (x > 0 ? x / y : (x - y + 1) / y); }
template<class T> pair<T, T> divmod(T x, T y) { T q = floor_div(x, y); return {q, x - q * y}; } /// (q, r) s.t. x = q*y + r 
ll GCD(ll a, ll b) { if(a < b) swap(a, b); if(b == 0) return a; if(a%b == 0) return b; else return GCD(b, a%b); }
ll LCM(ll a, ll b) { assert(GCD(a,b) != 0); return a / GCD(a, b) * b; }
ll MOD(ll &x, const ll P) { ll ret = x%P; if(ret < 0) ret += P; return x = ret; } /// x % P を非負整数に直す
ll mpow(ll x, ll n, const ll mod) { x %= mod; ll ret = 1; while(n > 0) { if(n & 1) ret = ret * x % mod; x = x * x % mod; n >>= 1; } return ret; } /// x^n % mod を計算
ll lpow(ll x, ll n) { ll ret = 1; while(n > 0){ if(n & 1) ret = ret * x; x = x * x; n >>= 1; } return ret; } /// x^nを計算
string toBinary(ll n) { if(n == 0) return "0"; assert(n > 0); string ret; while (n != 0){ ret += ( (n & 1) == 1 ? '1' : '0' ); n >>= 1; } reverse(ret.begin(), ret.end()); return ret; } /// 10進数(long long) -> 2進数(string)への変換
ll toDecimal(string S) { ll ret = 0; for(int i = 0; i < (int)S.size(); i++){ ret *= 2LL; if(S[i] == '1') ret += 1; } return ret; } /// 2進数(string)　→　10進数(long long)への変換
int ceil_pow2(ll n) { int x = 0; while ((1ll << x) < n) x++; return x;} /// return minimum non-negative `x` s.t. `n <= 2**x`
int floor_pow2(ll n) { int x = 0; while ((1ll << (x+1)) <= n) x++; return x;} /// return maximum non-negative `x` s.t. `n >= 2**x`



// ############################
// #                          #
// #    C O D E  S T A R T    #
// #                          #
// ############################

typedef string::const_iterator State;


/// ParseErrorが発生したときのエラー情報用
// TODO : 使いやすいよう設定し直す
class ParseError : public std::exception {
    public:
        // デフォルトコンストラクタ
        ParseError() : message("Parse error") {}

        // コンストラクタ：カスタムエラーメッセージを持つ
        ParseError(const std::string& msg, int line = -1, int column = -1)
            : message(msg), line(line), column(column) {
            buildFullMessage();
        }

        // コンストラクタ：行と列情報を含む
        ParseError(int line, int column)
            : message("Parse error"), line(line), column(column) {
            buildFullMessage();
        }

        // エラーメッセージを取得するメンバ関数
        const char* what() const noexcept override {
            return fullMessage.c_str();
        }

        // 行番号を取得するメンバ関数
        int getLine() const {
            return line;
        }

        // 列番号を取得するメンバ関数
        int getColumn() const {
            return column;
        }

    private:
        std::string message;
        std::string fullMessage;
        int line;
        int column;

        // エラーメッセージを構築するプライベート関数
        void buildFullMessage() {
            std::ostringstream oss;
            oss << message;
            if (line >= 0) {
                oss << " at line " << line;
            }
            if (column >= 0) {
                oss << ", column " << column;
            }
            fullMessage = oss.str();
        }
};


/// begin が 期待される文字 expectedを指していたらbeginを一つ進める（期待する文字でなければエラー発生）
// assertのようなイメージ、デバッグ用（使用例: 式の最後に=が来るのであれば、consume(begin, '=')として最後まで到達してることを確認できる）
void consume(State& begin, const char expected) {
    if (*begin == expected) {
        begin++;
    }
    else {
        cerr << "Expected char is '" << expected << "' but got '" << *begin << "'" << endl;
        cerr << "Rest string is '";
        while (*begin) {
            cerr << *begin++;
        }
        cerr << "'" << endl;
        throw ParseError();
    }
}


long long expression(State& begin);
long long term(State& begin);
long long factor(State& begin);
long long number(State& begin);

ll mod;
bool ng = false;

/// 四則演算（64bit整数用）
long long expression(State& begin) {
    long long ret = term(begin);

    while(true) {
        if(*begin == '+') {
            consume(begin, '+');
            ret += term(begin);
            MOD(ret, mod);
        }
        else if(*begin == '-') {
            consume(begin, '-');
            ret -= term(begin);
            MOD(ret, mod);
        }
        else break;
    }

    return ret;
}

/// 乗除
long long term(State& begin) {
    long long ret = factor(begin);

    while(true) {
        if(*begin == '*') {
            consume(begin, '*');
            ret *= factor(begin);
            MOD(ret, mod);
        }
        else if(*begin == '/') {
            consume(begin, '/');
            ll tmp = factor(begin);
            if(tmp == 0) ng = true;
            ret *= mpow(tmp,mod-2,mod);
            MOD(ret, mod);
        }
        else break;
    }

    return ret;
}

/// 括弧付きの式
long long factor(State& begin) {
    if(*begin == '(') {
        consume(begin, '(');
        long long ret = expression(begin);
        consume(begin, ')');
        return ret;
    }
    else {
        return number(begin);
    }
}


/// 数
long long number(State& begin) {
    long long ret = 0;

    while(isdigit(*begin)) {
        ret *= 10;
        ret += *begin - '0';
        MOD(ret, mod);
        begin++;
    }

    return ret;
}



/// main()の中に0を受け取る変数（終了判定）を定義しておく
//ll N;
string S;

void solve() {
    S.erase(remove_if(all(S), ::isspace), S.end()); // remove_if: 前に引数で与えられた関数に引っかからなかったものが寄せられる -> eraseの第一引数に渡せば消せる
    //debug(S);

    ng = false;
    State it = S.begin();
    
    string mods;
    while(*it != ':') {
        mods += *it;
        it++;
    }
    it++;
    mod = stoll(mods);
    //debug(mod);
    
    string ans;
    auto it2 = it;
    while(it2 != S.end()) {
        ans += *it2;
        it2++;
    }
    ans += " = ";
    //debug(ans);

    ll res = expression(it);
    if(ng) {
        cout << "NG\n";
        return;
    }
    ans += to_string(res);
    ans += " (mod ";
    ans += mods;
    ans += ")";

    cout << ans << nl;

}



signed main() {
    cin.tie(0); ios_base::sync_with_stdio(false);
    TIMER_START;
    //cout << fixed << setprecision(15);
    

    //int tt = 1;
    //cin >> tt;
    while(true){
        // cin >> N;
        // if(N == 0) break;
        getline(cin, S);
        if(S[0] == '0') break;

        solve();
    }

    TIMECHECK;
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3576
final_rank: 12

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef string::const_iterator State;
class ParseError {};

int number(State &begin);
int term(State &begin);
int expression(State &begin);
int factor(State &begin);
int p;
bool flag;
int pow_mod(int n, int k){
    if(k == 0) return 1;
    if(k == 1) return n;
    if(k%2 == 1) return (n*pow_mod(n,k-1))%p;
    int x = pow_mod(n, k/2);
    return (x*x)%p;
}
int inv(int n){
  return pow_mod(n, p-2);
}
int number(State &begin){
    int ret =0;
    while(isdigit(*begin)){
        ret = ret*10+(*begin - '0');
        ret %= p;
        begin++;
    }
    // cout << ret << endl;
    return ret;
}
int term(State &begin){
    int ret = factor(begin);
    while(true){
        if(*begin == '*'){
            begin++;
            ret *= factor(begin);
            ret %= p;
        }
        else if(*begin == '/'){
            begin++;
            int x = factor(begin);
            if(x == 0) {
              flag = false;
            }
            ret *= inv(x);
            ret %= p;
        }
        else{
            break;
        }
    }
    ret %= p;
    return ret;
}
int expression(State &begin) {
    int ret = term(begin);
    for (;;) {
        if (*begin == '+') {
            begin++;
            ret += term(begin);
            ret %= p;
        } else if (*begin == '-') {
            begin++;
            ret -= term(begin);
            ret = (ret+p)%p;
        } else {
            break;
        }
    }
    ret %= p;
    return ret;
}
int factor(State &begin) {
    if (*begin == '(') {
        begin++; // '('を飛ばす。
        int ret = expression(begin);
        begin++; // ')'を飛ばす。
        return ret;
    } else {
        return number(begin);
    }
}
bool solve(){
    string s;
    cin >> p;
    getline(cin, s);
    s.erase(std::remove_if(s.begin(), s.end(), ::isspace), s.end());
    if(p == 0) return false;
    State begin = s.begin();
    begin++;
    flag = true;
    int ans = expression(begin);
    // cout << ans << endl;
    if(flag){
      cout << s.substr(1, s.size()-1) << " = " << ans << " (mod " << p << ")" << endl;
    }
    else cout << "NG" << endl;
    return true;
}
int main(){
    while(solve());
}
accuracy: 1
time_ms: 40
memory_kb: 3220
final_rank: 9

code_snippet: #include <bits/stdc++.h>

struct Data {
    std::string expr;
    int prime;
    int val;
    bool ok;
};

void valid(Data data) {
    if (!data.ok) return;
}

std::ostream& operator<<(std::ostream& os, const Data& data) {
    valid(data);
    if (data.ok) {
        os << data.expr << " = " << data.val << " (mod " << data.prime << ")";
    } else {
        os << "NG";
    }

    return os;
}

std::string eliminate_space(std::string s) {
    s.erase(std::remove_if(s.begin(), s.end(), [](char c) { return c == ' '; }), s.end());
    return s;
}

int powmod(int base, int exp, int mod) {
    int res = 1;
    while (exp > 0) {
        if (exp & 1) {
            res *= base;
            res %= mod;
        }
        base *= base;
        base %= mod;
        exp >>= 1;
    }
    return res;
}

class ExprError {};

struct Expr {
    using Iter = std::string::const_iterator&;

    std::string s;
    int p;

    Expr(std::string s, int p): s(s), p(p) {}

    void consume(Iter it, char c) {
        it++;
    }

    std::pair<int, bool> eval() {
        auto it = s.cbegin();
        try {
            return {expr(it), true};
        } catch (ExprError) {
            return {-1, false};
        }
    }

    int expr(Iter it) {
        int res = term(it);
        while (it != s.end() && (*it == '+' || *it == '-')) {
            if (*it == '+') {
                consume(it, '+');
                res = (res + term(it)) % p;
            } else {
                consume(it, '-');
                res = (res - term(it) + p) % p;
            }
        }
        return res;
    }

    int term(Iter it) {
        int res = factor(it);
        while (it != s.end() && (*it == '*' || *it == '/')) {
            if (*it == '*') {
                consume(it, '*');
                res = res * factor(it) % p;
            } else {
                consume(it, '/');
                int temp = factor(it);
                if (temp == 0) {
                    throw ExprError();
                }
                res = res * powmod(temp, p - 2, p) % p;
            }
        }
        return res;
    }

    int factor(Iter it) {
        if (*it == '(') {
            consume(it, '(');
            int res = expr(it);
            consume(it, ')');
            return res;
        } else {
            return number(it);
        }
    }

    int number(Iter it) {
        int res = 0;
        while (it != s.end() && std::isdigit(*it)) {
            res = 10 * res + (*it) - '0';
            it++;
        }

        return res;
    }
};

struct Parser {
    using Iter = std::string::const_iterator&;
    std::string s;

    Parser(std::string s): s(s) {}

    void consume(Iter it, char c) {
        it++;
    }

    Data parse() {
        s = eliminate_space(s);

        Data data;
        auto it = s.cbegin();
        data.prime = prime(it);
        consume(it, ':');
        data.expr = expr(it);

        Expr expr(data.expr, data.prime);
        auto [val, ok] = expr.eval();
        data.val = val;
        data.ok = ok;

        return data;
    }

    int prime(Iter it) {
        int res = 0;
        while (it != s.end() && *it != ':') {
            res = 10 * res + (*it) - '0';
            it++;
        }
        return res;
    }

    std::string expr(Iter it) {
        std::string res(it, s.cend());
        it = s.cend();
        return res;
    }
};

int main() {
    std::string s;
    while (true) {
        std::getline(std::cin, s);
        if (s == "0:") break;
        Parser parser(s);
        std::cout << parser.parse() << std::endl;
    }
}
accuracy: 1
time_ms: 20
memory_kb: 3568
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;

int getMod(string& S) {
    reverse(S.begin(), S.end());
    int res = 0;
    while (S.back() != ':') {
        res = (res * 10) + (S.back() - '0');
        S.pop_back();
    }
    assert(S.back() == ':');
    S.pop_back();
    reverse(S.begin(), S.end());
    return res;
}

string clean(const string& S) {
    string res;
    for (auto c : S) if (c != ' ') {
        res += c;
    }
    return res;
}

ll mod;

namespace zawa {

ll add(ll a, ll b) {
    return (a + b >= mod ? a + b - mod : a + b);
}

ll sub(ll a, ll b) {
    ll res = a - b + mod;
    return (res >= mod ? res - mod : res);
}

ll mul(ll a, ll b) {
    return (a * b) % mod;
}

ll pow(ll a, ll p) {
    ll res = 1LL, base = a;
    while (p) {
        if (p & 1) res = mul(res, base);
        base = mul(base, base);
        p >>= 1;
    }
    return res;
}

pair<ll, bool> div(ll a, ll b) {
    if (b == 0) return { 0, false };
    return { mul(a, pow(b, mod - 2)), true };
}

} // namespace zawa

int it;
bool ok = true;

bool isDig(char c) {
    return '0' <= c and c <= '9';
}

ll factor(const string&);
ll term(const string&);
ll expr(const string&);

ll factor(const string& S) {
    if (S[it] == '(') {
        it++;
        ll res = expr(S);
        assert(S[it] == ')');
        it++;
        return res;
    }
    if (isDig(S[it])) {
        ll res = 0;
        while (isDig(S[it])) {
            res = (res * 10) + (S[it] - '0');
            it++;
        }
        return res;
    }
    assert(false);
}

ll term(const string& S) {
    ll lhs = factor(S);
    while (1) {
        if (it == (int)S.size()) break;
        if (S[it] == ')') break;
        if (S[it] == '+' or S[it] == '-') break;
        char op = S[it];
        it++;
        ll rhs = factor(S);
        // cout << "   calc term :" << lhs << ' ' << rhs << ' ' << op << endl;
        if (op == '*') lhs = zawa::mul(lhs, rhs);
        else if (op == '/') {
            auto cond = zawa::div(lhs, rhs);
            if (cond.second) {
                lhs = cond.first;
            }
            else {
                ok = false;
                lhs = 0;
            }
        }
        else assert(false);
    }
    return lhs;
}

ll expr(const string& S) {
    ll lhs = term(S);
    while (1) {
        if (it == (int)S.size()) break;
        if (S[it] == ')') break;
        char op = S[it];
        it++;
        ll rhs = term(S);
        // cout << "calc expr: " << lhs << ' ' << rhs << ' ' << op << endl;
        if (op == '+') lhs = zawa::add(lhs, rhs);
        else if (op == '-') lhs = zawa::sub(lhs, rhs);
        else assert(false);
    }
    return lhs;
}

bool solve() {
    string S; getline(cin, S);
    mod = getMod(S);

    if (S.empty()) return false;

    S = clean(S);

    it = 0;
    ok = true;
    ll ans = expr(S);
    if (ok) {
        cout << S << " = " << ans << ' ' << "(mod " << mod << ')' << endl;
    }
    else {
        cout << "NG" << endl;
    }

    return true;
}

int main() {
    while (solve()) ;
}
accuracy: 1
time_ms: 30
memory_kb: 3436
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef __int128_t lll;
typedef long double ld;
typedef pair<ll, ll> pl;
typedef tuple<ll, ll, ll> tt;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<vvl> vvvl;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<vvd> vvvd;
typedef vector<bool> vb;
typedef vector<vb> vvb;
typedef vector<vvb> vvvb;
typedef vector<char> vc;
typedef vector<vc> vvc;
typedef vector<vvc> vvvc;
typedef vector<pl> vp;
typedef vector<tt> vt;
typedef vector<string> vs;

const ll INF = 1000000010;
const ll INFL = INF * INF;
const ld epsilon = 1e-10;

#define ovl(a, b, c, d, e, ...) e
#define pb push_back
#define eb emplace_back
#define MP make_pair
#define DEBUG(...) DEBUG_(#__VA_ARGS__, __VA_ARGS__)
#define REP1(i, r) for (int i = 0; i < (r); i++)
#define REP2(i, l, r) for (int i = (l); i < (r); i++)
#define REP3(i, l, r, d) for (int i = (l); i < (r); i += (d))
#define REP(...) ovl(__VA_ARGS__, REP3, REP2, REP1)(__VA_ARGS__)
#define RREP1(i, r) for (int i = (r)-1; i >= 0; i--)
#define RREP2(i, l, r) for (int i = (r)-1; i >= (l); i--)
#define RREP3(i, l, r, d) for (int i = (r)-1; i >= (l); i -= (d))
#define RREP(...) ovl(__VA_ARGS__, RREP3, RREP2, RREP1)(__VA_ARGS__)
#define EACH1(x, a) for (auto &x : a)
#define EACH2(x, y, a) for (auto &[x, y] : a)
#define EACH3(x, y, z, a) for (auto &[x, y, z] : a)
#define EACH(...) ovl(__VA_ARGS__, EACH3, EACH2, EACH1)(__VA_ARGS__)
#define ALL(x) begin(x), end(x)
#define RALL(x) (x).rbegin(), (x).rend()
#define sz(x) (ll) x.size()
#define LB(a, x) (lower_bound(ALL(a), x) - a.begin())
#define UB(a, x) (upper_bound(ALL(a), x) - a.begin())
#define FLG(x, i) (((x) >> (i)) & 1)
#define CNTBIT(x) __builtin_popcountll(x)
#define IN(x, a, b) ((a) <= (x) && (x) < (b))
#define int ll

template <class T>
void DEBUG_(string_view name, const T &a) {
    cerr << name << ": " << a << endl;
}

template <class T>
void DEBUG_(string_view name, const vector<T> &a) {
    cerr << name << ": ";
    REP(i, sz(a)) cerr << a[i] << " ";
    cerr << endl;
}

template <class T, class U>
bool chmax(T &x, const U &y) {
    return x < y ? x = y, 1 : 0;
}
template <class T, class U>
bool chmin(T &x, const U &y) {
    return x > y ? x = y, 1 : 0;
}

//-----------------------------------------------------------------------

typedef string::const_iterator State;

int MOD;

int modinv(int b) {
    int e = MOD - 2;
    int p = b;
    int ans = 1;
    while (e) {
        if (e & 1) {
            ans *= p;
            ans %= MOD;
        }
        e >>= 1;
        p = (p * p) % MOD;
    }
    return ans;
}

int number(State &begin) {
    int ret = 0;
    while (isdigit(*begin) || *begin == ' ') {
        if (*begin == ' ') {
            begin++;
            continue;
        }
        ret *= 10;
        ret += *begin - '0';
        begin++;
    }
    return ret;
}

int expression(State &state);

int factor(State &begin) {
    if (*begin == ' ') {
        begin++;
    }
    if (*begin == '(') {
        begin++;
        int ret = expression(begin);
        begin++;
        return ret;
    } else {
        return number(begin);
    }
}

int term(State &begin) {
    int ret = factor(begin);

    while (true) {
        if (*begin == '*') {
            // DEBUG("*");
            begin++;
            ret *= factor(begin);
            ret %= MOD;
        } else if (*begin == '/') {
            begin++;
            int div = factor(begin);
            if (div == 0) {
                throw logic_error("zero");
                break;
            }
            ret *= modinv(div);
            ret %= MOD;
        } else if (*begin == ' ') {
            begin++;
        } else {
            break;
        }
    }

    return ret;
}

int expression(State &begin) {
    int ret = term(begin);
    while (true) {
        // DEBUG(ret);
        if (*begin == '+') {
            // DEBUG("+");
            begin++;
            ret += term(begin);
            ret %= MOD;
        } else if (*begin == '-') {
            // DEBUG("-");
            begin++;
            ret += MOD - (term(begin) % MOD);
            ret %= MOD;
        } else if (*begin == ' ') {
            begin++;
        } else {
            break;
        }
    }
    return ret;
}

signed main() {
    while (true) {
        string S;
        getline(cin, S);
        if (S == "0:") break;
        string T = "";
        bool isStart = false;
        REP(i, int(S.size())) {
            if (S[i] == ':') {
                i++;
                isStart = true;
            }
            if (!isStart) continue;
            if (S[i] != ' ') {
                T += S[i];
            }
        }
        T += " = ";
        State begin = S.begin();
        MOD = number(begin);
        assert(*begin == ':');
        begin++;
        try {
            int ans = expression(begin);
            T += to_string(ans) + " (mod " + to_string(MOD) + ")";
            cout << T << endl;
        } catch (logic_error const &) {
            cout << "NG" << endl;
        }
    }

    // random_test();

    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3696
final_rank: 13

code_snippet: #include <bits/stdc++.h>
using namespace std;

using ll = long long;

typedef string::const_iterator State;
class ParseError {};

ll mod = -1;
bool ng = false;

ll mypow(ll x, ll n) {
    ll ret = 1;
    while(n) {
        if(n & 1) ret = (ret * x) % mod;
        x = x * x % mod;
        n >>= 1;
    }
    return ret;
}

ll shisoku(State&);

ll number(State& ptr) {
    ll ret = 0;
    while(isdigit(*ptr)) {
        ret *= 10;
        ret += *ptr - '0';
        ptr++;
    }
    return ret;
}

ll factor(State& ptr) {
    if(*ptr == '(') {
        ptr++;
        int ret = shisoku(ptr);
        ptr++;
        return ret;
    } else
        return number(ptr);
}

ll kakewaru(State& ptr) {
    ll ret = factor(ptr);
    while(true) {
        if(*ptr == '*') {
            ptr++;
            ret *= factor(ptr);
            ret %= mod;
        } else if(*ptr == '/') {
            ptr++;
            int num = factor(ptr);
            if(num == 0) {
                ng = true;
                return 0;
            }
            ret *= mypow(num, mod - 2);
            ret %= mod;
        } else {
            break;
        }
    }
    return ret;
}

ll shisoku(State& ptr) {
    ll ret = kakewaru(ptr);
    while(true) {
        if(*ptr == '+') {
            ptr++;
            ret += kakewaru(ptr);
            ret %= mod;
        } else if(*ptr == '-') {
            ptr++;
            ret += mod - kakewaru(ptr);
            ret %= mod;
        } else {
            break;
        }
    }
    return ret;
}

string ignoreSpace(string s) {
    string ret = "";
    for(auto&& c : s)
        if(c != ' ') ret.push_back(c);
    return ret;
}

int main() {
    string s;
    while(true) {
        ng = false;
        getline(cin, s);

        s = ignoreSpace(s);

        State ptr = s.begin();
        mod = number(ptr);
        if(mod == 0) break;
        ptr++;
        int ans = shisoku(ptr);
        if(!ng) {
            auto itr = find(s.begin(), s.end(), ':');
            cout << string(itr + 1, s.end()) << " = " << ans << " (mod " << mod
                 << ")" << endl;
        } else
            cout << "NG" << endl;
    }
}
accuracy: 1
time_ms: 30
memory_kb: 3492
final_rank: 8

code_snippet: #include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < n; ++i)
typedef long long ll;
using namespace std;

int mod;
class Result {
  public:
    int val;
    bool parse_ok;

    Result() : val(0), parse_ok(true) {}

    Result &operator+=(const Result &rhs) {
        val += rhs.val;
        if (val >= mod) val -= mod;
        parse_ok &= rhs.parse_ok;
        return *this;
    }
    Result &operator-=(const Result &rhs) {
        val -= rhs.val;
        if (val < 0) val += mod;
        parse_ok &= rhs.parse_ok;
        return *this;
    }
    Result &operator*=(const Result &rhs) {
        val = val * rhs.val % mod;
        parse_ok &= rhs.parse_ok;
        return *this;
    }
    Result &operator/=(const Result &rhs) {
        if (rhs.val == 0)
            parse_ok = false;
        else
            val = val * mpow(rhs.val, mod - 2) % mod;
        parse_ok &= rhs.parse_ok;
        return *this;
    }

    int mpow(int x, int n) {
        int res = 1;
        while (n) {
            if (n & 1) res = res * x % mod;
            x = x * x % mod;
            n >>= 1;
        }
        return res;
    }
};

vector<string> OPS = {"+-", "*/"};
Result parse(const string &s, size_t &i, size_t p = 0) {
    if (p == OPS.size()) {
        Result res = Result();
        if (s[i] == '(') {
            res = parse(s, ++i, 0);
            assert(s[i] == ')');
            ++i;
        } else if (isdigit(s[i])) {
            while (isdigit(s[i])) {
                res.val *= 10;
                res.val += s[i++] - '0';
            }
        }
        return res;
    }

    Result res = parse(s, i, p + 1);
    while (i < s.length()) {
        char op = s[i];
        if (OPS[p].find(op) == string::npos) break;
        Result rhs = parse(s, ++i, p + 1);

        if (op == '+') res += rhs;
        if (op == '-') res -= rhs;
        if (op == '*') res *= rhs;
        if (op == '/') res /= rhs;
    }
    return res;
}

void solve(string S) {
    size_t i = 0;
    mod = 0;
    while (isdigit(S[i])) {
        mod *= 10;
        mod += S[i++] - '0';
    }

    string t = "";
    while (++i < S.length()) {
        if (S[i] == ' ') continue;
        t += S[i];
    }

    i = 0;
    Result res = parse(t, i);

    if (!res.parse_ok) {
        printf("NG\n");
        return;
    }
    printf("%s = %d (mod %d)\n", t.c_str(), res.val, mod);
}

int main() {
    cin.tie(0)->sync_with_stdio(0);

    string S;
    while (getline(cin, S)) {
        if (S == "0:") break;
        solve(S);
    }

    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3648
final_rank: 1

code_snippet: #include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < n; ++i)
typedef long long ll;
using namespace std;

int mod;
class Result {
  public:
    int val;
    bool parse_ok;

    Result() : val(0), parse_ok(true) {}

    Result &operator+=(const Result &rhs) {
        val += rhs.val;
        if (val >= mod) val -= mod;
        parse_ok &= rhs.parse_ok;
        return *this;
    }
    Result &operator-=(const Result &rhs) {
        val -= rhs.val;
        if (val < 0) val += mod;
        parse_ok &= rhs.parse_ok;
        return *this;
    }
    Result &operator*=(const Result &rhs) {
        val = val * rhs.val % mod;
        parse_ok &= rhs.parse_ok;
        return *this;
    }
    Result &operator/=(const Result &rhs) {
        if (rhs.val == 0)
            parse_ok = false;
        else
            val = val * mpow(rhs.val, mod - 2) % mod;
        return *this;
    }

    int mpow(int x, int n) {
        int res = 1;
        while (n) {
            if (n & 1) res = res * x % mod;
            x = x * x % mod;
            n >>= 1;
        }
        return res;
    }
};

vector<string> OPS = {"+-", "*/"};
Result parse(const string &s, size_t &i, size_t p = 0) {
    if (p == OPS.size()) {
        Result res = Result();
        if (s[i] == '(') {
            res = parse(s, ++i, 0);
            assert(s[i] == ')');
            ++i;
        } else if (isdigit(s[i])) {
            while (isdigit(s[i])) {
                res.val *= 10;
                res.val += s[i++] - '0';
            }
        }
        return res;
    }

    Result res = parse(s, i, p + 1);
    while (i < s.length()) {
        char op = s[i];
        if (OPS[p].find(op) == string::npos) break;
        Result rhs = parse(s, ++i, p + 1);

        if (op == '+') res += rhs;
        if (op == '-') res -= rhs;
        if (op == '*') res *= rhs;
        if (op == '/') res /= rhs;
    }
    return res;
}

void solve(string S) {
    size_t i = 0;
    mod = 0;
    while (isdigit(S[i])) {
        mod *= 10;
        mod += S[i++] - '0';
    }

    string t = "";
    while (++i < S.length()) {
        if (S[i] == ' ') continue;
        t += S[i];
    }

    i = 0;
    Result res = parse(t, i);

    if (!res.parse_ok) {
        printf("NG\n");
        return;
    }
    printf("%s = %d (mod %d)\n", t.c_str(), res.val, mod);
}

int main() {
    cin.tie(0)->sync_with_stdio(0);

    string S;
    while (getline(cin, S)) {
        if (S == "0:") break;
        solve(S);
    }

    return 0;
}
accuracy: 0.8333333333333334
time_ms: 10
memory_kb: 3584
final_rank: 20

code_snippet: #include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;
#define FOR(i, k, n) for (int i = (k); i < (int)(n); ++i)
#define REP(i, n) FOR(i, 0, n)
#define FORIT(i, c)                                                            \
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
template <class T> void debug(T begin, T end) {
  for (T i = begin; i != end; ++i)
    cerr << *i << " ";
  cerr << endl;
}
inline bool valid(int x, int y, int W, int H) {
  return (x >= 0 && y >= 0 && x < W && y < H);
}
typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
class ParseError {};
struct Result {
  ll value;
  int p;
  Result(ll value, int p) : value(value), p(p) {}
};
void skip(const string &s, Result &r, char expected) {
  if (s[r.p] == expected) {
    r.p++;
  } else {
    cerr << "try to skip'" << expected << "' but this char is '" << s[r.p]
         << "'." << endl;
    assert(false);
  }
}
Result expression(const string &s, int p, const int MOD);
Result term(const string &s, int p, const int MOD);
Result factor(const string &s, int p, const int MOD);
map<pair<int, int>, int> inv_dict;
int inverse(int x, const int MOD) {
  pair<int, int> state = make_pair(x, MOD);
  if (inv_dict.count(state))
    return inv_dict[state];
  int res = 1;
  REP(iter, MOD - 2) res = (res * x) % MOD;
  return inv_dict[state] = res;
}
Result expression(const string &s, int p, const int MOD) {
  Result r = term(s, p, MOD);
  while (s[r.p] == '+' || s[r.p] == '-') {
    Result r_ = term(s, r.p + 1, MOD);
    if (s[r.p] == '+') {
      r.value = (r.value + r_.value) % MOD;
    } else {
      r.value = (r.value - r_.value + MOD) % MOD;
    }
    r.p = r_.p;
  }
  return r;
}
Result term(const string &s, int p, const int MOD) {
  Result r = factor(s, p, MOD);
  while (s[r.p] == '*' || s[r.p] == '/') {
    Result r_ = factor(s, r.p + 1, MOD);
    if (s[r.p] == '*') {
      r.value = (r.value * r_.value) % MOD;
    } else {
      if (r_.value == 0)
        throw ParseError();
      r.value = (r.value * inverse(r_.value, MOD)) % MOD;
    }
    r.p = r_.p;
  }
  return r;
}
Result factor(const string &s, int p, const int MOD) {
  if (s[p] == '(') {
    Result r = expression(s, p + 1, MOD);
    skip(s, r, ')');
    return r;
  } else {
    int val = 0;
    while (isdigit(s[p])) {
      val = val * 10 + s[p++] - '0';
    }
    return Result(val, p);
  }
}
int main() {
  string line;
  while (getline(cin, line)) {
    if (line == "0:")
      break;
    REP(i, line.size()) if (line[i] == ':') line[i] = ' ';
    stringstream ss(line);
    string mod_str;
    ss >> mod_str;
    string expr, s;
    while (ss >> s)
      expr += s;
    int mod;
    sscanf(mod_str.c_str(), "%d", &mod);
    try {
      int val = expression(expr, 0, mod).value;
      printf("%s = %d (mod %d)\n", expr.c_str(), val, mod);
    } catch (...) {
      cout << "NG" << endl;
    }
  }
  return 0;
}
accuracy: 1
time_ms: 90
memory_kb: 3648
final_rank: 18

code_snippet: #include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;
#define FOR(i, k, n) for (int i = (k); i < (int)(n); ++i)
#define REP(i, n) FOR(i, 0, n)
#define FORIT(i, c)                                                            \
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
template <class T> void debug(T begin, T end) {
  for (T i = begin; i != end; ++i)
    cerr << *i << " ";
  cerr << endl;
}
inline bool valid(int x, int y, int W, int H) {
  return (x >= 0 && y >= 0 && x < W && y < H);
}
typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
class ParseError {};
struct Result {
  ll value;
  int p;
  Result(ll value, int p) : value(value), p(p) {}
};
void skip(const string &s, Result &r, char expected) {
  if (s[r.p] == expected) {
    r.p++;
  } else {
    cerr << "try to skip'" << expected << "' but this char is '" << s[r.p]
         << "'." << endl;
    assert(false);
  }
}
Result expression(const string &s, int p, const int MOD);
Result term(const string &s, int p, const int MOD);
Result factor(const string &s, int p, const int MOD);
int inverse(int x, const int MOD) {
  int res = 1;
  int pow = MOD - 2;
  while (pow != 0) {
    if (pow & 1)
      res = (res * x) % MOD;
    pow >>= 1;
    x = (x * x) % MOD;
  }
  return res;
}
Result expression(const string &s, int p, const int MOD) {
  Result r = term(s, p, MOD);
  while (s[r.p] == '+' || s[r.p] == '-') {
    Result r_ = term(s, r.p + 1, MOD);
    if (s[r.p] == '+') {
      r.value = (r.value + r_.value) % MOD;
    } else {
      r.value = (r.value - r_.value + MOD) % MOD;
    }
    r.p = r_.p;
  }
  return r;
}
Result term(const string &s, int p, const int MOD) {
  Result r = factor(s, p, MOD);
  while (s[r.p] == '*' || s[r.p] == '/') {
    Result r_ = factor(s, r.p + 1, MOD);
    if (s[r.p] == '*') {
      r.value = (r.value * r_.value) % MOD;
    } else {
      if (r_.value == 0)
        throw ParseError();
      r.value = (r.value * inverse(r_.value, MOD)) % MOD;
    }
    r.p = r_.p;
  }
  return r;
}
Result factor(const string &s, int p, const int MOD) {
  if (s[p] == '(') {
    Result r = expression(s, p + 1, MOD);
    skip(s, r, ')');
    return r;
  } else {
    int val = 0;
    while (isdigit(s[p])) {
      val = val * 10 + s[p++] - '0';
    }
    return Result(val, p);
  }
}
int main() {
  string line;
  while (getline(cin, line)) {
    if (line == "0:")
      break;
    REP(i, line.size()) if (line[i] == ':') line[i] = ' ';
    stringstream ss(line);
    string mod_str;
    ss >> mod_str;
    string expr, s;
    while (ss >> s)
      expr += s;
    int mod;
    sscanf(mod_str.c_str(), "%d", &mod);
    try {
      int val = expression(expr, 0, mod).value;
      printf("%s = %d (mod %d)\n", expr.c_str(), val, mod);
    } catch (...) {
      cout << "NG" << endl;
    }
  }
  return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3468
final_rank: 15

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

const int INF = 1012345678;

class segtree {
private:
	int sz;
	vector<pair<int, int> > val;
public:
	segtree() : sz(0), val(vector<pair<int, int> >()) {}
	segtree(int n) {
		sz = 1;
		while (sz < n) {
			sz *= 2;
		}
		val = vector<pair<int, int> >(2 * sz);
		for (int i = sz - 1; i >= 0; i--) {
			val[sz + i] = make_pair(INF, -i);
		}
		for (int i = sz - 1; i >= 1; i--) {
			val[i] = min(val[i * 2], val[i * 2 + 1]);
		}
	}
	void update(int pos, int x) {
		pos += sz;
		val[pos] = make_pair(x, -(pos - sz));
		while (pos > 1) {
			pos >>= 1;
			val[pos] = min(val[pos * 2], val[pos * 2 + 1]);
		}
	}
	pair<int, int> rangemin(int l, int r) const {
		pair<int, int> res = make_pair(INF, -1);
		l += sz;
		r += sz;
		while (l != r) {
			if (l & 1) res = min(res, val[l]), l++;
			if (r & 1) r--, res = min(res, val[r]);
			l >>= 1;
			r >>= 1;
		}
		res.second *= -1;
		return res;
	}
};

int modpow(int a, int b, int m) {
	int res = 1;
	while (b >= 1) {
		if (b % 2 == 1) {
			res = 1LL * res * a % m;
		}
		a = 1LL * a * a % m;
		b >>= 1;
	}
	return res;
}

int parse(int l, int r, int p, const vector<string>& s, const segtree& seg) {
	if (r - l == 1) {
		return stoi(s[l]);
	}
	int mid = seg.rangemin(l, r).second;
	int lres = parse(l, mid, p, s, seg);
	int rres = parse(mid + 1, r, p, s, seg);
	if (lres == -1 || rres == -1) {
		return -1;
	}
	if (s[mid] == "+") {
		return (lres + rres) % p;
	}
	if (s[mid] == "-") {
		return (lres - rres + p) % p;
	}
	if (s[mid] == "*") {
		return (1LL * lres * rres) % p;
	}
	if (s[mid] == "/") {
		if (rres == 0) {
			return -1;
		}
		int modinv = modpow(rres, p - 2, p);
		return (1LL * lres * modinv) % p;
	}
	return -1;
}

vector<string> split_to_tokens(const string& str) {
	string s;
	for (int i = 0; i < int(str.size()); i++) {
		if (str[i] != ' ') {
			s += str[i];
		}
	}
	string numval;
	vector<string> res;
	for (int i = 0; i < int(s.size()); i++) {
		if ('0' <= s[i] && s[i] <= '9') {
			numval += s[i];
		}
		else {
			if (numval != "") {
				res.push_back(numval);
			}
			numval = "";
			res.push_back(string(1, s[i]));
		}
	}
	if (numval != "") {
		res.push_back(numval);
	}
	return res;
}

int main() {
	while (true) {
		string str;
		getline(cin, str);
		if (str == "0:") {
			break;
		}
		vector<string> tokens = split_to_tokens(str);
		int p = stoi(tokens[0]);
		tokens = vector<string>(tokens.begin() + 2, tokens.end());
		vector<string> s;
		vector<int> depth;
		int cur_depth = 0;
		for (int i = 0; i < int(tokens.size()); i++) {
			if (tokens[i] == "(") {
				cur_depth += 2;
			}
			else if (tokens[i] == ")") {
				cur_depth -= 2;
			}
			else {
				s.push_back(tokens[i]);
				depth.push_back('0' <= tokens[i][0] && tokens[i][0] <= '9' ? INF / 2 : cur_depth + (tokens[i] == "+" || tokens[i] == "-" ? 0 : 1));
			}
		}
		int M = s.size();
		segtree seg(M);
		for (int i = 0; i < M; i++) {
			seg.update(i, depth[i]);
		}
		int answer = parse(0, M, p, s, seg);
		if (answer == -1) {
			cout << "NG" << endl;
		}
		else {
			string outstr = "";
			for (int i = 0; i < int(tokens.size()); i++) {
				outstr += tokens[i];
			}
			outstr += " = " + to_string(answer) + " (mod " + to_string(p) + ")";
			cout << outstr << endl;
		}
	}
	
	return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 5456
final_rank: 19

code_snippet: #include <bits/stdc++.h>

using namespace std;

bool is_digit(char c) {
    return '0' <= c and c <= '9';
}

pair<int, int> read_int(const string &s, int i) {
    int j = i;
    while (is_digit(s[j])) ++j;
    return { stoi(s.substr(i, j - i)), j };
}

int prime;

int inv_mod(int x) {
    int res = 1;
    int pow_x = x;
    for (int v = prime - 2; v; v >>= 1) {
        if (v & 1) res = (long long) res * pow_x % prime;
        pow_x = (long long) pow_x * pow_x % prime;
    }
    return res;
}
int add(int x, int y) {
    return (x + y) % prime;
}
int sub(int x, int y) {
    return (x - y + prime) % prime;
}
int mul(int x, int y) {
    return (long long) x * y % prime;
}

void solve() {
    string s_;
    getline(cin, s_);
    
    if (s_[0] == '0') exit(0);

    string s;
    for (char c : s_) if (c != ' ') s += c;

    auto [p, exp_begin] = read_int(s, 0);
    prime = p;
    assert(s[exp_begin] == ':');
    s = s.substr(exp_begin + 1);

    const int n = s.size();

    vector<int> rp(n, -1);
    vector<int> st;
    for (int i = 0; i < n; ++i) {
        if (s[i] == '(') {
            st.push_back(i);
        } else if (s[i] == ')') {
            int l = st.back();
            rp[l] = i;
            st.pop_back();
        }
    }

    auto scan = [&](auto scan, int l, int r) -> optional<int> {
        vector<int> terms;
        char op = '\0';
        for (int i = l; i < r; ++i) {
            int val;
            if (s[i] == '(') {
                int j = rp[i];
                auto opt_val = scan(scan, i + 1, j);
                if (not opt_val.has_value()) return nullopt;
                val = *opt_val;
                i = j + 1;
            } else {
                assert(is_digit(s[i]));
                auto [v, j] = read_int(s, i);
                val = v;
                i = j;
            }
            if (op == '*') {
                terms.back() = mul(terms.back(), val);
            } else if (op == '/') {
                if (val == 0) return nullopt;
                terms.back() = mul(terms.back(), inv_mod(val));
            } else {
                if (op == '-') {
                    terms.push_back(prime - val);
                } else {
                    terms.push_back(val);
                }
            }
            op = s[i];
        }
        int res = 0;
        for (int v : terms) res = add(res, v);
        return res;
    };

    auto ans = scan(scan, 0, n);
    if (ans.has_value()) {
        cout << s << " = " << *ans << " (mod " << p << ")" << endl;
    } else {
        cout << "NG" << endl;
    }
}

int main() {
    while (true) solve();
}
accuracy: 1
time_ms: 30
memory_kb: 3508
final_rank: 10

code_snippet: #define _USE_MATH_DEFINES
#include<bits/stdc++.h>

using namespace std;
#define LP(I,S,G) for (long long int I = (S); I < (G); I++)
#define IN(X) 	for (int in = 0; in < X.size(); in++)cin >> X[in]
#define OUT(X) 	for (int in = 0; in < X.size(); in++)cout << X[in]<<" "
#define SORT(X) sort((X).begin(), (X).end())
#define CSORT(X,Y) sort(X.begin(), X.end(),Y)
#define COPY(X,Y) copy(X.begin(), X.end(), Y.begin())
#define ALL(X,Y) for (auto X = (Y).begin(); X != (Y).end(); X++)
#define FULL(a)  (a).begin(),(a).end()
#define BFS(Q,S) for(Q.push(S);Q.size()!=0;Q.pop())
typedef long long int ll;
typedef unsigned long long int ull;
long long int M = pow(10, 9) + 7;


int dx[] = { 0,-1,0,1 }, dy[] = { -1,0,1,0 };

ll MAX(ll A, ll B) { return ((A) > (B) ? (A) : (B)); }
ll MIN(ll A, ll B) { return ((A) < (B) ? (A) : (B)); }
long long int xor128() {
	static long long int x = 123456789, y = 362436069, z = 521288629, w = 88675123;
	long long int t = (x ^ (x << 11));
	x = y; y = z; z = w;
	return (w = (w ^ (w >> 19)) ^ (t ^ (t >> 8)));
}

struct HashPair {
	//注意 constがいる
	template<class T1, class T2>
	size_t operator()(const pair<T1, T2> &p) const {
		//first分をハッシュ化する
		auto hash1 = hash<T1>{}(p.first);
		//second分をハッシュ化する
		auto hash2 = hash<T2>{}(p.second);
		//重複しないようにハッシュ処理
		size_t seed = 0;
		seed ^= hash1 + 0x9e3779b9 + (seed << 6) + (seed >> 2);
		seed ^= hash2 + 0x9e3779b9 + (seed << 6) + (seed >> 2);
		return seed;
	}
};
template<class I1, class I2>
istream& operator>>(istream& s, pair<I1, I2>& in) {
	s >> in.first >> in.second;
	return s;
}

class runtime_modint {
	using u64 = std::uint_fast64_t;

	static u64 &mod() {
		static u64 mod_ = 0;
		return mod_;
	}

public:
	u64 a;
	runtime_modint(const u64 x = 0) : a(x % get_mod()) {}
	u64 &value() noexcept { return a; }
	const u64 &value() const noexcept { return a; }
	runtime_modint operator+(const runtime_modint rhs) const {
		return runtime_modint(*this) += rhs;
	}
	runtime_modint operator-(const runtime_modint rhs) const {
		return runtime_modint(*this) -= rhs;
	}
	runtime_modint operator*(const runtime_modint rhs) const {
		return runtime_modint(*this) *= rhs;
	}
	runtime_modint operator/(const runtime_modint rhs) const {
		return runtime_modint(*this) /= rhs;
	}
	runtime_modint &operator+=(const runtime_modint rhs) {
		a += rhs.a;
		if (a >= get_mod()) {
			a -= get_mod();
		}
		return *this;
	}
	runtime_modint &operator-=(const runtime_modint rhs) {
		if (a < rhs.a) {
			a += get_mod();
		}
		a -= rhs.a;
		return *this;
	}
	runtime_modint &operator*=(const runtime_modint rhs) {
		a = a * rhs.a % get_mod();
		return *this;
	}
	runtime_modint &operator/=(runtime_modint rhs) {
		u64 exp = get_mod() - 2;
		while (exp) {
			if (exp % 2) {
				*this *= rhs;
			}
			rhs *= rhs;
			exp /= 2;
		}
		return *this;
	}

	static void set_mod(const u64 x) { mod() = x; }
	static u64 get_mod() { return mod(); }
};

template<class group = long long int>
class calculator {
	group cal_add_sub(string& s, ll& now) {
		if (fail)return 0;
		group ret = cal_mult_div(s, now);
		while (1) {
			if (s[now] == '+') {
				now++;
				ret += cal_mult_div(s, now);
			}
			else if (s[now] == '-') {
				now++;
				ret -= cal_mult_div(s, now);
			}
			else return ret;
		}
	}
	group cal_mult_div(string& s, ll& now) {
		if (fail)return 0;
		group ret = cal_child(s, now);
		while (1) {
			if (s[now] == '*') {
				now++;
				ret *= cal_child(s, now);
			}
			else if (s[now] == '/') {
				now++;
				group x = cal_child(s, now);
				if (x.a == 0) {
					fail = 1;
					return 0;
				}
				ret /= x;
			}
			else return ret;
		}
	}

	group cal_child(string& s, ll& now) {
		if (fail)return 0;
		if (s[now] == '(') {
			now++;
			group ret = cal_add_sub(s, now);
			now++;
			return ret;
		}
		return get_group(s, now);
	}
	//ここが群によって変わる
	group get_group(string& s, ll& now) {
		group ret = 0;
		while (s[now] - '0' >= 0 && s[now] - '0' <= 9) {
			ret *= 10;
			ret += s[now] - '0';
			now++;
			if (now == s.size())return ret;
		}
		return ret;
	}
public:
	bool fail = 0;
	group solve(string& s) {
		ll now = 0;
		fail = 0;
		return cal_add_sub(s, now);
	}
};

int main() {
	calculator<runtime_modint> c;
	while (1) {
		string s;
		getline(cin, s);
		if (s[0] == '0')break;
		bool f = 0;
		ll p = 0;
		string math;
		LP(i,0,s.size()){
			if (s[i] == ':') f = 1;
			else if (!f) {
				p *= 10;
				p += s[i] - '0';
			}
			else {
				if (s[i] != ' ')math.push_back(s[i]);
			}
		}
		runtime_modint::set_mod(p);
		ll ans = c.solve(math).a;
		if (!c.fail)cout << math << " = " << ans << " (mod " << p << ")\n";
		else cout << "NG\n";
	}
	return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3464
final_rank: 14

code_snippet: #include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <bitset>
#include <climits>
#include <string>
#include <cmath>
#include <bitset>
#include <complex>
#include <functional>
#include <ctime>
#include <cassert>
#include <fstream>
#include <stack>
#include <random>
#include <iomanip>
#include <time.h>
#include <list>
#include <unordered_map>

#include <algorithm>
#include <array>

using namespace std;
typedef long long ll;
typedef long double dd;
typedef unsigned long long ull;
typedef vector<ll> vl;
typedef vector<dd> vd;
typedef vector<vector<ll>> vvl;
typedef vector<vector<dd>> vvd;
//#define i_7 (ll)(1E9+7)
#define i_7 998244353
#define i_5 i_7-2
ll mod(ll a){
    ll c=a%i_7;
    if(c>=0)return c;
    return c+i_7;
}
typedef pair<ll,ll> l_l;
typedef pair<dd,dd> d_d;
ll inf=(ll)1E18;
#define rep(i,l,r) for(ll i=l;i<=r;i++)
#define pb push_back
ll max(ll a,ll b){if(a<b)return b;else return a;}
ll min(ll a,ll b){if(a>b)return b;else return a;}
dd EPS=1E-9;
dd PI=acos(-1);
#define endl "\n"
#define fastio ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);



ll hpow(ll x,ll y,ll p){
    if(y==0)return 1;
    ll res=hpow(x,y/2,p);
    res = (res*res)%p;
    if(y%2==1){
        res = (res*x)%p;
    }
    return res%p;
}


bool is_op(char c){
    vector<char> ops = {'+', '-', '*', '/'};
    rep(i,0,(ll)ops.size()-1){
        if(c == ops[i]){
            return true;
        }
    }
    return false;
}
string sNumber(string &s, ll &cur){
    string res;
    while(isdigit(s[cur])){
        res += s[cur];
        cur++;
    }
    return res;
}
ll Number(string &s, ll &cur){
    ll res=0;
    while(isdigit(s[cur])){
        res *= 10;
        res += s[cur] - '0';
        cur++;
    }
    return res;
}

ll exp(string &s, ll &cur, const ll p);
ll exp2(string &s, ll &cur, const ll p);
ll exp3(string &s, ll &cur, const ll p);
string Ans(string &s, ll &cur, const ll p);

bool valid;

ll exp(string &s, ll &cur, const ll p){
    ll res = exp2(s, cur, p);
    while(cur < s.size() && (s[cur] == '+' || s[cur] == '-')){
        char op = s[cur];
        cur++;
        ll tmp = exp2(s, cur, p);
        if(op == '+'){
            res = ((res + tmp) % p + p)%p;
        }else{
            res = ((res - tmp) % p + p)%p;
        }
    }
    return (res+p)%p;
}
ll exp2(string &s, ll &cur, const ll p){
    ll res = exp3(s, cur, p);
    while(cur < s.size() && (s[cur] == '*' || s[cur] == '/')){
        char op = s[cur];
        cur++;
        ll tmp = exp3(s, cur, p);
        if(op == '*'){
            res = ((res * tmp) % p + p)%p;
        }else{
            if(tmp == 0){
                valid = false;
            }
            res = ((res * hpow(tmp, p-2, p)) % p + p)%p;
        }
    }
    return (res+p)%p;
}
ll exp3(string &s, ll &cur, const ll p){
    if(s[cur] == '('){
        cur++;
        ll res = exp(s, cur, p);
        assert(s[cur] == ')');
        cur++;
        return (res+p)%p;
    }else{
        return Number(s, cur)%p;
    }
}

ll str_to_ll(string s){
    ll res =0 ;
    rep(i,0,(ll)s.size()-1){
        res *= 10;
        res += s[i] -'0';
    }
    return res;
}


signed main(){fastio
    while(true){
        string s;
        getline(cin, s);
        if(s[0]=='0'){
            break;
        }
        ll cur=0;
        string ps;
        string t;
        bool hoge=true;
        rep(i,0,(ll)s.size()-1){
            if(s[i] == ' ')continue;
            if(s[i] == ':'){
                hoge=false;
                continue;
            }
            if(hoge){
                ps += s[i];
            }else{
                t += s[i];
            }
        }
        ll p = str_to_ll(ps);
        valid = true;
        ll res = exp(t, cur, p);
        if(valid){
            cout<<t<<" = "<<res<<" (mod "<<p<<")"<<endl;
        }else{
            cout<<"NG"<<endl;
        }
    }
}
accuracy: 1
time_ms: 30
memory_kb: 3780
final_rank: 16

code_snippet: /*
　　　∫ ∫ ∫
　　　ノヽ
　　（＿　 ）
　（＿　　　 ）
（＿＿＿＿＿＿ ）
　ヽ(´･ω･)ﾉ　
　　 |　 /
　　 UU
*/
#pragma region macro
#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>
#include <vector>
#include <cassert>
#include <cmath>
#include <utility>
#include <tuple>
#include <map>
#include <set>
#include <deque>
#include <queue>
typedef long long int64;
using namespace std;
typedef vector<int> vi;
const int64 INF = 1LL << 62;
const int inf = 1<<30;
const char bn = '\n';
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return 1; } return 0; }
#define REP(i, n) for (int i = 0; i < (n); i++)
#define ALL(obj) (obj).begin(), (obj).end() //コンテナじゃないと使えない!!
#define debug(x) cerr << #x << ": " << (x) << "\n";
#define mp make_pair
template <typename T>
ostream& operator<<(ostream& os, const vector<T> &V){
    int N = V.size();
    REP(i,N){
        os << V[i];
        if (i!=N-1) os << " ";
    }
    os << "\n";
    return os;
}
template <typename T,typename S>
ostream& operator<<(ostream& os, pair<T,S> const&P){
    os << "(";
    os << P.first;
    os << " , ";
    os << P.second;
    os << ")";
    return os;
}
template <typename T,typename S,typename U>
ostream& operator<<(ostream& os, tuple<T,S,U> const& P){
    os << "(";
    os << get<0>(P);
    os << ", ";
    os << get<1>(P);
    os << ", ";
    os << get<2>(P);
    os << ")";
    return os;
}
template <typename T>
ostream& operator<<(ostream& os, set<T> &S){
    auto it=S.begin();
    while(it!=S.end()){
        os << *it;
        os << " ";
        it++;
    }
    os << "\n";
    return os;
}
template <typename T>
ostream& operator<<(ostream& os, deque<T> &q){
    for(auto it=q.begin();it<q.end();it++){
        os<<*it;
        os<<" ";
    }
    os<<endl;
    return os;
}
template <typename T,typename S>
ostream& operator<<(ostream& os, map<T,S> const&M){
    for(auto e:M){
        os<<e;
    }
    os<<endl;
    return os;
}
vector<pair<int,int>> dxdy = {mp(0,1),mp(1,0),mp(-1,0),mp(0,-1)};
#pragma endregion
//fixed<<setprecision(10)<<ans<<endl;


int64 pow(int a,int b,int mod){
    vector<bool> bit;
    for(b=b;b>0;b>>=1){
        bit.push_back(b&1);
    }
    vector<int64> fac(bit.size()); fac[0] = a;
    int64 res = 1;
    for(int i=1;i<bit.size();i++){
        fac[i] = (fac[i-1] * fac[i-1])%mod;
    }
    for(int i=0;i<bit.size();i++){
        if(bit[i]) res*=fac[i];
        res%=mod;
    }
    return res;
}


int MOD;
//mint
struct mint {
    int64 x;
    mint(int64 x=0):x((x+2*MOD)%MOD){}
    mint& operator+=(const mint a) {
        if ((x += a.x) >= MOD) x -= MOD;
        return *this;
    }
    mint& operator-=(const mint a) {
        if ((x += MOD-a.x) >= MOD) x -= MOD;
        return *this;
    }
    mint& operator*=(const mint a) {
        (x *= a.x) %= MOD;
        return *this;
    }
    mint operator+(const mint a) const {
        mint res(*this);
        return res+=a;
    }
    mint operator-(const mint a) const {
        mint res(*this);
        return res-=a;
    }
    mint operator*(const mint a) const {
        mint res(*this);
        return res*=a;
    }
    mint pow(int64 t) const {
        if (!t) return 1;
        mint a = pow(t>>1);
        a *= a;
        if (t&1) a *= *this;
        return a;
    }

    // for prime MOD
    mint inv() const {
        return pow(MOD-2);
    }
    mint& operator/=(const mint a) {
        return (*this) *= a.inv();
    }
    mint operator/(const mint a) const {
        mint res(*this);
        return res/=a;
    }
};
ostream& operator<<(ostream& os, mint a){
    os << a.x;
    return os;
}

// 構文解析
/*
    構文解析でよくあるバグは次の二つです。
    - begin++をし忘れる
    - getlineとcinの混合
*/


typedef string::const_iterator State;
class ParseError {};

// beginがexpectedを指していたらbeginを一つ進める。
void consume(State &begin, char expected) {
    if (*begin == expected) {
        begin++;
    } else {
        cerr << "Expected '" << expected << "' but got '" << *begin << "'"
            << endl;
        cerr << "Rest string is '";
        while (*begin) {
            cerr << *begin++;
        }
        cerr << "'" << endl;
        throw ParseError();
    }
}
void print_rest_string(State begin){
    cerr << "Rest string is '";
    while (*begin) {
        cerr << *begin++;
    }
    cerr << "'" << endl;
}
mint expression(State &begin);
mint term(State &begin);
mint factor(State &begin);
mint number(State &begin);

bool NG = false;
// 四則演算の式をパースして、その評価結果を返す。
mint expression(State &begin){
    mint res = term(begin);

    while(true){
        if(*begin == '+'){
            consume(begin, '+');
            res += term(begin);
        }else if(*begin == '-'){
            consume(begin, '-');
            res -= term(begin);
        }else{
            break;
        }
    }

    return res;
}

// 乗算除算の式をパースして、その評価結果を返す。
mint term(State &begin){
    mint res = factor(begin);
    
    while(true){
        if(*begin == '*'){
            consume(begin, '*');
            res *= factor(begin);
        }else if(*begin == '/'){
            consume(begin, '/');
            mint val = factor(begin);
            if(val.x == 0){
                NG = true;
            }
            res /= val;
        }else{
            break;
        }
    }

    return res;
}

mint factor(State &begin){
    if(*begin == '('){
        consume(begin, '('); // '('を飛ばす。
        mint res = expression(begin);
        consume(begin, ')'); // ')'を飛ばす。
        return res;
    }else{
        return number(begin);
    }
}

// 数字の列をパースして、その数を返す。
mint number(State &begin){
    mint res = 0;
    while(isdigit(*begin)){
        res *= 10;
        res += *begin - '0';
        begin++;
    }

    return res;
}

void solve(string S){
    State begin = S.begin();
    // debug(S)
    // debug(MOD)
    NG=false;
    mint ans = expression(begin);
    if(NG){
        cout << "NG" << endl;
    }else{
        cout << S << " = " << ans.x << " (mod " << MOD << ")" << endl;
    }
}


int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    string S; ;
    while(getline(cin,S)){
        if(S[0] == '0') break;
        string T;
        bool flag = false;
        string MOD_str = "";
        for(auto s:S){
            if(flag){
                if(s!=' ') T += s;
            }else{
                if(s==':') flag=true;
                else MOD_str+=s;
            }
        }
        MOD=stoi(MOD_str);
        solve(T);
    }
}
accuracy: 1
time_ms: 40
memory_kb: 3528
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;
int modpow(int a, int b, int mod){
  int ans = 1;
  while (b > 0){
    if (b % 2 == 1){
      ans *= a;
      ans %= mod;
    }
    a *= a;
    a %= mod;
    b /= 2;
  }
  return ans;
}
int modinv(int a, int mod){
  return modpow(a, mod - 2, mod);
}
int expr(string &s, int mod, int &p);
int factor(string &s, int mod, int &p){
  if (s[p] == '('){
    p++;
    int ans = expr(s, mod, p);
    p++;
    return ans;
  } else {
    int ans = 0;
    while (isdigit(s[p]) != 0){
      ans = ans * 10 + (s[p] - '0');
      ans %= mod;
      p++;
    }
    return ans;
  }
}
int term(string &s, int mod, int &p){
  int ans = factor(s, mod, p);
  if (ans == -1){
    return -1;
  }
  while (true){
    char c = s[p];
    if (c != '*' && c != '/'){
      break;
    }
    p++;
    int ans2 = factor(s, mod, p);
    if (ans2 == -1){
      return -1;
    }
    if (c == '*'){
      ans *= ans2;
      ans %= mod;
    }
    if (c == '/'){
      if (ans2 == 0){
        return -1;
      }
      ans *= modinv(ans2, mod);
      ans %= mod;
    }
  }
  return ans;
}
int expr(string &s, int mod, int &p){
  int ans = term(s, mod, p);
  if (ans == -1){
    return -1;
  }
  while (true){
    char c = s[p];
    if (c != '+' && c != '-'){
      break;
    }
    p++;
    int ans2 = term(s, mod, p);
    if (ans2 == -1){
      return -1;
    }
    if (c == '+'){
      ans += ans2;
      ans %= mod;
    }
    if (c == '-'){
      ans += mod - ans2;
      ans %= mod;
    }
  }
  return ans;
}
int main(){
  while (true){
    int p;
    char c;
    string s;
    cin >> p >> c;
    getline(cin, s);
    if (p == 0 && s == ""){
      break;
    }
    int N = s.size();
    string t;
    for (int i = 0; i < N; i++){
      if (s[i] != ' '){
        t += s[i];
      }
    }
    t += '=';
    int x = 0;
    int ans = expr(t, p, x);
    t.pop_back();
    if (ans == -1){
      cout << "NG" << endl;
    } else {
      cout << t << " = " << ans << " (mod " << p << ")" << endl;
    }
  }
}
accuracy: 1
time_ms: 20
memory_kb: 3480
final_rank: 3

code_snippet: #include <iostream>
#include <vector>
#include <string>
using namespace std;
using ll = long long int;
class ParseError{};

struct Solver{
    const ll p;
    const string s;
    ll expr(int &);
    ll term(int &);
    ll factor(int &);
    ll number(int &);
    Solver(ll p, const string &expression): p(p), s(expression){

    };

    ll modpow(ll a, ll x){
        ll ans = 1;
        while(x > 0){
            if(x & 1){
                ans *= a;
                ans %= p;
            }
            a *= a;
            a %= p;
            x >>= 1;
        }
        return ans;
    }

    

    void solve(){
        try{
            int i = 0;
            ll ans = expr(i);
            cout << s << " = " << ans << " (mod " << p << ")" << '\n';
        }catch(ParseError e){
            cout << "NG" << '\n';
        }
    }
};
ll Solver::expr(int &i){
    ll ans = term(i);
    while(s[i] == '+' || s[i] == '-'){
        char op = s[i++];
        ll v2 = term(i);
        if(op == '+') ans += v2;
        else ans -= v2;
        while(ans < 0) ans += p;
        ans %= p;
    }
    return ans;
}

ll Solver::term(int &i){
    ll ans = factor(i);
    while(s[i] == '*' || s[i] == '/'){
        char op = s[i++];
        ll v2 = factor(i);
        v2 %= p;
        if(op == '*') ans *= v2;
        else{
            if(v2 == 0) throw ParseError();
            else{
                ans *= modpow(v2, p-2);
            }
        }
        ans %= p;
    }
    return ans;
}

ll Solver::factor(int &i){
    if(isdigit(s[i])) return number(i);
    else{
        ++i;
        ll ans = expr(i);
        ++i;
        return ans;
    }
}

ll Solver::number(int &i){
    ll ans = 0;
    while(isdigit(s[i])) ans = ans*10 + s[i++]-'0';
    return ans%p;
}

int main(){
    while(true){
        string line;
        getline(cin, line);
        if(line == "0:") break;

        ll p = 0;
        string expression = "";
        int i = 0;
        for(; i < line.length(); i++){
            if(line[i] != ':'){
                p *= 10;
                p += line[i]-'0';
            }else break;
        }
        i++;
        for(; i < line.length(); i++){
            if(line[i] != ' ') expression += line[i];
        }

        Solver sol(p, expression);
        sol.solve();
    }
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3528
final_rank: 11

code_snippet: #define _USE_MATH_DEFINES
#include<iostream>
#include<string>
#include<sstream>
#include<regex>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<list>
#include<algorithm>
#include<numeric>
#include<cmath>
#include<iomanip>
#include<random>
using namespace std;
#define int long long
#define uint unsigned long long
const int mod=1e9+7;
const int inf=mod*mod;
const double eps=1e-10;
int p;
int myplus(int n,int m){
	if(n==-1||m==-1)
		return -1;
	return(n+m)%p;
}
int myminus(int n,int m){
	if(n==-1||m==-1)
		return -1;
	return(n-m+p)%p;
}
int myprod(int n,int m){
	if(n==-1||m==-1)
		return -1;
	return n*m%p;
}
int mydiv(int n,int m){
	if(n==-1||m==-1||m==0)
		return -1;
	int inv=1,ex=p-2;
	while(ex){
		if(ex&1)
			inv=myprod(inv,m);
		m=myprod(m,m);
		ex>>=1;
	}
	return myprod(n,inv);
}
typedef string::const_iterator state;
int expr(state&it);
int number(state&it){
	int ret;
	for(ret=0;'0'<=*it&&*it<='9';it++)
		ret=ret*10+*it-'0';
	return ret;
}
int factor(state&it){
	if('0'<=*it&&*it<='9')
		return number(it);
	int ret=expr(++it);
	it++;
	return ret;
}
int term(state&it){
	int ret=factor(it);
	while(1){
		if(*it=='*')
			ret=myprod(ret,factor(++it));
		else if(*it=='/')
			ret=mydiv(ret,factor(++it));
		else
			return ret;
	}
}
int expr(state&it){
	int ret=term(it);
	while(1){
		if(*it=='+')
			ret=myplus(ret,term(++it));
		else if(*it=='-')
			ret=myminus(ret,term(++it));
		else
			return ret;
	}
}
signed main(){
	while(cin>>p,p){
		cin.ignore();
		string s;
		getline(cin,s);
		s.erase(remove(s.begin(),s.end(),' '),s.end());
		s+='a';
		state it=s.begin();
		int ans=expr(it);
		s.pop_back();
		if(ans==-1)
			cout<<"NG"<<endl;
		else
			cout<<s<<" = "<<ans<<" (mod "<<p<<')'<<endl;
	}
}
accuracy: 1
time_ms: 30
memory_kb: 3444
final_rank: 7