Go: package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

var sc = bufio.NewScanner(os.Stdin)
var route [][]int

func scanInt() int {
	num, _ := strconv.Atoi(scanString())
	return num
}

func scanString() string {
	sc.Scan()
	return sc.Text()
}

func init() {
	sc.Split(bufio.ScanWords)
}

func dfs(h, w int) {
	if route[h][w] == 0 {
		return
	}

	route[h][w] = 0
	for _, x := range []int{-1, 0, 1} {
		for _, y := range []int{-1, 0, 1} {
			if route[h+x][w+y] == 0 {
				continue
			}
			dfs(h+x, w+y)
		}
	}
}

func main() {
	writer := bufio.NewWriter(os.Stdout)
	for {
		w, h := scanInt(), scanInt()
		if w == 0 && h == 0 {
			break
		}

		route = make([][]int, h+2)
		route[0] = make([]int, w+2)
		for i := 1; i <= h; i++ {
			route[i] = make([]int, w+2)
			for j := 1; j <= w; j++ {
				route[i][j] = scanInt()
			}
		}
		route[h+1] = make([]int, w+2)

		total := 0
		for i := 1; i <= h; i++ {
			for j := 1; j <= w; j++ {
				if route[i][j] == 1 {
					total++
					dfs(i, j)
				}
			}
		}
		fmt.Fprintln(writer, total)
	}
	writer.Flush()
}

C++: #include <iostream>
#include <string>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <complex>
#include <utility>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <climits>
#include <bitset>
#include <ctime>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <cassert>
#include <cstddef>
#include <iomanip>
#include <numeric>
#include <tuple>
#include <sstream>
#include <fstream>

using namespace std;
#define REP(i, n) for (int (i) = 0; (i) < (n); (i)++)
#define FOR(i, a, b) for (int (i) = (a); (i) < (b); (i)++)
#define RREP(i, a) for(int (i) = (a) - 1; (i) >= 0; (i)--)
#define FORR(i, a, b) for(int (i) = (a) - 1; (i) >= (b); (i)--)
#define DEBUG(C) cerr << #C << " = " << C << endl;
using LL = long long;
using VI = vector<int>;
using VVI = vector<VI>;
using VL = vector<LL>;
using VVL = vector<VL>;
using VD = vector<double>;
using VVD = vector<VD>;
using PII = pair<int, int>;
using PDD = pair<double, double>;
using PLL = pair<LL, LL>;
using VPII = vector<PII>;
#define ALL(a) begin((a)), end((a))
#define RALL(a) rbegin((a)), rend((a))
#define SORT(a) sort(ALL((a)))
#define RSORT(a) sort(RALL((a)))
#define REVERSE(a) reverse(ALL((a)))
#define MP make_pair
#define FORE(a, b) for (auto &&a : (b))
#define FIND(s, e) ((s).find(e) != (s).end())
#define EB emplace_back

const int INF = 1e9;
const int MOD = INF + 7;
const LL LLINF = 1e18;

VVI C;
vector<vector<bool>> used;
int MH, MW;
int dh[] = {0, 0, -1, 1, -1, -1, 1, 1};
int dw[] = {-1, 1, 0, 0, -1, 1, -1, 1};
bool inside(int h, int w) {
    return 0 <= h && h < MH && 0 <= w && w < MW;
}
bool dfs(int h, int w) {
    if (used[h][w]) return false;
    used[h][w] = true;
    REP(i, 8) {
        int nh = h + dh[i], nw = w + dw[i];
        if (!inside(nh, nw)) continue;
        if (C[nh][nw] == 1) dfs(nh, nw);
    }
    return true;
}
void solve(int w, int h) {
    MH = h; MW = w;
    C.resize(h, VI(w));
    used.resize(h, vector<bool>(w, false));
    REP(i, h)REP(j, w) cin >> C[i][j];
    int cnt = 0;
    REP(i, h)REP(j, w) {
        if (C[i][j] == 1) cnt += dfs(i, j);
    }
    cout << cnt << endl;
    used.clear();
    C.clear();
    return;
}

int main(void) {
    int n, p, m, w, h;
    string s;
    int a, b, c;
    while (cin >> w >> h) {
        if (w == 0 && h == 0) return 0;
        solve(w, h);
        //return 0;
    }
}

