import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Scanner;


class Cell {
	int y, x;

	public Cell(int y, int x) {
		this.y = y;
		this.x = x;
	}
}


public class Robotici {
	static final int[] dy = new int[] {0, 0, -1, 0, 1};
	static final int[] dx = new int[] {0, 1, 0, -1, 0};
	String fileIn, fileOut;
	
	int ny, nx;
	int[][] dir;
	int[][] color;
	int[][] rank;
	int maxDancers;


	Cell paint(int startY, int startX, int colorOld, int colorNew) {
		int l = 0;
		int y = startY;
		int x = startX;
		
		while (dir[y][x] != 0 && color[y][x] == colorOld) {
			color[y][x] = colorNew;
			l++;
			int d = dir[y][x];
			y += dy[d];
			x += dx[d];
		}
		
		int r = l + rank[y][x];
		y = startY;
		x = startX;
		
		for (int i = 0; i < l; i++) {
			rank[y][x] = r--;
			int d = dir[y][x];
			y += dy[d];
			x += dx[d];
		}
			
		return new Cell(y, x);
	}

	
	void solve() {
		color = new int[ny][nx];
		rank = new int[ny][nx];
		
		int currentColor = 1;
		for (int y = 0; y < ny; y++)
			for (int x = 0; x < nx; x++)
				if (dir[y][x] != 0 && color[y][x] == 0) {
					Cell front = paint(y, x, 0, currentColor);
					int c = color[front.y][front.x];
					
					if (c == 0)                                        // 1) naisli smo na slobodno polje 
						color[front.y][front.x] = currentColor;
					else                                              
						if (c == currentColor)  {                      // 2) napravili smo petlju, rep blokira
							paint(front.y, front.x, currentColor, -1);
							paint(y, x, currentColor, -2);
						} else {
							if (c < 0)                                 // 3) udarili smo u petlju ili blokirani lanac, blokiramo
								paint(y, x, currentColor, -2);
							else                                       // 4) pridruzujemo se postojecem lancu koji ne blokira
								paint(y, x, currentColor, c);
						}
					
					currentColor++;
				}

		maxDancers = 0;
		
		int[] maxColorRank = new int[currentColor];
		for (int y = 0; y < ny; y++)
			for (int x = 0; x < nx; x++) {
				int c = color[y][x];
				if (c == -1)
					maxDancers++;                                      // u petlji se svi krecu
				if (c > 0)
					if (rank[y][x] > maxColorRank[c])                  // u ostalim grupama samo najduzi lanac 
						maxColorRank[c] = rank[y][x];
			}
		
		for (int maxRank : maxColorRank)
			maxDancers += maxRank;
	}

	
	void readInput() throws FileNotFoundException {
		Scanner in = new Scanner(new File(fileIn));
		
		ny = in.nextInt();
		nx = in.nextInt();
		dir = new int[ny][nx];
		for (int y = 0; y < ny; y++)
			for (int x = 0; x < nx; x++)
				dir[y][x] = in.nextInt();
		
		in.close();
	}
	

	void writeOutput() throws IOException {
		PrintWriter out = new PrintWriter(fileOut);
		out.print(maxDancers);
		out.close();
	}
	
	
	public Robotici(String fileIn, String fileOut) {
		this.fileIn = fileIn;
		this.fileOut = fileOut;
		
		try {
			readInput();
			solve();
			writeOutput();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	

	public static void main(String[] args) {
		new Robotici("robotici.in", "robotici.out");
	}
}
