#include <bits/stdc++.h>
// iostream is too mainstream
#include <cstdio>
// bitch please
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <cmath>
#include <iomanip>
#include <time.h>
#define dibs reserve
#define OVER9000 1234567890
#define ALL_THE(CAKE,LIE) for(auto LIE =CAKE.begin(); LIE != CAKE.end(); LIE++)
#define tisic 47
#define soclose 1e-8
#define chocolate win
// so much chocolate
#define patkan 9
#define ff first
#define ss second
#define abs(x) (((x) < 0)?-(x):(x))
#define uint unsigned int
#define dbl long double
#define pi 3.14159265358979323846
using namespace std;
// mylittledoge

using cat = long long;

#ifdef DONLINE_JUDGE
	// palindromic tree is better than splay tree!
	#define lld I64d
#endif

cat pw(cat a, cat e, cat mod) {
	if(e <= 0) return 1;
	cat x = pw(a, e/2, mod);
	x = x * x % mod;
	if(e&1) x = x * a % mod;
	return x;
}

int main() {
	cin.sync_with_stdio(0);
	cin.tie(0);
	cout << fixed << setprecision(10);
	int N, M;
	cin >> N >> M;
	map< pair<int, int>, int> A;
	for(int i = 0; i < N; i++) A[{i, i}] = -1;
	for(int i = 1; i < N; i++) A[{i-1, i}] = A[{i, i-1}] = -1;
	for(int i = 1; i < N-1; i++) A[{i-1, i+1}] = A[{i+1, i-1}] = -1;
	for(int i = 0; i < M; i++) {
		int x, y, z;
		cin >> x >> y >> z;
		A[{x-1, y-1}] = z;
	}
	set< pair<int, int> > S;
	ALL_THE(A, it) {
		auto jt = A.find({it->ff.ss, it->ff.ff});
		if(abs(it->ff.ss-it->ff.ff) >= 3) S.insert({min(it->ff.ff, it->ff.ss), max(it->ff.ff, it->ff.ss)});
		if(jt != end(A) && abs(it->ff.ss-it->ff.ff) >= 3 && it->ss != -1 && jt->ss != it->ss && jt->ss != -1) {
			cout << "0\n";
			return 0;
		}
	}
	cat free = (N <= 3) ? 0 : (1LL*(N-3)*(N-2)/2-S.size());
	vector<int> pd[2] = {vector<int>(N-1, 0), vector<int>(N-1, 0)};
	for(int i = 0; i < N-1; i++) {
		int x = A[{i, i+1}], y = A[{i+1, i}];
		if(x != -1 && y != -1) pd[x^y][i] = 1;
		else if(x == -1 && y == -1) pd[0][i] = pd[1][i] = 2;
		else pd[0][i] = pd[1][i] = 1;
	}
	vector<int> pdd[2] = {vector<int>(N, 0), vector<int>(N, 0)};
	pdd[0][0] = pdd[1][0] = 1;
	pdd[0][N-1] = pdd[1][N-1] = 1;
	for(int i = 1; i < N-1; i++) {
		int x = A[{i-1, i+1}], y = A[{i+1, i-1}];
		if(x != -1 && y != -1) pdd[x^y][i] = 1;
		else if(x == -1 && y == -1) pdd[0][i] = pdd[1][i] = 2;
		else pdd[0][i] = pdd[1][i] = 1;
	}	
	cat mod = 998244353;
	vector<cat> dp[2] = {vector<cat>(N, 0), vector<cat>(N, 0)};
	if(A[{0, 0}] == -1) dp[0][0] = dp[1][0] = 1;
	else dp[A[{0, 0}]][0] = 1;
	for(int i = 1; i < N; i++) for(int j = 0; j < 2; j++) for(int k = 0; k < 2; k++) {
		auto it = A.find({i, i});
		if(it != end(A) && it->ss != k && it->ss != -1) continue;
		dp[k][i] = (dp[k][i] + pd[j^k][i-1] * pdd[k][i] * dp[j][i-1]) % mod;
	}
	cat ans = (dp[0][N-1] + dp[1][N-1]) % mod;
	ans = ans * pw(2, free, mod) % mod;
	if(ans < 0) ans += mod;
	cout << ans << "\n";
	return 0;
}

// look at my code
// my code is amazing
