description: A matrix of size n × m, such that each cell of it contains either 0 or 1, is considered beautiful if the sum in every contiguous submatrix of size 2 × 2 is exactly 2, i. e. every "square" of size 2 × 2 contains exactly two 1's and exactly two 0's.
  
  You are given a matrix of size n × m. Initially each cell of this matrix is empty. Let's denote the cell on the intersection of the x-th row and the y-th column as (x, y). You have to process the queries of three types:
  
    * x y -1 — clear the cell (x, y), if there was a number in it; 
    * x y 0 — write the number 0 in the cell (x, y), overwriting the number that was there previously (if any); 
    * x y 1 — write the number 1 in the cell (x, y), overwriting the number that was there previously (if any). 
  
  
  
  After each query, print the number of ways to fill the empty cells of the matrix so that the resulting matrix is beautiful. Since the answers can be large, print them modulo 998244353.
  
  Input
  
  The first line contains three integers n, m and k (2 ≤ n, m ≤ 10^6; 1 ≤ k ≤ 3 ⋅ 10^5) — the number of rows in the matrix, the number of columns, and the number of queries, respectively.
  
  Then k lines follow, the i-th of them contains three integers x_i, y_i, t_i (1 ≤ x_i ≤ n; 1 ≤ y_i ≤ m; -1 ≤ t_i ≤ 1) — the parameters for the i-th query.
  
  Output
  
  For each query, print one integer — the number of ways to fill the empty cells of the matrix after the respective query, taken modulo 998244353.
  
  Example
  
  Input
  
  
  2 2 7
  1 1 1
  1 2 1
  2 1 1
  1 1 0
  1 2 -1
  2 1 -1
  1 1 -1
  
  
  Output
  
  
  3
  1
  0
  1
  2
  3
  6
solution: #include <bits/stdc++.h>
  #pragma GCC optimize("Ofast", "-funroll-loops", "-fdelete-null-pointer-checks")
  #pragma GCC target("ssse3", "sse3", "sse2", "sse", "avx2", "avx")
  #pragma GCC optimize(3, "Ofast", "inline")
  using namespace std;
  const long long mod = 998244353;
  void imult(long long& lhs, const long long& rhs) {
    lhs = ((lhs % mod) * (rhs % mod)) % mod;
  }
  void iadd(long long& lhs, const long long& rhs) {
    lhs = ((lhs % mod) + (rhs % mod)) % mod;
  }
  void isubt(long long& lhs, const long long& rhs) {
    long long ret = (lhs - rhs) % mod;
    lhs = ret + (ret < 0 ? mod : 0);
  }
  long long bpw(const long long& lhs, const long long& rhs) {
    if (rhs == 0) return 1;
    long long ret = bpw(lhs, rhs >> 1);
    imult(ret, ret);
    if (rhs & 1) imult(ret, lhs);
    return ret;
  }
  long long inv(const long long& x) { return bpw(x, mod - 2); }
  long long mult(const long long& lhs, const long long& rhs) {
    return ((lhs % mod) * (rhs % mod)) % mod;
  }
  long long add(const long long& lhs, const long long& rhs) {
    return ((lhs % mod) + (rhs % mod)) % mod;
  }
  long long subt(const long long& lhs, const long long& rhs) {
    long long ret = (lhs - rhs) % mod;
    return ret + (ret < 0 ? mod : 0);
  }
  long long divv(const long long& lhs, const long long& rhs) {
    return mult(lhs, inv(rhs));
  }
  const int sz = 1e6 + 5;
  set<int> rws0e[sz], rws1e[sz], cls0e[sz], cls1e[sz], rwscon, clscon, nerw, necl;
  set<pair<int, int> > zch, och;
  map<pair<int, int>, int> board;
  int n, m, k;
  long long cur;
  void add0(int x, int y) {
    board[{x, y}] = 0;
    if ((x + y) & 1)
      och.insert({x, y});
    else
      zch.insert({x, y});
    if (x & 1)
      cls1e[y].insert(x);
    else
      cls0e[y].insert(x);
    if (y & 1)
      rws1e[x].insert(y);
    else
      rws0e[x].insert(y);
    if (!rws1e[x].empty() && !rws0e[x].empty()) rwscon.insert(x);
    if (!cls1e[y].empty() && !cls0e[y].empty()) clscon.insert(y);
    nerw.insert(x);
    necl.insert(y);
  }
  void add1(int x, int y) {
    board[{x, y}] = 1;
    if ((x + y) & 1)
      zch.insert({x, y});
    else
      och.insert({x, y});
    if (x & 1)
      cls0e[y].insert(x);
    else
      cls1e[y].insert(x);
    if (y & 1)
      rws0e[x].insert(y);
    else
      rws1e[x].insert(y);
    if (!rws1e[x].empty() && !rws0e[x].empty()) rwscon.insert(x);
    if (!cls1e[y].empty() && !cls0e[y].empty()) clscon.insert(y);
    nerw.insert(x);
    necl.insert(y);
  }
  void del0(int x, int y) {
    board.erase({x, y});
    if ((x + y) & 1)
      och.erase({x, y});
    else
      zch.erase({x, y});
    if (x & 1)
      cls1e[y].erase(x);
    else
      cls0e[y].erase(x);
    if (y & 1)
      rws1e[x].erase(y);
    else
      rws0e[x].erase(y);
    if (rws1e[x].empty() || rws0e[x].empty()) rwscon.erase(x);
    if (cls1e[y].empty() || cls0e[y].empty()) clscon.erase(y);
    if (rws1e[x].empty() && rws0e[x].empty()) nerw.erase(x);
    if (cls1e[y].empty() && cls0e[y].empty()) necl.erase(y);
  }
  void del1(int x, int y) {
    board.erase({x, y});
    if ((x + y) & 1)
      zch.erase({x, y});
    else
      och.erase({x, y});
    if (x & 1)
      cls0e[y].erase(x);
    else
      cls1e[y].erase(x);
    if (y & 1)
      rws0e[x].erase(y);
    else
      rws1e[x].erase(y);
    if (rws1e[x].empty() || rws0e[x].empty()) rwscon.erase(x);
    if (cls1e[y].empty() || cls0e[y].empty()) clscon.erase(y);
    if (rws1e[x].empty() && rws0e[x].empty()) nerw.erase(x);
    if (cls1e[y].empty() && cls0e[y].empty()) necl.erase(y);
  }
  void upd(int x, int y, int t) {
    if (t == -1 || (board.find({x, y}) != board.end())) {
      if (board[{x, y}] == 0)
        del0(x, y);
      else
        del1(x, y);
    }
    if (t == 0) {
      add0(x, y);
    } else if (t == 1) {
      add1(x, y);
    }
    if (rwscon.empty() && clscon.empty()) {
      cur = add(bpw(2, m - necl.size()), bpw(2, n - nerw.size()));
      if (zch.empty()) isubt(cur, 1);
      if (och.empty()) isubt(cur, 1);
    } else {
      if (!rwscon.empty() && !clscon.empty())
        cur = 0;
      else if (!rwscon.empty()) {
        cur = bpw(2, m - necl.size());
      } else if (!clscon.empty()) {
        cur = bpw(2, n - nerw.size());
      }
    }
  }
  int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    ;
    cin >> n >> m >> k;
    cur = subt(add(bpw(2, n), bpw(2, m)), 2);
    while (k--) {
      int x, y, t;
      cin >> x >> y >> t;
      upd(--x, --y, t);
      cout << cur << '\n';
    }
    return 0;
  }
  