Problem:
Score : 900 points

Problem Statement

Takahashi has an N \times N grid. The square at the i-th row and the j-th column of the grid is denoted by (i,j).
Particularly, the top-left square of the grid is (1,1), and the bottom-right square is (N,N).

An integer, 0 or 1, is written on M of the squares in the Takahashi's grid.
Three integers a_i,b_i and c_i describe the i-th of those squares with integers written on them: the integer c_i is written on the square (a_i,b_i).

Takahashi decides to write an integer, 0 or 1, on each of the remaining squares so that the condition below is satisfied.
Find the number of such ways to write integers, modulo 998244353.

For all 1\leq i < j\leq N, there are even number of 1s in the square region whose top-left square is (i,i) and whose bottom-right square is (j,j).

Constraints

2 \leq N \leq 10^5

0 \leq M \leq min(5 \times 10^4,N^2)

1 \leq a_i,b_i \leq N(1\leq i\leq M)

0 \leq c_i \leq 1(1\leq i\leq M)

If i \neq j, then (a_i,b_i) \neq (a_j,b_j).

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N M
a_1 b_1 c_1
:
a_M b_M c_M

Output

Print the number of possible ways to write integers, modulo 998244353.

Sample Input 1

3 3
1 1 1
3 1 0
2 3 1

Sample Output 1

8

For example, the following ways to write integers satisfy the condition:

101 111
011 111
000 011

Sample Input 2

4 5
1 3 1
2 4 0
2 3 1
4 2 1
4 4 1

Sample Output 2

32

Sample Input 3

3 5
1 3 1
3 3 0
3 1 0
2 3 1
3 2 1

Sample Output 3

0

Sample Input 4

4 8
1 1 1
1 2 0
3 2 1
1 4 0
2 1 1
1 3 0
3 4 1
4 4 1

Sample Output 4

4

Sample Input 5

100000 0

Sample Output 5

342016343

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

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

using s64 = long long;

const int N = 100000;
const int M = 998244353;

int n, m;
int f[N + 1][16];

int power[N + 1];

struct point_t {
  int x, y, w, d;
  point_t() {}
  point_t(int x, int y, int w)
    : x(x), y(y), w(w) {
    d = max(x, y) - min(x, y);
  }

  friend bool operator<(point_t a, point_t b) {
    return a.d < b.d;
  }
};
vector<point_t> g[N + 1];

int main() {
  scanf("%d %d", &n, &m);
  for (int i = 0; i < m; ++i) {
    int x, y, w;
    scanf("%d %d %d", &x, &y, &w);
    int k = max(x, y);
    g[k].emplace_back(x, y, w);
  }
  for (int i = 1; i <= n; ++i) {
    sort(g[i].begin(), g[i].end());
  }

  power[0] = 1;
  for (int i = 1; i <= n; ++i) {
    power[i] = power[i - 1] * 2 % M;
  }

  for (int s = 0; s < 16; ++s) {
    bool match = ~__builtin_popcount(s) & 1;
    for (int i = 1; i <= 2 && match; ++i) {
      for (point_t p : g[i]) {
        int id = (p.x - 1) * 2 + p.y - 1;
        if ((s >> id & 1) != p.w) {
          match = false;
          break;
        }
      }
    }
    if (match) {
      f[2][s] = 1;
    }
  }
  for (int i = 3; i <= n; ++i) {
    for (int s = 0; s < 16; ++s) {
      bool match = ~__builtin_popcount(s) & 1;
      int j = 0;
      while (j < g[i - 1].size() && g[i - 1][j].d < 1 && match) {
        point_t p = g[i - 1][j];
        int id = (p.x - (i - 1)) * 2 + p.y - (i - 1);
        if ((s >> id & 1) != p.w) {
          match = false;
          break;
        }
        ++j;
      }
      j = 0;
      while (j < g[i].size() && g[i][j].d < 2 && match) {
        point_t p = g[i][j];
        int id = (p.x - (i - 1)) * 2 + p.y - (i - 1);
        if ((s >> id & 1) != p.w) {
          match = false;
          break;
        }
        ++j;
      }
      if (!match) {
        continue;
      }
      for (int t = 0; t < 16; ++t) {
        if ((t >> 3 & 1) == (s & 1) && f[i - 1][t]) {
          int current = j;
          int need = (__builtin_popcount(s) & 1) ^ (__builtin_popcount(t) & 1) ^ (s & 1), remain = 2;
          while (current < g[i].size()) {
            point_t p = g[i][current];
            if (p.d > 2) {
              break;
            }
            need ^= p.w;
            --remain;
            ++current;
          }
          int sum = 0;
          if (!remain) {
            if (need) {
              continue;
            }
            sum = 1;
          } else {
            sum = remain;
          }
          int free = i - 3;
          while (current < g[i].size()) {
            point_t p = g[i][current];
            int next = current;
            need = 0;
            remain = 2;
            while (next < g[i].size()) {
              point_t q = g[i][next];
              if (q.d != p.d) {
                break;
              }
              need ^= q.w;
              --remain;
              ++next;
            }
            if (!remain && need) {
              sum = 0;
              break;
            }
            if (remain > 0) {
              sum = sum * remain % M;
            }
            current = next;
            --free;
          }
          f[i][s] = (f[i][s] + (s64)power[free] * sum % M * f[i - 1][t]) % M;
        }
      }
    }
  }

  int answer = 0;
  for (int i = 0; i < 16; ++i) {
    answer = (answer + f[n][i]) % M;
  }
  cout << answer << endl;

  return 0;
}