#include <iostream>
#include <queue>
using namespace std;
const int N = 1000010;
typedef pair<int, int> PII;
int g[N];
int n, m;
PII q[N]; //使用数组来模拟队列
// void dfs(int x, int y) {
// int dx[8] = {-1, -1, -1, 0, 1, 1, 1, 0}, dy[8] = {-1, 0, 1, 1, 1, 0, -1, -1};
// g[m * x + y] = 0;
// for (int i = 0; i < 8; i ++) {
// int a = x + dx[i], b = y + dy[i];
// if (a >= 0 && a < n && b >= 0 && b < m && g[a * m + b]) {
// dfs(a, b);
// }
// }
// }
void dfs(int x, int y) {
g[m * x + y] = 0;
for (int i = -1; i <= 1; i ++) {
for (int j = -1; j <= 1; j ++) {
int a = x + i, b = y + j;
if (a >= 0 && a < n && b >= 0 && b < m && g[a * m + b]) {
dfs(a, b);
}
}
}
}
//此时来完成宽搜优先遍历
void bfs01(int x, int y) {
queue<PII> q;
q.push({x, y});
g[x * m + y] = 0;
while (q.size()) {
auto t = q.front();
q.pop();
int x = t.first, y = t.second;
for (int i = -1; i <= 1; i ++) {
for (int j = -1; j <= 1; j ++) {
int a = x + i, b = y + j;
if (a >= 0 && a < n && b >= 0 && b < m && g[a * m + b]) {
g[a * m + b] = 0;
q.push({a, b});
}
}
}
}
}
void bfs(int x, int y) {
int hh = 0, tt = 0;
q[0] = {x, y};
g[m * x + y] = 0;
while (hh <= tt ) {
PII t = q[hh ++];
int x = t.first, y = t.second;
for (int i = -1; i <= 1; i ++) {
for (int j = -1; j <= 1; j ++) {
int a = x + i, b = y + j;
if (a >= 0 && a < n && b >= 0 && b < m && g[m * a + b]) {
g[m * a + b] = 0;
q[++ tt] = {a, b};
}
}
}
}
}
int main() {
scanf("%d%d", &n, &m);
for(int i = 0, k = 0; i < n; i ++) {
for (int j = 0; j < m; j ++, k ++) {
scanf("%d", &g[k]);
}
}
//从前往后来遍历每一个点
int res = 0;
for (int i = 0; i < n; i ++) {
for (int j = 0; j < m; j ++) {
if (g[i * m + j]) {
res ++;
bfs(i, j);
}
}
}
printf("%d\n", res);
return 0;
}