Go: // AOJ 1160: How Many Islands? http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1160

package main

import (
	"bufio"
	"container/list"
	"fmt"
	"os"
	"strconv"
)

var SEA = 0
var LAND = 1

func nextInt(sc *bufio.Scanner) int {
	sc.Scan()
	v, _ := strconv.Atoi(sc.Text())
	return v
}

func discoverIslands(M, V [][]int, H, W int) int {
	// 島を探す
	queue := list.New()
	islands := 0
	for i := 1; i <= H; i++ {
		for j := 1; j <= W; j++ {
			// 訪問済みの土地ならスキップ
			if V[i][j] == 1 {
				continue
			}

			// 訪問中の土地が海なら訪問済みにしてスキップ
			if M[i][j] == SEA {
				V[i][j] = 1
				continue
			}

			// 未訪問の陸地が見つかったので
			// 島の数を1つ増やし、この陸地から辿れる陸地を訪問していく
			islands++
			queue.PushBack([]int{i, j})

			for queue.Len() > 0 {
				cur := queue.Remove(queue.Front()).([]int)
				h, w := cur[0], cur[1]
				if V[h][w] == 1 {
					continue
				}
				V[h][w] = 1

				// 全方向に未訪問の陸地がないか探索
				for v := -1; v <= 1; v++ {
					for l := -1; l <= 1; l++ {
						dh := h + v
						dw := w + l
						if M[dh][dw] == LAND && V[dh][dw] == 0 {
							queue.PushBack([]int{dh, dw})
						}
					}
				}
				/*
					if M[h-1][w] == LAND {
						queue.PushBack([]int{h - 1, w})
					}
					if M[h-1][w+1] == LAND {
						queue.PushBack([]int{h - 1, w + 1})
					}
					if M[h][w+1] == LAND {
						queue.PushBack([]int{h, w + 1})
					}
					if M[h+1][w+1] == LAND {
						queue.PushBack([]int{h + 1, w + 1})
					}
					if M[h+1][w] == LAND {
						queue.PushBack([]int{h + 1, w})
					}
					if M[h+1][w-1] == LAND {
						queue.PushBack([]int{h + 1, w - 1})
					}
					if M[h][w-1] == LAND {
						queue.PushBack([]int{h, w - 1})
					}
					if M[h-1][w-1] == LAND {
						queue.PushBack([]int{h - 1, w - 1})
					}
				*/
			}
		}
	}
	return islands
}

func main() {
	sc := bufio.NewScanner(os.Stdin)
	sc.Split(bufio.ScanWords)

	for {
		W, H := nextInt(sc), nextInt(sc)

		if W == 0 && H == 0 {
			break
		}
		// Initialize map and visted list
		M := make([][]int, H+2)
		V := make([][]int, H+2)
		for i := 0; i < H+2; i++ {
			M[i] = make([]int, W+2)
			V[i] = make([]int, W+2)
		}
		for i := 1; i <= H; i++ {
			for j := 1; j <= W; j++ {
				M[i][j] = nextInt(sc)
			}
		}

		islands := discoverIslands(M, V, H, W)

		fmt.Println(islands)
	}
}

C++: #include <bits/stdc++.h>
#define _GLIBCXX_DEBUG
using namespace std;
using ll = long long;
using vec = vector<ll>;
using vect = vector<double>;
using Graph = vector<vector<ll>>;
#define loop(i, n) for (ll i = 0; i < n; i++)
#define Loop(i, m, n) for (ll i = m; i < n; i++)
#define pool(i, n) for (ll i = n; i >= 0; i--)
#define Pool(i, m, n) for (ll i = n; i >= m; i--)
#define mod 1000000007ll;
#define setbit bitset<8>
#define flagcount __builtin_popcount
#define flag(x) (1 << x)
#define flagadd(bit, x) bit |= flag(x)
#define flagpop(bit, x) bit &= ~flag(x)
#define flagon(bit, i) bit &flag(i)
#define flagoff(bit, i) !(bit & (1 << i))
#define all(v) v.begin(), v.end()
#define low2way(v, x) lower_bound(all(v), x)
#define high2way(v, x) upper_bound(all(v), x)
#define count2way(v, x) high2way(v, x) - low2way(v, x)
#define lower(v, x) low2way(v, x) - v.begin()       //1番左が0、もし見つから無いならｎを出力
#define higher(v, x) high2way(v, x) - v.begin() - 1 //1番左が0、もし見つからないならn-1を出力（注意）
#define putout(a) cout << a << endl
#define putout2(a, b) \
  putout(a);          \
  putout(b)
#define putout3(a, b, c) \
  putout(a);             \
  putout(b);             \
  putout(c)
#define putout4(a, b, c, d) \
  putout(a);                \
  putout(b);                \
  putout(c);                \
  putout(d)
#define putout5(a, b, c, d, e) \
  putout(a);                   \
  putout(b);                   \
  putout(c);                   \
  putout(d);                   \
  putout(e)
