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<iostream>
#include<cmath>
#include<algorithm>
#include<string>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<iomanip>
#include<bitset>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> P;
typedef pair<ll,P> P1;
typedef pair<P,P> P2;
#define pu push
#define pb push_back
#define mp make_pair
#define eps 1e-7
#define INF 1000000000
#define fi first
#define sc second
#define rep(i,x) for(ll i=0;i<x;i++)
#define repn(i,x) for(ll i=1;i<=x;i++)
#define SORT(x) sort(x.begin(),x.end())
#define ERASE(x) x.erase(unique(x.begin(),x.end()),x.end())
#define POSL(x,v) (lower_bound(x.begin(),x.end(),v)-x.begin())
#define POSU(x,v) (upper_bound(x.begin(),x.end(),v)-x.begin())

const int MAX = 510000;
const int MOD = 1000000007;

// 四方向への移動ベクトル
const int dx[8] = {1, 0, -1, 0, 1, 1, -1, -1};
const int dy[8] = {0, 1, 0, -1, 1, -1, 1, -1};

// 入力
int H, W;
vector<vector<ll> > field;

// 探索
bool seen[51][51]; // seen[h][w] := マス (h, w) が検知済みかどうか
void dfs(int h, int w) {
    seen[h][w] = true;

    // 四方向を探索
    for (int dir = 0; dir < 8; ++dir) {
        int nh = h + dx[dir];
        int nw = w + dy[dir];

        // 場外アウトしたり、移動先が壁の場合はスルー
        if (nh < 0 || nh >= H || nw < 0 || nw >= W) continue;
        if (field[nh][nw] == 0) continue;

        // 移動先が探索済みの場合
        if (seen[nh][nw]) continue;

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

int main(){
  vector<ll> ans;
  while(1){
    cin >> W >> H;
    if(H == 0 and W == 0) break;
    field.clear();
    field.resize(H); rep(j,H) field[j].resize(W);
    rep(i,H) rep(j,W) cin >> field[i][j];

    rep(i,51) rep(j,51) seen[i][j] = false;
    ll tmp = 0;
    rep(i,H){
      rep(j,W){
        if(field[i][j] == 1 and seen[i][j] == false){
          dfs(i,j);
          tmp++;
        }
      }
    }
    ans.pb(tmp);
  }
  rep(i,ans.size()) cout << ans[i] << endl;
}

C++: //41
#include<iostream>

using namespace std;

int w,h;
bool imap[50][50];

void ff(int y,int x){
  imap[y][x]=false;
  for(int i=-1;i<=1;i++){
    for(int j=-1;j<=1;j++){
      int ny=y+i,nx=x+j;
      if(0<=ny&&ny<h&&0<=nx&&nx<w&&imap[ny][nx]){
	ff(ny,nx);
      }
    }
  }
}

int main(){
  for(;cin>>w>>h,w|h;){
    fill_n(&imap[0][0],50*50,false);
    for(int y=0;y<h;y++){
      for(int x=0;x<w;x++){
	cin>>imap[y][x];
      }
    }
    int ans=0;
    for(int y=0;y<h;y++){
      for(int x=0;x<w;x++){
	if(imap[y][x]){
	  ans++;
	  ff(y,x);
	}
      }
    }
    cout<<ans<<endl;
  }
  return 0;
}

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

#define REP(i,n,m) for(int i=n;i<m;i++)
#define rep(i,n) REP(i,0,n)

class Point{
public:
	int x,y;

	Point(int tx,int ty){
		x = tx;
		y = ty;
	}
};

int w,h;
int t[52][52];
int dx[] = {-1,0,1,-1,1,-1,0,1};
int dy[] = {-1,-1,-1,0,0,1,1,1};

int solve(void){
	int res = 0;

	rep(i,h) rep(j,w) if(t[i][j] == 1) {
		res++;
		deque<Point> stack;
		stack.push_back(Point(j,i));

		while(!stack.empty()){
			Point p = stack.back(); stack.pop_back();
			t[p.y][p.x] = 0;

			rep(k,8){
				int nx = p.x + dx[k];
				int ny = p.y + dy[k];

				if(nx>=0 && nx<w && ny>=0 && ny<h && t[ny][nx]==1){
					stack.push_back(Point(nx,ny));
				}
			}
		}
	}

	return res;
}

int main(void){
	while(cin>>w>>h && (w||h)){
		rep(i,h) rep(j,w) cin>>t[i][j];
		cout<<solve()<<endl;
	}


	return 0;
}

C++: #include<iostream>
#include<fstream>

using namespace std;

	ifstream fin;
	ofstream fout;

	//http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1160&lang=jp

	int gomi = 0;

	int a[52][52] = {};
	int check(int, int);

	int main(){

		fin.open("input.txt");
		fout.open("output.txt");

		//		int w = 0, h = 0;
		int width = 0, height = 0;
		int count = 0;


		while (1){
			for (int i = 0; i < 50; i++)
				for (int j = 0; j < 50; j++)
					a[i + 1][j + 1] = 0;

			cin >> width >> height;
			if (width == 0 && height == 0)break;

			for (int i = 0; i < height; i++){
				for (int j = 0; j < width; j++){
					//初期化
					gomi = a[i + 1][j + 1] = 0;

					cin >> a[i + 1][j + 1];
				}
			}

			for (int i = 0; i < height; i++){
				for (int j = 0; j < width; j++){
					if (a[i + 1][j + 1] == 1){
						check(i + 1, j + 1);
//						a[i + 1][j + 1] = 1;
						count++;
					}
				}
			}
			cout << count << endl;
			fout << count << endl;

			//初期化
			count = 0;
			for (int i = 0; i < height; i++){
				for (int j = 0; j < width; j++){
					a[i + 1][j + 1] = 0;
				}
			}
		}
	}

	int check(int y, int x){
		for (int i = -1; i <= 1; i++){
			for (int j = -1; j <= 1; j++){
				if (i + j != 0 || i - j != 0){
					if (a[y + i][x + j] == 1){
						a[y + i][x + j] = 0;
						check(y + i, x + j);
					}
				}
			}
		}
		return 0;
	}

/*	int check(int y, int x){
		if (a[y + 1][x] == 1){
			a[y + 1][x] = 0;
			check(y + 1, x);
		}
		//-----------------------------
		if (a[y][x + 1] == 1){
			a[y][x + 1] = 0;
			check(y, x + 1);
		}
		//-----------------------------
		if (a[y - 1][x] == 1){
			a[y - 1][x] = 0;
			check(y - 1, x);
		}
		//-----------------------------
		if (a[y][x - 1] == 1){
			a[y][x - 1] = 0;
			check(y, x - 1);
		}
		//-----------------------------
		if (a[y + 1][x + 1] == 1){
			a[y + 1][x + 1] = 0;
			check(y + 1, x + 1);
		}
		//-----------------------------
		if (a[y + 1][x - 1] == 1){
			a[y + 1][x - 1] = 0;
			check(y + 1, x - 1);
		}
		//-----------------------------
		if (a[y - 1][x + 1] == 1){
			a[y - 1][x + 1] = 0;
			check(y - 1, x + 1);
		}
		//-----------------------------
		if (a[y - 1][x - 1] == 1){
			a[y - 1][x - 1] = 0;
			check(y - 1, x - 1);
		}
		//-----------------------------
		return 0;
	}*/