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 C# (Mono 4.6.2.0) (judge verdict: Wrong Answer)

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Threading.Tasks;
using static System.Console;
using static System.Math;
class Z { static void Main() => new K(); }
class K
{
    int F => int.Parse(Str);
    long FL => long.Parse(Str);
    int[] G => Strs.Select(int.Parse).ToArray();
    long[] GL => Strs.Select(long.Parse).ToArray();
    string Str => ReadLine();
    string[] Strs => Str.Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
    const int MOD = 998244353;
    public K()
    {
        SetOut(new StreamWriter(OpenStandardOutput()) { AutoFlush = false });
        WriteLine(Solve());
        Out.Flush();
    }
    Random rand = new Random();
    long Solve()
    {
        var I = G;
        int Y = I[0], X = I[1];
        var mat = new bool[Y][];
        for (var y = 0; y < Y; y++)
        {
            mat[y] = new bool[X];
            // I = G;
            // for (var x = 0; x < X; x++) mat[y][x] = I[x] != 0;
            for (var x = 0; x < X; x++) mat[y][x] = rand.Next(6) == 0;
        }
        var r = 0;
        for (var c = 0; c < X; c++)
        {
            int y = r;
            while (y < Y && !mat[y][c]) y++;
            if (y == Y) continue;
            if (y != r) AddTo(mat[r], mat[y]);
            for (y = r + 1; y < Y; y++) if (mat[y][c]) AddTo(mat[y], mat[r]);
            r++;
        }
        WriteLine($"rank = {r}");
        foreach (var m in mat) Print(m);
        return (Pow(2, X + Y - 1, MOD) - Pow(2, X + Y - r - 1, MOD) + MOD) % MOD;
    }
    void Print(bool[] a) => WriteLine(string.Join("", a.Select(b => b ? 1 : 0)));
    public static long Pow(long a, long b, long mod)
    {
        var p = 1L;
        var x = a;
        while (b > 0)
        {
            if ((b & 1) == 1) p = (p * x) % mod;
            b >>= 1;
            x = (x * x) % mod;
        }
        return p;
    }
    // a += b
    void AddTo(bool[] a, bool[] b)
    {
        var n = a.Length;
        for (var i = 0; i < n; i++) a[i] = a[i] ^ b[i];
    }
}