Problem:
Score : 800 points

Problem Statement

There is a square grid with N rows and M columns.
Each square contains an integer: 0 or 1. The square at the i-th row from the top and the j-th column from the left contains a_{ij}.

Among the 2^{N+M} possible pairs of a subset A of the rows and a subset B of the columns, find the number of the pairs that satisfy the following condition, modulo 998244353:

The sum of the |A||B| numbers contained in the intersection of the rows belonging to A and the columns belonging to B, is odd.

Constraints

1 \leq N,M \leq 300

0 \leq a_{i,j} \leq 1(1\leq i\leq N,1\leq j\leq M)

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N M
a_{11} ... a_{1M}
:
a_{N1} ... a_{NM}

Output

Print the number of the pairs of a subset of the rows and a subset of the columns that satisfy the condition, modulo 998244353.

Sample Input 1

2 2
0 1
1 0

Sample Output 1

6

For example, if A consists of the first row and B consists of both columns, the sum of the numbers contained in the intersection is 0+1=1.

Sample Input 2

2 3
0 0 0
0 1 0

Sample Output 2

8

Solution in Rust (1.15.1) (judge verdict: Accepted)

const MOD: usize = 998244353;

fn main() {
    let s = std::io::stdin();
    let mut sc = Scanner { stdin: s.lock() };
    let n = sc.read();
    let m = sc.read();
    let a: Vec<Vec<i64>> = (0..n).map(|_| sc.vec(m)).collect();
    let rank = f2_gauss_jordan(a);

    let dim_kernel = n - rank;
    let kernel_size = pow(2, dim_kernel);
    let ans = (pow(2, n) + MOD - kernel_size) % MOD * pow(2, m - 1);
    println!("{}", ans % MOD);
}

fn f2_gauss_jordan(mut a: Vec<Vec<i64>>) -> usize {
    let n = a.len();
    let m = a[0].len();
    let mut rank = 0;
    let mut row = 0;
    for col in 0..m {
        match (row..n).filter(|&i| a[i][col] == 1).next() {
            Some(pivot) => {
                a.swap(row, pivot);
                rank += 1;
                for k in (row + 1)..n {
                    if a[k][col] == 1 {
                        for i in 0..m {
                            a[k][i] ^= a[row][i];
                        }
                    }
                }

                row += 1;
            }
            None => {}
        }

        if row >= n {
            break;
        }
    }
    rank
}

fn pow(mut x: usize, mut e: usize) -> usize {
    let mut result = 1;
    while e > 0 {
        if e & 1 == 1 {
            result *= x;
            result %= MOD;
        }
        e >>= 1;
        x *= x;
        x %= MOD;
    }
    result
}

pub struct Scanner<R> {
    stdin: R,
}

impl<R: std::io::Read> Scanner<R> {
    pub fn read<T: std::str::FromStr>(&mut self) -> T {
        use std::io::Read;
        let buf = self
            .stdin
            .by_ref()
            .bytes()
            .map(|b| b.unwrap())
            .skip_while(|&b| b == b' ' || b == b'\n')
            .take_while(|&b| b != b' ' && b != b'\n')
            .collect::<Vec<_>>();
        unsafe { std::str::from_utf8_unchecked(&buf) }
            .parse()
            .ok()
            .expect("Parse error.")
    }
    pub fn vec<T: std::str::FromStr>(&mut self, n: usize) -> Vec<T> {
        (0..n).map(|_| self.read()).collect()
    }
    pub fn chars(&mut self) -> Vec<char> {
        self.read::<String>().chars().collect()
    }
}