// 基本テンプレート
// #define _GLIBCXX_DEBUG // for STL debug (optional)
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <string>
#include <cstring>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <set>
#include <complex>
#include <cmath>
#include <limits>
#include <cfloat>
#include <climits>
#include <ctime>
#include <cassert>
#include <numeric>
#include <fstream>
#include <functional>
#include <bitset>
using namespace std;

#define debug(...) fprintf(stderr, __VA_ARGS__)
#define int long long int
 
template<typename T> void chmax(T &a, T b) {a = max(a, b);}
template<typename T> void chmin(T &a, T b) {a = min(a, b);}
template<typename T> void chadd(T &a, T b) {a = a + b;}
 
typedef pair<int, int> pii;
typedef long long ll;
 
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
const ll INF = 1001001001001001LL;
const ll MOD = 998244353LL;

map<int, int> exist_ld[100010], exist_ru[100010];
int diag[100010], dp[100010][2];

const int MAXF = 100010;
int fact[MAXF+10], finv[MAXF+10];

int mod_pow(int x, int k) {
    int res = 1;
    for(; k>0; k>>=1) {
        if(k & 1) (res *= x) %= MOD;
        (x *= x) %= MOD;
    }
    return res;
}

void init_comb() {
    fact[0] = 1;
    for(int i=1; i<=MAXF; i++) fact[i] = (fact[i-1] * i) % MOD;

    finv[MAXF] = mod_pow(fact[MAXF], MOD-2);
    for(int i=MAXF-1; i>=0; i--) {
        finv[i] = finv[i+1] * (i+1) % MOD;
    }
}

int comb(int n, int r) {
    if(r < 0 or n < r) return 0;
    return fact[n] * finv[n-r] % MOD * finv[r] % MOD;
}

int calc_comb_small(int pari, int deg_of_free) {
    int res = 0;
    for(int i=pari; i<=deg_of_free; i+=2) {
        (res += comb(deg_of_free, i)) %= MOD;
    }
    return res;
}

signed main() {
    init_comb();
    fill(diag, diag + 100000, -1);
    int N, M; cin >> N >> M;
    for(int i=0; i<M; i++) {
        int a, b, c; cin >> a >> b >> c;
        a--; b--;
        if(a == b) {
            diag[a] = c;
        }
        else if(a > b) {
            exist_ld[a][b] = c;
        }
        else if(a < b) {
            exist_ru[b][a] = c;
        }
    }

    if(diag[0] < 0) {
        dp[0][0] = dp[0][1] = 1;
    }
    else {
        dp[0][ diag[0] ] = 1;
    }

    for(int i=0; i<N-1; i++) {
        for(int k=0; k<2; k++) {
            for(int l=0; l<2; l++) {
                if(diag[i  ] >= 0 and diag[i  ] != k) continue;
                if(diag[i+1] >= 0 and diag[i+1] != l) continue;
                int pari = (k + l) % 2, deg_of_free = 0;
                int mul = 1;

                if(exist_ld[i+1].count(i)) {
                    pari += exist_ld[i+1][i];
                }
                else deg_of_free++;

                if(exist_ru[i+1].count(i)) {
                    pari += exist_ru[i+1][i];
                }
                else deg_of_free++;

                pari %= 2;
                // fprintf(stderr, "i = %lld, k = %lld, pari = %lld, deg_of_free = %lld\n", i, k, pari, deg_of_free);
                // fprintf(stderr, "comb = %lld\n", calc_comb_small(pari, deg_of_free));
                if(deg_of_free == 2) mul = 2;
                if(deg_of_free == 0 and pari != 0) continue;

                // 左上の偶奇
                pari = k;
                deg_of_free = i;
                int match = 0;
                for(auto e : exist_ld[i+1]) {
                    int coor, val; tie(coor, val) = e;
                    if(coor >= i) continue;

                    if(exist_ru[i+1].count(coor)) {
                        if(coor == i-1) {
                            int cand_pari = (val + exist_ru[i+1][coor]) % 2;
                            if(cand_pari != pari) {
                                mul = 0;
                            }
                            else {
                                match++;
                            }
                        }
                        else {
                            if(val != exist_ru[i+1][coor]) mul = 0;
                            else match++;
                        }
                    }
                    else {
                        deg_of_free--;
                    }
                }
                for(auto e : exist_ru[i+1]) {
                    int coor, val; tie(coor, val) = e;
                    if(coor >= i) continue;

                    if(exist_ld[i+1].count(coor)) {
                        if(coor == i-1) {
                            int cand_pari = (val + exist_ld[i+1][coor]) % 2;
                            if(cand_pari != pari) {
                                mul = 0;
                            }
                        }
                        else {
                            if(val != exist_ld[i+1][coor]) mul = 0;
                        }
                    }
                    else {
                        deg_of_free--;
                    }
                }
                deg_of_free -= match;

                // fprintf(stderr, "i = %lld, k = %lld, l = %lld, deg_of_free = %lld\n", i, k, l, deg_of_free);

                (mul *= mod_pow(2, deg_of_free)) %= MOD;
                (dp[i+1][l] += dp[i][k] * mul) %= MOD;
            }
        }
    }
    
    /*
    for(int i=0; i<N; i++) {
        fprintf(stderr, "dp[%lld][0] = %lld, dp[%lld][1] = %lld\n", i, dp[i][0], i, dp[i][1]);
    }
    */
    
    cout << (dp[N-1][0] + dp[N-1][1]) % MOD << endl;
    return 0;
}


Measured memory_bytes: 16640