Problem:
Problem B: Cubes Without Holes

There is a cube which consists of n × n × n small cubes. Small cubes have marks on their surfaces. An example where n = 4 is shown in the following figure.

Then,
次に、上図（右）に示すように、印のついた表面から、反対の面まで水平または垂直に貫通する穴をあける。

あなたの仕事は、n と 印の位置を読み込み、穴の空いていない小さい立方体の個数を数えるプログラムを作成することである。

Input

入力はいくつかのデータセットからなる。各データセットは以下の形式で与えられる：

n h
c1 a1 b1
c2 a2 b2
.
.
.
ch ah bh

h は印の数を示す整数である。これに続く h 行によって h 個の印の位置が入力される。印の位置を指定するために下図に示す座標軸を用いることにする。(x, y, z) = (1, 1, 1) が左下奥の立方体、(x, y, z) = (n, n, n) が右上手前の立方体を示す。

ci は i 番目の印がつけられている平面を示す文字列である。ci は "xy" 、"xz"、 "yz"　のいづれかであり、それぞれ i 番目の印が xy 平面、xz 平面、 yz 平面上にあることを示す。

ai, bi　は　ci で示された平面上の座標を示す。 xy 平面、xz 平面、yz 平面のとき、ai, bi はそれぞれ平面の座標 (x, y)、(x, z)、(y, z) を示す。例えば、上図において、印 A, B, C の ci, ai, bi の値はそれぞれ、"xy 4 4", "xz 1 2", "yz 2 3" となる。

n, h がともに 0 のとき、入力の終わりを示す。

n ≤ 500, h ≤ 200 と仮定してよい。

Output

各データセットに対して、穴の空いていない立方体の数を１行に出力せよ。

Sample Input

4 3
xy 4 4
xz 1 2
yz 2 3
4 5
xy 1 1
xy 3 3
xz 3 3
yz 2 1
yz 3 3
0 0

Output for the Sample Input

52
46

Solution in Haskell (judge verdict: Accepted)

import Control.Applicative
import Control.Monad
import Control.Monad.ST
-- import qualified Data.ByteString as BS
import Data.Functor
import Data.Function
import Data.Monoid
import Data.Maybe
import Data.List
import qualified Data.Foldable as Foldable
--import qualified Data.Set as Set
--import qualified Data.Sequence as Sequence
import Data.List.Split
import Data.Bits
import Data.Char
import Data.Ix
import Data.Ratio
import Data.Ord
import Data.Fixed
import Data.Tuple
import Data.Array
--import Data.Array.Unboxed
--import Data.Array.IArray
import Data.Array.MArray
import Data.Array.IO
import Data.Array.ST
import Data.IORef
import Data.STRef
import Text.Printf
import System.IO
-- import System.IO.Unsafe
 
-- templete
readInt = read :: String -> Int
readInteger = read :: String -> Integer
readDouble = read :: String -> Double
getInt = readLn :: IO Int
getInts = map readInt . words <$> getLine
getInteger = readLn :: IO Integer
getIntegers = map readInteger . words <$> getLine
getDouble = readLn :: IO Double
getDoubles = map readDouble . words <$> getLine
sjoin :: (Show a) => [a] -> String
sjoin = unwords . map show
tjoin :: (Show a, Show b) => (a, b) -> String
tjoin (x, y) = show x ++ (' ' : show y)
cond :: a -> a -> Bool -> a
cond t f c = if c then t else f
apply2 :: (a -> a -> b) -> [a] -> b
apply2 f [x,y] = f x y
apply3 :: (a -> a -> a -> b) -> [a] -> b
apply3 f [x,y,z] = f x y z
apply4 :: (a -> a -> a -> a -> b) -> [a] -> b
apply4 f [x,y,z,w] = f x y z w
fnTuple :: (a -> b, a -> c) -> a -> (b, c)
fnTuple (f,g) a = (f a, g a)
replace :: (Eq a) => a -> a -> [a] -> [a]
replace x y = map (\z -> if z==x then y else z)
binMap :: (a -> a -> b) -> [a] -> [b]
binMap f (x:xs@(y:_)) = f x y : binMap f xs
binMap _ _ = []
splitRec :: Int -> [a] -> [[a]]
splitRec _ [] = []
splitRec n xs = let (y,ys) = splitAt n xs in y : splitRec n ys
infixl 7 `divCeil`
divCeil :: Integral a => a -> a -> a
x `divCeil` y = (x+y-1) `div` y
coverC :: Ord a => (a, a) -> a -> Bool
coverC (l,r) x = l<=x && x<=r
coverH :: Ord a => (a, a) -> a -> Bool
coverH (l,r) x = l<=x && x<r
ibsearch :: (Int -> Bool) -> (Int,Int) -> Int
ibsearch f (ok,ng) = if abs (ok-ng) <= 1 then ok else let mid = (ok + ng) `div` 2 in ibsearch f (if f mid then (mid,ng) else (ok,mid))
whenM :: Monad m => m Bool -> m () -> m ()
whenM c a = c >>= flip when a
unconsU :: [a] -> (a, [a])
unconsU (x:xs) = (x, xs)
-- templete

ana [dir, a, b] = (dir', (readInt a, readInt b))
  where
    dir' = case dir of
        "xy" -> 0
        "xz" -> 1
        "yz" -> 2

main = do
    [n,h] <- getInts
    unless (n==0 && h==0) $ do
        ds <- map (ana. words) <$> replicateM h getLine
        let ((yz,xz),xy) = fmap (map snd) . swap . fmap (fmap (map snd) . swap . fmap (map snd) . partition ((==1) . fst)) $ partition ((==0) . fst) ds
        let xy_xz = [(y,z) | (x,y) <- xy, (x',z) <- xz, x==x']
        let xy_yz = [(x,z) | (x,y) <- xy, (y',z) <- yz, y==y']
        let xz_yz = [(x,y) | (x,z) <- xz, (y,z') <- yz, z==z']
        let xy_xz_yz = [() | p <- xy_xz, q <- yz, p==q]
        print $ n^3 - n * (length xy + length xz + length yz) + (length xy_xz + length xy_yz + length xz_yz) - length xy_xz_yz
        main