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 Haskell (GHC 7.10.3) (judge verdict: Accepted)

{-# LANGUAGE
  ScopedTypeVariables, BangPatterns, TupleSections, ExplicitForAll,
  LambdaCase, MultiWayIf, Unsafe, RecordWildCards, FlexibleContexts, CPP,
  NoMonomorphismRestriction, GADTs,
  RankNTypes, EmptyDataDecls, EmptyCase, ViewPatterns #-}

import Data.Bits
import Data.List
import qualified Data.ByteString.Char8 as BS
import qualified Data.ByteString.Lazy.Char8 as BSL
import Data.IntMap.Strict (IntMap)
import qualified Data.IntMap.Strict as IMS
import qualified Data.IntMap.Lazy as IML
import Data.IntSet (IntSet)
import qualified Data.IntSet as IS
import qualified Data.Sequence as Seq
import Data.Sequence (Seq)
import qualified Data.Array.IArray as A
import qualified Data.Array.MArray.Safe as A
import qualified Data.Array.MArray as A
import Data.Array (Array)
import Data.Array.Unboxed (UArray)
import Data.Array.IArray (IArray)
import Data.Array.MArray.Safe (MArray)
import Data.Array.IO.Safe (IOArray, IOUArray)
import Data.Array.ST.Safe (STArray, STUArray, runSTArray, runSTUArray)
import qualified Data.Vector as V
import qualified Data.Vector.Unboxed as VU
import qualified Data.Vector.Unboxed.Mutable as VUM
import Control.Monad
import Control.Monad.ST
-- import Control.Monad.ST.Safe
import Control.Applicative
import Data.Maybe
import Data.Tuple
import Data.Ord
import Control.Monad.State.Strict
import Data.Int
import Data.Word
import System.IO
import Data.Function
import Control.Monad.Primitive
import qualified Data.Vector.Primitive.Mutable as VPM
import qualified Data.Vector.Generic.Mutable as VGM
import Data.STRef
import Data.IORef
import Control.DeepSeq
import Numeric.Natural

main :: IO ()
main = do
  [n,m] <- map readInt . words <$> getLine
  a <- V.unfoldrN n (runStateT
                      $ foldM
                         (\ !acc _ -> (shiftL acc 1 .|.).fromIntegral <$> rInt)
                         0 [1..m]) <$> BSL.getContents
  let rank = countRank n m a
  print $ fromMon $ 2^(n+m-1) - 2^(n+m-rank-1)
      

{-# INLINE countRank #-}
countRank :: Int -> Int -> V.Vector Natural -> Int
countRank n m = (\(acc,_,_) -> acc) .
                  until (\(!acc,!j,!vec) -> j < 0) go
                  . (0,m-1,) . V.filter (/=0)
  where
    go (!acc,!j,!vec) = case V.find (`testBit` j) vec of
      Nothing -> (acc, j-1, vec)
      Just row ->
        (acc+1, j-1,
         V.filter (/=0)
          $ V.map (\ !row1 -> if testBit row1 j then xor row1 row else row1)
          $ vec)
              
            
  

{-# INLINE modulus #-}
modulus :: (Integral i) => i
modulus = 998244353

{-# INLINE nprime #-}
nprime :: Word64
nprime = 998244351

{-# INLINE rsq #-}
rsq :: Word64
rsq = 932051910

newtype Montgomery = Mon {unMon :: Word32}
  deriving (Eq, Show)

instance Num Montgomery where
  {-# INLINE (+) #-}
  (+) = monAdd
  {-# INLINE (*) #-}
  (*) = monMult
  {-# INLINE (-) #-}
  (-) = monSub
  {-# INLINE negate #-}
  negate (Mon x) = Mon (modulus - x)
  {-# INLINE fromInteger #-}
  fromInteger = monRep . fromInteger
  {-# INLINE signum #-}
  signum x | x == Mon 0 = Mon 0
           | otherwise  = monRep 1
  {-# INLINE abs #-}
  abs = id

{-# INLINE monMult #-}
monMult :: Montgomery -> Montgomery -> Montgomery
monMult (Mon x) (Mon y) = Mon $ monRed $ fromIntegral x * fromIntegral y

{-# INLINE monAdd #-}
monAdd :: Montgomery -> Montgomery -> Montgomery
monAdd (Mon x) (Mon y) = Mon $ x+y + if x >= modulus-y then modulus else 0
    
{-# INLINE monSub #-}
monSub :: Montgomery -> Montgomery -> Montgomery
monSub (Mon x) (Mon y) = Mon $ x-y + if x < y then modulus else 0

{-# INLINE monRep #-}
monRep :: Word32 -> Montgomery
monRep x = Mon $ monRed $ rsq * fromIntegral x

{-# INLINE fromMon #-}
fromMon :: Montgomery -> Word32
fromMon (Mon x) = monRed $ fromIntegral x

{-# INLINE monRed #-}
monRed :: Word64 -> Word32
monRed x = t - if t >= modulus then modulus else 0
  where t = fromIntegral $ (`shiftR` 32) $ x + x*nprime .&.mask32 *modulus

mask32 :: Word64
mask32 = bit 32 - 1


rInt :: StateT BSL.ByteString Maybe Int
rInt = StateT $ BSL.readInt . BSL.dropWhile (<'!')

#define D(f,r,d) f::Integral a=>a->d;f=fromIntegral;r::String->d;r=read
#define C(f,r,g,h,d) D(f,r,d);g,h::RealFrac a=>a->d;g=floor;h=ceiling
C(_toInteger_,readInteger,floorInteger,ceilInteger,Integer)
C(toInt,readInt,floorInt,ceilInt,Int)
C(toI8,readI8,floorI8,ceilI8,Int8)
C(toI16,readI16,floorI16,ceilI16,Int16)
C(toI32,readI32,floorI32,ceilI32,Int32)
C(toI64,readI64,floorI64,ceilI64,Int64)
C(toWord,readWord,floorWord,ceilWord,Word)
C(toW8,readW8,floorW8,ceilW8,Word8)
C(toW16,readW16,floorW16,ceilW16,Word16)
C(toW32,readW32,floorW32,ceilW32,Word32)
C(toW64,readW64,floorW64,ceilW64,Word64)
D(toDouble,readDouble,Double)
D(toFloat,readFloat,Float)
#undef D
#undef C


#define N(f,g,a,m)\
  f :: forall e i s. (C(a,m)A.Ix i) => (i,i) -> e -> m (a i e); f=A.newArray;\
  g :: forall e i s. (C(a,m)A.Ix i) => (i,i) -> m (a i e); g=A.newArray_
#define C(a,m)
N(newIOA,newIOA_,IOArray,IO)
N(newSTA,newSTA_,STArray s,ST s)
#undef C
#define C(a,m) MArray (a) e (m), 
N(newIOUA,newIOUA_,IOUArray,IO)
N(newSTUA,newSTUA_,STUArray s,ST s)
#undef C
#undef N