#define Gput(a, b) G[a].push_back(b)
#define cin1(a) cin >> a
#define cin2(a, b) cin >> a >> b
#define cin3(a, b, c) cin >> a >> b >> c
#define cin4(a, b, c, d) cin >> a >> b >> c >> d
#define cin5(a, b, c, d, e) cin >> a >> b >> c >> d >> e
#define sum(v) accumulate(all(v), 0ll)
#define gcd(x, y) __gcd(x, y)
ll ctoi(char c)
{
  if (c >= '0' && c <= '9')
  {
    return c - '0';
  }
  return 0;
}
ll lcm(ll x, ll y)
{
  ll z = gcd(x, y);
  return x * y / z;
}
ll primejudge(ll n)
{
  if (n < 2)
    return 0;
  else if (n == 2)
    return 1;
  else if (n % 2 == 0)
    return 0;
  double sqrtn = sqrt(n);
  Loop(i, 3, sqrtn + 1)
  {
    if (n % i == 0)
    {
      return 0;
    }
    i++;
  }
  return 1;
}
//場合によって使い分ける
//const ll dx[4]={1,0,-1,0};
//const ll dy[4]={0,1,0,-1};
const ll dx[8]={1,1,0,-1,-1,-1,0,1};
const ll dy[8]={0,1,1,1,0,-1,-1,-1};

/*
//TIMESTAMPbfs
vector<bool> seen;
vec first;
vec last;
void dfs(const Graph &G,ll v,ll &time){
  if(!(seen[v])){
  seen[v]=true;
  first[v]=time++;
  for(auto next_v:G[v]){
    if(seen[next_v])continue;
    dfs(G,next_v,time);
  }
  last[v]=time++;
  }
}
//main関数内で
  seen.assign(n, false); // 全頂点を「未訪問」に初期化
  first.resize(n);
  last.resize(n);
*/
//多次元配列の宣言名
//vector<vector<ll>> field(h, vector<ll>(w));
//記念
/*
field.assign(h, vector<ll>(w, 0));
vector<vector<ll>> field;
void dfs(ll x,ll y,ll h,ll w){
  field[x][y]=0;
  loop(i,8){
    ll next_x=x+dx[i],next_y=y+dy[i];
    if(next_x<0||next_x>=h||next_y<0||next_y>=w)continue;
    if(field[next_x][next_y]==0)continue;
    dfs(next_x,next_y,h,w);
  }
}
*/
int main(){
  vec a={198,55,152,18,23,7,8,13,11,1,1,0,0,1};
  loop(i,14)putout(a[i]);
  return 0;
}

C++: #include <cstdio>
#include <iostream>
#include <string>
#include <sstream>
#include <stack>
#include <algorithm>
#include <cmath>
#include <queue>
#include <map>
#include <set>
#include <cstdlib>
#include <bitset>
#include <tuple>
#include <assert.h>
#include <deque>
#include <bitset>
#include <iomanip>
#include <limits>
#include <chrono>
#include <random>
#include <array>
#include <unordered_map>
#include <functional>
#include <complex>

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

const long long MAX = 5100000;
const long long INF = 1LL << 60;
const long long mod = 1000000007LL;
//const long long mod = 998244353LL;

using namespace std;
typedef unsigned long long ull;
typedef long long ll;

int dw[8] = { 0,1,1,1,0,-1,-1,-1 };
int dh[8] = { 1,1,0,-1,-1,-1,0,1 };
void bfs(int sh, int sw, vector<vector<int>>& a) {
	queue<pair<int, int>> q;
	a[sh][sw] = 0;
	int H = a.size();
	int W = a[0].size();
	q.emplace(sh, sw);
	while (!q.empty()) {
		int h, w; tie(h, w) = q.front();
		q.pop();
		for (int i = 0; i < 8; i++) {
			int nh = h + dh[i];
			int nw = w + dw[i];
			if (nh < 0 || nh >= H || nw < 0 || nw >= W) continue;
			if (a[nh][nw] == 0) continue;
			a[nh][nw] = 0;
			q.emplace(nh, nw);
		}
	}
}

int main()
{
	/*
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	*/

	while (1) {
		int W, H; scanf("%d %d", &W, &H);
		if (W == 0 && H == 0) break;
		int res = 0;
		vector<vector<int>> a(H, vector<int>(W)); for (ll i = 0; i < H; i++) for (ll j = 0; j < W; j++) scanf("%d", &a[i][j]);
		for (int i = 0; i < H; i++) {
			for (int j = 0; j < W; j++) {
				if (a[i][j]) {
					res++;
					bfs(i, j, a);
				}
			}
		}
		printf("%d\n", res);
	}
	return 0;
}

C++: #include<iostream>
using namespace std;

char mp[55][55];

void dfs(int x, int y, int n, int m) {
	mp[x][y] = '0';

	for (int i = -1;i <= 1;i++) {
		for (int j = -1;j <= 1;j++) {
			int ax = x + i;
			int ay = y + j;
			if (ax >= 0 && ay >= 0 && ax < m&&ay < n&&mp[ax][ay] == '1') {
				dfs(ax, ay,n,m);
			}
		}
	}
	return;
}

int main() {
	int n, m;
	while (cin >> n >> m, n, m) {
		for (int i = 0;i < m;i++)
			for(int j=0;j<n;j++)cin >> mp[i][j];

		int al = 0;
		for (int i = 0;i < m;i++) {
			for (int j = 0;j < n;j++) {
				if (mp[i][j] == '1') {
					dfs(i, j, n, m);
					al++;
				}
			}
		}
		cout << al << endl;
	}
	return 0;
}