#include <iostream>
#include <cstdio>
using namespace std;

const int MaxN = 201;

int move[][2] = { {0, 1}, {-1, 0}, {0, -1}, {1, 0} };

int n, m;
int smer[MaxN][MaxN];
int inv[MaxN][MaxN];

long lvl[MaxN][MaxN];

long marker[MaxN][MaxN];
long markID;


long najdublje(int i, int j)
{
	// markiraj
	lvl[i][j] = -1;

	long najduboko = 0;
	for (int k = 0; k < 4; k++)
	{
		if (inv[i][j] & (1<<k))
			najduboko = max(najduboko, 1 + najdublje(i + move[k][0], j + move[k][1]));
	}
	return najduboko;
}

long ciklus(int i, int j, int dubina)
{
	// markiraj
	lvl[i][j] = dubina;
	marker[i][j] = markID;

	int in = i + move[smer[i][j] - 1][0], jn = j + move[smer[i][j] - 1][1];
	if (lvl[in][jn] == 0)
		return ciklus(in, jn, dubina + 1);
	else if (marker[in][jn] != markID)
		return 0;
	else
		return dubina - lvl[in][jn] + 1;
}

int main()
{
	scanf("%d %d", &n, &m);
	for (int i = 0; i < n; i++)
		for (int j = 0; j < m; j++)
			scanf("%d", &smer[i][j]);

	// obrnuto
	for (int i = 0; i < n; i++)
		for (int j = 0; j < m; j++)
		{
			inv[i][j] = 0;
			if (j < m - 1 && smer[i][j+1] == 3)
				inv[i][j] |= 1;

			if (i > 0 && smer[i-1][j] == 4)
				inv[i][j] |= 2;

			if (j > 0 && smer[i][j-1] == 1)
				inv[i][j] |= 4;

			if (i < n - 1 && smer[i+1][j] == 2)
				inv[i][j] |= 8;
		}


	memset(lvl, 0, sizeof(lvl));
	long longestPath = 0;

	// drvece
	for (int i = 0; i < n; i++)
		for (int j = 0; j < m; j++)
		{
			// koren drveta
			if (smer[i][j] == 0)
			{
				long deep = najdublje(i, j);
				longestPath += deep;
			}
		}

	// ciklusi
	memset(marker, 0, sizeof(marker));
	markID = 1;
	for (int i = 0; i < n; i++)
		for (int j = 0; j < m; j++)
		{
			// nije markiran, trazimo ciklus
			if (lvl[i][j] == 0 && smer[i][j] != 0)
			{
				long cycle = ciklus(i, j, 0);
				longestPath += cycle;
				markID++;
			}
		}

	printf("%ld\n", longestPath);
	return 0;
}
