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 JAVA (judge verdict: Accepted)

import java.util.*;
import static java.util.Arrays.*;
import static java.lang.Math.*;

public class Main {

	static Scanner sc = new Scanner(System.in);
	static int N, M;
	static int[][][] flr = new int[100][100][2];
	static boolean read() {
		N = sc.nextInt();
		if (N == 0) return false;
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < N; j++) {
				flr[i][j][0] = sc.nextInt();
				flr[i][j][1] = sc.nextInt();
			}
		}
		
		return true;
	}

	static int[][] step = new int[100][100];
	static int sol;
	static void solve() {
		sol = 0;
		for (int i = 0; i < N; i++) fill(step[i], -1);
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < N; j++) {
				rec(j, i, i * N + j);
			}
		}
		System.out.println(sol);
	}
	
	static void rec(int x, int y, int s) {
		if (step[y][x] == s) {
			sol++;
		} else if (step[y][x] == -1) {
			step[y][x] = s;
			rec(flr[y][x][0], flr[y][x][1], s);
		}
	}
	
	public static void main(String[] args) {
		while (read())
			solve();
	}
}