#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;
}

Measured memory_bytes: 10752