Problem:
Problem B: Let's JUMPSTYLE

Description

踊りの好きなFは，とあるダンスホールでJUMPSTYLEと呼ばれるハードコアな踊りの練習をすることにした．

フロアはN×Nの格子状にタイルが敷き詰められている．
踊りの練習をサポートするため，各タイルには次のステップに飛び移るべきタイルの座標が書かれている．Fは日々の練習によって強靭な運動神経を持っており，フロア内の任意のタイルへ飛び移ることができる．

Fは，十分に長い時間この踊りを続けていけば，いつか定常状態に入り，同じルートをただループする状態になることに気付いた．Fはこのようなループがこのフロアにいくつ存在するのか疑問に思い，プログラマであるあなたに相談することにした．

Input

入力は複数のテストケースから成る．

各テストケースはフロアの1辺の長さNを含む1行で始まる．(1 ≦ N ≦ 100)

続くN行は，フロアの各タイルに書いてあるジャンプ先の座標を以下のように表している．

は，それぞれ座標(i, j)にあるタイルに書いてあるジャンプ先のx座標およびy座標を表す．座標は0-originであり，すべての座標の値は0以上N未満の整数である．

入力は0のみから成る行で終わる．

Output

各テストケースに対し，異なるループの個数を1行で出力する．

Sample Input

1
0 0
2
1 1 0 1
1 0 0 0
2
1 1 0 1
1 1 1 0
3
0 1 2 2 2 1
0 2 1 2 2 1
0 0 0 1 1 1
4
3 2 2 0 3 2 2 1
1 1 0 3 1 1 3 1
0 3 2 3 3 0 2 3
1 1 1 1 3 2 1 3
0

Output for Sample Input

1
2
1
2
3

Solution in Haskell (judge verdict: Accepted)

import Control.Applicative
import Control.Monad
import Data.List
import Data.Vector.Unboxed (Vector, (!), (//))
import qualified Data.Vector.Unboxed as V

main :: IO ()
main = do
  n <- readLn
  unless (n == 0) $ do
    solve n <$> replicateM n f >>= print
    main
  where
    f = map read <$> words <$> getLine

solve :: Int -> [[Int]] -> Int
solve n xs = let tm = V.fromList . concat $ map f xs
                 cm = V.replicate (n * n) (-1) :: Vector Int
             in fst $ foldl' (g tm []) (0, cm) [0 .. n*n-1]
  where
    f (x:y:rs) = n * y + x : f rs
    f [] = []
    g tm ac (c, m) i
      | m ! i == (-1) = g tm (i:ac) (c, m // [(i, c)]) (tm ! i)
      | m ! i == c = (c + 1, m)
      | otherwise = (c, m // (map (\j -> (j, m ! i)) ac))