using System;
using System.Runtime.CompilerServices;
// n が縦の長さで、インデックスは i を割り当ててる
// m が横の長さで、インデックスは j を割り当ててる
namespace Island {
static class Program {
static void Main ( ) {
Read.InitNum(out int n, out int m); // 初期化数の読み込み
int[,] map = new int[n, m]; // 初期化
Read.Island(map, n, m); // map データの読み込み
int count = Search.Bigin(map, n, m); // 走査して、島の数を格納
Console.WriteLine(count); // 表示
}
}
// 読み込みメソッドをまとめたクラス
static class Read {
public static void InitNum ( out int n, out int m ) {
string[] strs = Console.ReadLine().Split();
m = int.Parse(strs[0]);
n = int.Parse(strs[1]);
}
public static void Island ( int[,] map, int n, int m ) {
for ( int i = 0; i < n; i++ ) {
string[] strs = Console.ReadLine().Split();
for ( int j = 0; j < m; j++ ) {
map[i, j] = int.Parse(strs[j]);
}
}
}
}
// 走査とカウントに必要なメソッドをまとめたクラス
static class Search {
public static int Bigin ( int[,] map, int n, int m ) {
// 島コード:陸地がない場合は 0 、陸地がある場合は 1 で map が読み込まれているので
// 2, 3, 4, 5 と分類コードを振り分けていく
int code = 2;
// map 全体を走査して map[i, j] が未分類コード 1 の時だけ
// 再帰的に連続する陸地を同じ分類コードに塗っていく
for ( int i = 0; i < n; i++ ) {
for ( int j = 0; j < m; j++ ) {
if ( map[i, j] == 1 ) {
Recursive(code, map, i, j, n, m);
code++;
}
}
}
// 最後の分類コードから初期値 2 を引いた数が島の数になる
return code - 2;
}
// 上下左右でメソッドを分けて効率化を図るか
// このままにしてすっきりしたコードを保つか
private static void Recursive ( int code, int[,] map, int i, int j, int n, int m ) {
if ( i >= 0 && j >= 0 && i < n && j < m && map[i, j] == 1 ) {
map[i, j] = code;
Recursive(code, map, i + 1, j, n, m ); // 下
Recursive(code, map, i - 1, j, n, m ); // 上
Recursive(code, map, i, j + 1, n, m ); // 右
Recursive(code, map, i, j - 1, n, m ); // 左
}
}
}
}