from sys import stdin input = stdin.readline class WeightedUnionFind: def __init__(self, n): self.par = [i for i in range(n)] self.rank = [0] * n self.weight = [0] * n self.h1 = [] self.h2 = [] self.h3 = [] def leader(self, x): if self.par[x] == x: return x else: y = self.leader(self.par[x]) self.weight[x] ^= self.weight[self.par[x]] self.h3.append(x) self.par[x] = y self.h1.append(x) return y def merge(self, x, y, w): rx = self.leader(x) ry = self.leader(y) if self.rank[rx] < self.rank[ry]: self.par[rx] = ry self.h1.append(rx) self.weight[rx] = w ^ self.weight[x] ^ self.weight[y] self.h3.append(rx) else: self.par[ry] = rx self.h1.append(ry) self.weight[ry] = w ^ self.weight[y] ^ self.weight[x] self.h3.append(ry) if self.rank[rx] == self.rank[ry]: self.rank[rx] += 1 self.h2.append(rx) def same(self, x, y): return self.leader(x) == self.leader(y) def diff(self, x, y): return self.weight[x] ^ self.weight[y] def reset(self): while self.h1: n = self.h1.pop() self.par[n] = n while self.h2: n = self.h2.pop() self.rank[n] = 0 while self.h3: n = self.h3.pop() self.weight[n] = 0 MOD = 998244353 N, Q = map(int, input().split()) query = [list(map(int, input().split())) for _ in range(Q)] UF = WeightedUnionFind(N) ans = pow(2, N, MOD) inv = pow(2, -1, MOD) NG = False for q in query: if q[0] != 3 and q[1] == q[2]: if q[0] == 2: NG = True print(ans if not NG else 0) continue if q[0] == 1: u, v = q[1:] u, v = u-1, v-1 if UF.same(u, v) and UF.diff(u, v) == 1: NG = True if not UF.same(u, v): UF.merge(u, v, 0) ans *= inv ans %= MOD elif q[0] == 2: u, v = q[1:] u, v = u-1, v-1 if UF.same(u, v) and UF.diff(u, v) == 0: NG = True if not UF.same(u, v): UF.merge(u, v, 1) ans *= inv ans %= MOD else: UF.reset() ans = pow(2, N, MOD) NG = False print(ans if not NG else 0)