#include #include #include #include using namespace std; using mint = atcoder::modint998244353; using ll = long long; int main() { ll N, Q; cin >> N >> Q; vector> G(N); atcoder::dsu uf(N); for (ll i = 0; i < Q; i++) { ll t, a, b; cin >> t >> a >> b; if (t == 0) { uf.merge(a - 1, b - 1); } else { G[a - 1].push_back(b - 1); G[b - 1].push_back(a - 1); } } // cerr << "#" << endl; auto g = uf.groups(); const ll M = g.size(); vector leaders(M); for (ll i = 0; i < M; i++) { leaders[i] = uf.leader(g[i][0]); } sort(leaders.begin(), leaders.end()); vector> G2(M); atcoder::dsu uf2(M); for (ll i = 0; i < M; i++) { for (int j : g[i]) { for (ll to : G[j]) { ll x = uf.leader(j); ll y = uf.leader(to); if (x == y) { cout << "0\n"; return 0; } ll xx = lower_bound(leaders.begin(), leaders.end(), x) - leaders.begin(); ll yy = lower_bound(leaders.begin(), leaders.end(), y) - leaders.begin(); G2[xx].push_back(yy); G2[yy].push_back(xx); uf2.merge(xx, yy); } } } // cerr << "#" << endl; mint ans = 1; vector color(N, -1); for (ll i = 0; i < M; i++) { if (uf2.leader(i) == i) { deque dq; dq.push_back(i); color[i] = 0; while (!dq.empty()) { ll q = dq.front(); dq.pop_front(); for (ll to : G2[q]) { if (color[to] == -1) { color[to] = 1 - color[q]; dq.push_back(to); } else if (color[to] != 1 - color[q]) { cout << "0\n"; return 0; } } } ans *= 2; } } cout << ans.val() << "\n"; }