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>
using namespace std;

#define REP(i,m,n) for(int i=(m); i<(int)(n); i++)
#define RREP(i,m,n) for(int i=(int)(n-1); i>=m; i--)
#define rep(i,n) REP(i,0,n)
#define rrep(i,n) RREP(i,0,n)
#define all(a) (a).begin(),(a).end()
#define rall(a) (a).rbegin(),(a).rend()
#define aut(r,v) __typeof(v) r = (v)
#define each(it,o) for(aut(it,(o).begin()); it!=(o).end(); ++it)
#define reach(it,o) for(aut(it,(o).rbegin()); it!=(o).rend(); ++it)
#define fi first
#define se second
#define debug(...) {cerr<<"[L"<<__LINE__<<"] "; _debug(__VA_ARGS__);}

template<typename T1, typename T2> ostream& operator<<(ostream& o, const pair<T1, T2>& p)
{return o<<"("<<p.first<<", "<<p.second<<")";}
template<typename T>string join(const vector<T>&v, string del=", ")
{stringstream s;rep(i,v.size())s<<del<<v[i];return s.str().substr(del.size());}
template<typename T>ostream& operator<<(ostream& o, const vector<T>&v)
{if(v.size())o<<"["<<join(v)<<"]";return o;}
template<typename T>ostream& operator<<(ostream& o, const vector<vector<T> >&vv)
{int l=vv.size();if(l){o<<endl;rep(i,l){o<<(i==0?"[ ":",\n  ")<<vv[i]<<(i==l-1?" ]":"");}}return o;}
template<typename T>ostream& operator<<(ostream& o, const set<T>& st)
{vector<T> v(st.begin(),st.end());o<<"{ "<<join(v)<<" }";return o;}
template<typename T1, typename T2>ostream& operator<<(ostream& o, const map<T1, T2>& m)
{each(p,m){o<<(p==m.begin()?"{ ":",\n  ")<<*p<<(p==--m.end()?" }":"");}return o;}
inline void _debug(){cerr<<endl;}
template<class First, class... Rest>
void _debug(const First& first, const Rest&... rest){cerr<<first<<" ";_debug(rest...);}

typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef vector<vl> vvl;

const double PI = (1*acos(0.0));
const double EPS = 1e-9;
const ll INF = 0x3f3f3f3f;
const ll INFL = 0x3f3f3f3f3f3f3f3fLL;
const ll mod = 1e9 + 7;

inline void finput(string filename) {
    freopen(filename.c_str(), "r", stdin);
}

int di[] = {0, -1, -1, -1, 0, 1, 1, 1};
int dj[] = {1, 1, 0, -1, -1, -1, 0, 1};

int w,h;
vvi C;

void dfs(pii cur, pii pre, int num){
    int i = cur.fi, j = cur.se;
    C[i][j] = 0;
    rep(k,8){
        int ni = i+di[k];
        int nj = j+dj[k];
        if(ni < 0 || h <= ni) continue;
        if(nj < 0 || w <= nj) continue;
        if(C[ni][nj] == 0) continue;
        if(ni == pre.fi && nj == pre.se) continue;
        dfs(pii(ni,nj), pii(i,j), num);
    }
}

void solve(){
    C = vvi(h, vi(w));
    rep(i,h) rep(j,w) cin >> C[i][j];

    int cnt = 0;
    rep(i,h){
        rep(j,w){
            if(C[i][j] == 1)
                dfs(pii(i,j), pii(-1,-1), ++cnt);
        }
    }
    cout << cnt << endl;
}

int main(){
    ios_base::sync_with_stdio(0);
    // finput("./input");
    while(cin >> w >> h, w != 0 && h != 0){
        solve();
    }
    return 0;
}

C++: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i, n) for(int(i) = 0; i < (int)(n); (i)++)
using Graph = vector<vector<int>>;

int w, h;
ll cnt = 0;
Graph G;
struct Direct {
    int x;
    int y;
};

Direct direction[8] = {{-1, -1}, {0, -1}, {1, -1}, {-1, 0},
                       {1, 0},   {-1, 1}, {0, 1},  {1, 1}};

void dfs(int x, int y) {
    if(G[y][x] == 1) {
        G[y][x] = 0;
    }
    rep(i, 8) {
        if(0 <= x + direction[i].x && x + direction[i].x < w) {
            if(0 <= y + direction[i].y && y + direction[i].y < h) {
                if(G[y + direction[i].y][x + direction[i].x] == 1) {
                    dfs(x + direction[i].x, y + direction[i].y);
                }
            }
        }
    }
}

int main() {
    while(1) {
        cnt=0;
        cin >> w >> h;

        G = Graph(h);
        if(!w && !h) break;
        rep(i, h) {
            G[i] = vector<int>(w);
        }
        rep(i, h) {
            rep(j, w) {
                cin >> G[i][j];
            }
        }
        rep(i, h) {
            rep(j, w) {
                if(G[i][j]) {
                    cnt++;
                    dfs(j, i);
                }
            }
        }
        cout << cnt << endl;
    }
    return 0;
}

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

typedef struct{
	int first;
	int second;
}point;

int main(){
	while(1){
		int w, h;
		int field[50][50];
		int dx[8]={1,1,0,-1,-1,-1,0,1}, dy[8]={0,1,1,1,0,-1,-1,-1};
		
		scanf(" %d %d", &w, &h);
		if(w==0) break;
		
		for(int i=0; i<h; ++i)
		for(int j=0; j<w; ++j)	
		scanf(" %d", &field[i][j]);
		
		int ans=0;
		for(int i=0; i<h; ++i){
			for(int j=0; j<w; ++j){
			
				if(field[i][j]==1){
					//printf("%d %d\n", i, j);
					queue<point> que;
					point p;
					p.first=i; p.second=j;
					field[i][j]=2; //訪問済み
					que.push(p);
					++ans;
					
					//bfs
					while(!que.empty()){
						p=que.front();
						que.pop();
						for(int k=0; k<8; ++k){
							int nf=p.first+dy[k], ns=p.second+dx[k];
							if(nf>=0 && nf<h && ns>=0 && ns<w && field[nf][ns]==1){
								field[nf][ns]=2;
								point q;
								q.first=nf;
								q.second=ns;
								que.push(q);
							}	
						}
					
					}
		
				}
			}
			
		}
		printf("%d\n", ans);
	}
	return 0;
}