//#pragma GCC optimize("Ofast") //#pragma GCC target("avx") //#undef LOCAL #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; using uint = unsigned int; using ll = long long; using ull = unsigned long long; constexpr ll TEN(int n) { return (n == 0) ? 1 : 10 * TEN(n - 1); } template using V = vector; template using VV = V>; #include struct Scanner { int fd = -1; char line[(1 << 15) + 1]; size_t st = 0, ed = 0; void reread() { memmove(line, line + st, ed - st); ed -= st; st = 0; ed += ::read(fd, line + ed, (1 << 15) - ed); line[ed] = '\0'; } bool succ() { while (true) { if (st == ed) { reread(); if (st == ed) return false; } while (st != ed && isspace(line[st])) st++; if (st != ed) break; } if (ed - st <= 50) { bool sep = false; for (size_t i = st; i < ed; i++) { if (isspace(line[i])) { sep = true; break; } } if (!sep) reread(); } return true; } template ::value, int> = 0> bool read_single(T& ref) { if (!succ()) return false; while (true) { size_t sz = 0; while (st + sz < ed && !isspace(line[st + sz])) sz++; ref.append(line + st, sz); st += sz; if (!sz || st != ed) break; reread(); } return true; } template ::value>* = nullptr> bool read_single(T& ref) { if (!succ()) return false; bool neg = false; if (line[st] == '-') { neg = true; st++; } ref = T(0); while (isdigit(line[st])) { ref = 10 * ref + (line[st++] & 0xf); } if (neg) ref = -ref; return true; } template bool read_single(V& ref) { for (auto& d : ref) { if (!read_single(d)) return false; } return true; } void read() {} template void read(H& h, T&... t) { bool f = read_single(h); assert(f); read(t...); } int read_unsafe() { return 0; } template int read_unsafe(H& h, T&... t) { bool f = read_single(h); if (!f) return 0; return 1 + read_unsafe(t...); } Scanner(FILE* fp) : fd(fileno(fp)) {} }; struct Printer { public: template void write() {} template void write(const H& h, const T&... t) { if (F) write_single(' '); write_single(h); write(t...); } template void writeln(const T&... t) { write(t...); write_single('\n'); } Printer(FILE* _fp) : fp(_fp) {} ~Printer() { flush(); } private: static constexpr size_t SIZE = 1 << 15; FILE* fp; char line[SIZE], small[50]; size_t pos = 0; void flush() { fwrite(line, 1, pos, fp); pos = 0; } void write_single(const char& val) { if (pos == SIZE) flush(); line[pos++] = val; } template ::value>* = nullptr> void write_single(T val) { if (pos > (1 << 15) - 50) flush(); if (val == 0) { write_single('0'); return; } if (val < 0) { write_single('-'); val = -val; // todo min } size_t len = 0; while (val) { small[len++] = char(0x30 | (val % 10)); val /= 10; } for (size_t i = 0; i < len; i++) { line[pos + i] = small[len - 1 - i]; } pos += len; } void write_single(__int128 val) { if (pos > (1 << 15) - 50) flush(); if (val == 0) { write_single('0'); return; } if (val < 0) { write_single('-'); val = -val; // todo min } size_t len = 0; while (val) { small[len++] = char(0x30 | (val % 10)); val /= 10; } for (size_t i = 0; i < len; i++) { line[pos + i] = small[len - 1 - i]; } pos += len; } void write_single(const string& s) { for (char c : s) write_single(c); } void write_single(const char* s) { size_t len = strlen(s); for (size_t i = 0; i < len; i++) write_single(s[i]); } template void write_single(const V& val) { auto n = val.size(); for (size_t i = 0; i < n; i++) { if (i) write_single(' '); write_single(val[i]); } } }; template struct ModInt { using M = ModInt; static constexpr uint get_mod() { return MD; } const static M G; uint v; ModInt(ll _v = 0) { set_v(uint(_v % MD + MD)); } M& set_v(uint _v) { v = (_v < MD) ? _v : _v - MD; return *this; } explicit operator bool() const { return v != 0; } M operator-() const { return M() - *this; } M operator+(const M& r) const { return M().set_v(v + r.v); } M operator-(const M& r) const { return M().set_v(v + MD - r.v); } M operator*(const M& r) const { return M().set_v(uint(ull(v) * r.v % MD)); } M operator/(const M& r) const { return *this * r.inv(); } M& operator+=(const M& r) { return *this = *this + r; } M& operator-=(const M& r) { return *this = *this - r; } M& operator*=(const M& r) { return *this = *this * r; } M& operator/=(const M& r) { return *this = *this / r; } bool operator==(const M& r) const { return v == r.v; } M pow(ll n) const { M x = *this, r = 1; while (n) { if (n & 1) r *= x; x *= x; n >>= 1; } return r; } M inv() const { return pow(MD - 2); } friend ostream& operator<<(ostream& os, const M& r) { return os << r.v; } }; // using Mint = ModInt<998244353>; // template<> const Mint Mint::G = Mint(3); // bit op int popcnt(uint x) { return __builtin_popcount(x); } int popcnt(ull x) { return __builtin_popcountll(x); } int bsr(uint x) { return 31 - __builtin_clz(x); } int bsr(ull x) { return 63 - __builtin_clzll(x); } int bsf(uint x) { return __builtin_ctz(x); } int bsf(ull x) { return __builtin_ctzll(x); } //binary gcd ll gcd(ll _a, ll _b) { ull a = abs(_a), b = abs(_b); if (a == 0) return b; if (b == 0) return a; int shift = bsf(a|b); a >>= bsf(a); do { b >>= bsf(b); if (a > b) swap(a, b); b -= a; } while (b); return (a << shift); } /// g:gcd(a, b), ax+by=g struct EG { ll g, x, y; }; EG ext_gcd(ll a, ll b) { if (b == 0) { if (a >= 0) return EG{a, 1, 0}; else return EG{-a, -1, 0}; } else { auto e = ext_gcd(b, a % b); return EG{e.g, e.y, e.x - a / b * e.y}; } } ll inv_mod(ll x, ll md) { auto z = ext_gcd(x, md).x; return (z % md + md) % md; } template T pow_mod(T x, U n, T md) { T r = 1 % md; x %= md; while (n) { if (n & 1) r = (r * x) % md; x = (x * x) % md; n >>= 1; } return r; } // (rem, mod) pair crt(const V& b, const V& c) { int n = int(b.size()); ll r = 0, m = 1; for (int i = 0; i < n; i++) { auto eg = ext_gcd(m, c[i]); ll g = eg.g, im = eg.x; if ((b[i] - r) % g) return {0, -1}; ll tmp = (b[i] - r) / g * im % (c[i] / g); r += m * tmp; m *= c[i] / g; } return {(r % m + m) % m, m}; } template void nft(bool type, V& a) { int n = int(a.size()), s = 0; while ((1 << s) < n) s++; assert(1 << s == n); static V ep, iep; while (int(ep.size()) <= s) { ep.push_back(Mint::G.pow(Mint(-1).v / (1 << ep.size()))); iep.push_back(ep.back().inv()); } V b(n); for (int i = 1; i <= s; i++) { int w = 1 << (s - i); Mint base = type ? iep[i] : ep[i], now = 1; for (int y = 0; y < n / 2; y += w) { for (int x = 0; x < w; x++) { auto l = a[y << 1 | x]; auto r = now * a[y << 1 | x | w]; b[y | x] = l + r; b[y | x | n >> 1] = l - r; } now *= base; } swap(a, b); } } template V multiply_nft(const V& a, const V& b) { int n = int(a.size()), m = int(b.size()); if (!n || !m) return {}; if (min(n, m) <= 8) { V ans(n + m - 1); for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) ans[i + j] += a[i] * b[j]; return ans; } int lg = 0; while ((1 << lg) < n + m - 1) lg++; int z = 1 << lg; auto a2 = a, b2 = b; a2.resize(z); b2.resize(z); nft(false, a2); nft(false, b2); for (int i = 0; i < z; i++) a2[i] *= b2[i]; nft(true, a2); a2.resize(n + m - 1); Mint iz = Mint(z).inv(); for (int i = 0; i < n + m - 1; i++) a2[i] *= iz; return a2; } // Cooley-Tukey: input -> butterfly -> bit reversing -> output から // bit reversingを抜いたもの 直接使うな template void butterfly(bool type, V& a) { int n = int(a.size()), h = 0; while ((1 << h) < n) h++; assert(1 << h == n); if (n == 1) return; static V snow, sinow; if (snow.empty()) { Mint sep = Mint(1), siep = Mint(1); uint mod = Mint(-1).v; uint di = 4; while (mod % di == 0) { Mint ep = Mint::G.pow(mod / di); Mint iep = ep.inv(); snow.push_back(siep * ep); sinow.push_back(sep * iep); sep *= ep; siep *= iep; di *= 2; } } if (!type) { // fft for (int ph = 1; ph <= h; ph++) { // phase ph: size w -> 2w の FFT, p 並列 int w = 1 << (ph - 1), p = 1 << (h - ph); Mint now = Mint(1); for (int s = 0; s < w; s++) { int offset = s << (h - ph + 1); for (int i = 0; i < p; i++) { auto l = a[i + offset]; auto r = a[i + offset + p] * now; a[i + offset] = l + r; a[i + offset + p] = l - r; } int u = bsf(~uint(s)); now *= snow[u]; } } } else { // ifft for (int ph = h; ph >= 1; ph--) { int w = 1 << (ph - 1), p = 1 << (h - ph); Mint inow = Mint(1); for (int s = 0; s < w; s++) { int offset = s << (h - ph + 1); for (int i = 0; i < p; i++) { auto l = a[i + offset]; auto r = a[i + offset + p]; a[i + offset] = l + r; a[i + offset + p] = (l - r) * inow; } int u = bsf(~uint(s)); inow *= sinow[u]; } } } } template V multiply(const V& a, const V& b) { int n = int(a.size()), m = int(b.size()); if (!n || !m) return {}; if (min(n, m) < 8) { V ans(n + m - 1); for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) ans[i + j] += a[i] * b[j]; return ans; } int lg = 0; while ((1 << lg) < n + m - 1) lg++; int z = 1 << lg; auto a2 = a; a2.resize(z); butterfly(false, a2); if (a == b) { for (int i = 0; i < z; i++) a2[i] *= a2[i]; } else { auto b2 = b; b2.resize(z); butterfly(false, b2); for (int i = 0; i < z; i++) a2[i] *= b2[i]; } butterfly(true, a2); a2.resize(n + m - 1); Mint iz = Mint(z).inv(); for (int i = 0; i < n + m - 1; i++) a2[i] *= iz; return a2; } using mint = ModInt<998244353>; template<> const mint mint::G = mint(3); Scanner sc = Scanner(stdin); Printer pr = Printer(stdout); int main() { int x, y; ll t; int a, b, c, d; sc.read(x, y, t, a, b, c, d); a--; b--; c--; d--; if ((a+b+c+d) % 2 != t % 2) { pr.writeln(0); return 0; } bool sig = t % 2; t -= t % 2; auto but2 = [&](bool type, VV& a) { int h = int(a.size()); int w = int(a[0].size()); for (auto& x : a) { butterfly(type, x); } V buf(h); for (int i = 0; i < w; i++) { for (int j = 0; j < h; j++) { buf[j] = a[j][i]; } butterfly(type, buf); for (int j = 0; j < h; j++) { a[j][i] = buf[j]; } } }; auto mul = [&](VV a, VV b) { int h = int(a.size()); int w = int(a[0].size()); but2(false, a); but2(false, b); for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { a[i][j] *= b[i][j]; } } but2(true, a); mint in = (mint(h) * w).inv(); for (auto& v: a) for (auto& x: v) x *= in; return a; /* VV c(h, V(w)); for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { for (int k = 0; k < h; k++) { for (int l = 0; l < w; l++) { c[(i + k) % h][(j + l) % w] += a[i][j] * b[k][l]; } } } } return c;*/ }; int h = 2 << x; int w = 2 << y; VV f(h, V(w)); { f[0][0] += mint(1); f[0][1] += mint(1); f[1][0] += mint(1); f[0][w-1] += mint(1); f[h-1][0] += mint(1); VV g(h, V(w)); g[a][b] = 1; auto t2 = t; while (t2) { if (t2 & 1) { g = mul(f, g); } f = mul(f, f); t2 >>= 1; } f = g; } auto solve = [&](int tx, int ty) { mint ans = 0; ans += f[tx][ty]; ans -= f[h - 2 - tx][ty]; ans -= f[tx][w - 2 - ty]; ans += f[h - 2 - tx][w - 2 - ty]; return ans; }; mint ans = solve(c, d); if (sig) { ans = solve(c, d); if (c) ans += solve(c - 1, d); if (d) ans += solve(c, d - 1); if (c + 1 < ((1 << x) - 1)) ans += solve(c + 1, d); if (d + 1 < ((1 << y) - 1)) ans += solve(c, d + 1); } pr.writeln(ans.v); return 0; }