# -*- coding: utf-8 -*- import sys MOD = 998244353 def solve(): input_data = sys.stdin.read().strip().split() it = iter(input_data) N = int(next(it)); M = int(next(it)) A = [[0]*M for _ in range(N)] for i in range(N): for j in range(M): A[i][j] = int(next(it)) first_vals = set(A[i][0] for i in range(N)) ans = 0 for v in first_vals: # P_j: set of p in 0..M-1 such that A[j][p+1] == v (p corresponds to column index p+1) P = [set() for _ in range(N)] for j in range(N): for k in range(M): if A[j][k] == v: P[j].add(k) # k corresponds to p = k (because A[j][k] == v means column k+1) # initial mask: bit j = 1 iff 0 in P_j (i.e. A[j][1] == v) init_mask = 0 for j in range(N): if 0 in P[j]: init_mask |= (1 << j) dp = [0] * (1 << N) dp[init_mask] = 1 # steps i = 1..M for i in range(1, M+1): ndp = [0] * (1 << N) for mask in range(1 << N): ways = dp[mask] if ways == 0: continue # choose any j with mask's bit = 1 for j in range(N): if (mask >> j) & 1: if i < M: # after picking at step i, bit j becomes (i in P_j) newbit = 1 if i in P[j] else 0 newmask = (mask & ~(1 << j)) | (newbit << j) else: # i == M: no update happens after final pick newmask = mask ndp[newmask] = (ndp[newmask] + ways) % MOD dp = ndp ans = (ans + sum(dp)) % MOD print(ans % MOD) if __name__ == "__main__": solve()