C++: #include <bits/stdc++.h>
using namespace std;
using ll=long long;
typedef pair<int,int> P;
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; }
int main(){
    int w,h;
    cin>>w>>h;
    vector<vector<int>>G(h,vector<int>(w));
    queue<P> Q;
    for(int i=0;i<h;i++){
        for(int j=0;j<w;j++){
            cin>>G.at(i).at(j);
        }
    }
    int count=0,x,y,nx,ny;
    P p;
    for(int i=0;i<h;i++){
        for(int j=0;j<w;j++){
            if(G.at(i).at(j)==1){
            Q.push(P(i,j));
            while(!Q.empty()){
        p=Q.front();
        Q.pop();
        x=p.first;
        y=p.second;
        G.at(x).at(y)=0;
            for(int i=-1;i<=1;i++){
        for(int j=-1;j<=1;j++){
            nx=x+i;
            ny=y+j;
        if(0<=nx&& nx<h && 0<=ny&& ny<w && G.at(nx).at(ny)==1) Q.push(P(nx,ny));
        }
    }
    }
    count++;
    }
    }
    }
cout<<count<<endl;
}

C++: #include <cstdio>
#include <iostream>
#include <queue>
#include <utility>

using namespace std;

//関数プロトタイプ宣言
bool input();
void bfs(int H, int W);

//変数宣言
int w, h;
bool chart[50][50];		//trueは陸、falseは海
bool check[50][50];		//探索を終えた場所はtrue
typedef pair<int, int> P;	//P(h, w)に統一する
int dw[8] = {-1, -1, -1, 0, 0, 1, 1, 1};
int dh[8] = {-1, 0, 1, -1, 1, -1, 0, 1};	
//順に　左上　←　左下　↑　↓　右上　→　右下

int main()
{
	while (input())
	{
		int output = 0;
		//check配列の初期化
		for (int i=0; i<h; i++)
			for (int i2=0; i2<w; i2++)
				check[i][i2] = false;
	
		//陸の探索
		for (int i=0; i<h; i++)
		{
			for (int i2=0; i2<w; i2++)
			{
				//次のbfsで１つの島の全ての陸のcheckをtrueにする
				if (chart[i][i2]==true)
				{
					bfs(i, i2);		//引数は(h, w)で渡している
					output++;
				}
			}
		}
		printf("%d\n", output);
	}
	return 0;
}


//こいつにある陸の座標を渡すと、陸続きの全ての陸のcheck値がtrueになる
void bfs(int H, int W)
{
	queue<P> que;
	//スタート地点の陸の座標をキューに入れる
	que.push(P(H, W));
	check[H][W] = true;
	chart[H][W] = false;
	
	//キューが空になるまでループ
	while (que.size())
	{
		// printf("in while\n");
		
		//キューの先頭を取りだす
		P p = que.front();
		que.pop();
		
		//移動８方向をループ
		for (int i=0; i<8; i++)
		{
			//移動後の座標をnw, nhとする
			int nw = p.second + dw[i];
			int nh = p.first + dh[i];
			
			if (0<=nw && nw<w && 0<=nh && nh<h && chart[nh][nw]==true && check[nh][nw]==false)
			{
				que.push(P(nh, nw));
				check[nh][nw] = true;
				chart[nh][nw] = false;
			}
		}
	}
}

bool input()
{
	scanf("%d %d", &w, &h);
	if (w==0) return false;

	for (int i=0; i<h; i++)
	{
		for (int i2=0; i2<w; i2++)
		{
			//陸はtrue、海はfalseで入る
			cin >> chart[i][i2];
			// printf("%d ", chart[i][i2]);
		}
		// printf("\n");
	}
	return true;
}

C++: #include <bits/stdc++.h>
using namespace std;

// 入力
int H, W;
vector<vector<int>> field(H, vector<int>(W, 0));

// 探索
void dfs(int h, int w)
{
    field[h][w] = 0;

    // 八方向を探索
    for (int dh = -1; dh <= 1; ++dh)
    {
        for (int dw = -1; dw <= 1; ++dw)
        {
            int nh = h + dh, nw = w + dw;

            // 場外アウトしたり、0 だったりはスルー
            if (nh < 0 || nh >= H || nw < 0 || nw >= W)
                continue;
            if (field[nh][nw] == 0)
                continue;

            // 再帰的に探索
            dfs(nh, nw);
        }
    }
}

int main()
{
    // 入力受け取り
    while (cin >> W >> H)
    {
        if (H == 0 || W == 0)
            break;
        field.assign(H, vector<int>(W, 0));
        for (int h = 0; h < H; ++h)
            for (int w = 0; w < W; ++w)
                cin >> field[h][w];

        // 探索開始
        int count = 0;
        for (int h = 0; h < H; ++h)
        {
            for (int w = 0; w < W; ++w)
            {
                if (field[h][w] == 0)
                    continue; // 残島じゃなかったらスルー
                dfs(h, w);
                ++count;
            }
        }
        cout << count << endl;
    }
}