#include <iostream>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <bitset>
#include <algorithm>
#include <cstdio>

#define X first
#define Y second
using namespace std;

struct UnionFindTree{
	UnionFindTree():pos(pair<int, int>(-1, -1)), root(NULL){}
	pair<int, int> pos;
	UnionFindTree *root;
};

void dfs(int x, int y, int &count, vector<vector<UnionFindTree> > &pos){
	if(pos[pos[y][x].pos.Y][pos[y][x].pos.X].root==NULL){
		if(pos[y][x].root==NULL) pos[pos[y][x].pos.Y][pos[y][x].pos.X].root = &pos[y][x];
		else pos[pos[y][x].pos.Y][pos[y][x].pos.X].root = pos[y][x].root;
		dfs(pos[y][x].pos.X, pos[y][x].pos.Y, count, pos);
	}
	else if(pos[y][x].root == pos[pos[y][x].pos.Y][pos[y][x].pos.X].root){
		count++;
	}
	pos[y][x].root = pos[pos[y][x].pos.Y][pos[y][x].pos.X].root;
	return;
}

int main(){
	int n = 0;
	while(cin >> n && n != 0){
		vector<vector<UnionFindTree> > pos(n, vector<UnionFindTree>(n, UnionFindTree()));
		for(int i = 0; i < n; i++){
			for(int j = 0; j < n; j++){
				cin >> pos[i][j].pos.X >> pos[i][j].pos.Y;
			}
		}
		int count = 0;
		for(int i = 0; i < n; i++){
			for(int j = 0; j < n; j++){
				if(pos[i][j].root != NULL) continue;
				dfs(j, i, count, pos);
			}
		}
		cout << count << endl;
	}
	return 0;
}