{-# LANGUAGE RankNTypes #-}

import           Data.Array.MArray (MArray)
import qualified Data.Array.MArray as M
    ( freeze
    , getAssocs
    , getElems
    , newArray
    , newListArray
    , readArray
    , writeArray
    )

import Data.Array.ST (STArray, STUArray)

import Control.Applicative
import Control.Monad
import Control.Monad.ST    (ST, runST)

main :: IO ()
main = do
    [n, m] <- fmap read . words <$> getLine
    answer $ solve n m

type Answer = Int
answer :: Answer -> IO ()
answer = print

theMod = 998244353

solve :: Int -> Int -> Answer
solve n m = inner 1 1 1 (M.newArray (1, n) 1)
  where
    inner :: Int -> Int -> Int -> (forall s. ST s (STUArray s Int Int)) -> Answer
    inner k c d ds
      | k >= m    = last $ d : runST (M.getElems =<< ds)
      | otherwise = inner (succ k) d d' ds'
      where
        ds' = do
          arr <- ds
          foldM `flip` d' `flip` [2 .. n] $ \a i -> do
              x <- (a +) <$> M.readArray arr i
              M.writeArray arr i x
              return x
          return arr
        d'
          | k == 1    = 1
          | otherwise = c + d

x +/ y = until (theMod >) (`mod` theMod) $ x + y
