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 <sstream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cstring>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <bitset>
#include <numeric>
#include <utility>
#include <iomanip>
#include <algorithm>
#include <functional>
using namespace std;

typedef long long ll;
typedef vector<int> vint;
typedef vector<ll> vll;
typedef pair<int,int> pint;

#define DE 1
#define FI first
#define SE second
#define PB push_back
#define MP make_pair
#define ALL(s) (s).begin(),(s).end()
#define REP(i,n) for (int i = 0; i < (int)(n); ++i)
#define EACH(i,s) for (typeof((s).begin()) i = (s).begin(); i != (s).end(); ++i)
#define COUT(x) cout<<#x<<" = "<<(x)<<" (L"<<__LINE__<<")"<<endl

template<class T1, class T2> ostream& operator<<(ostream &s, pair<T1,T2> P){return s<<'<'<<P.first<<", "<<P.second<<'>';}
template<class T> ostream& operator<<(ostream &s, vector<T> P) {s<<"{ ";for(int i=0;i<P.size();++i){if(i>0)s<<", ";s<<P[i];}return s<<" }"<<endl;}
template<class T1, class T2> ostream& operator<<(ostream &s, map<T1,T2> P) {s<<"{ ";for(typeof(P.begin()) it=P.begin();it!=P.end();++it){if(it!=P.begin())s<<", ";s<<'<'<<it->first<<"->"<<it->second<<'>';}return s<<" }"<<endl;}



int dx[8] = {1, 1, 0, -1, -1, -1, 0, 1};
int dy[8] = {0, 1, 1, 1, 0, -1, -1, -1};

int w,h;
int C[100][100];
bool seen[100][100];

int res = 0;
void dfs(int x, int y) {
    seen[x][y] = true;
    
    for (int i = 0; i < 8; ++i) {
        int nx = x + dx[i], ny = y + dy[i];
        if (nx < 0 || nx >= h || ny < 0 || ny >= w) continue;
        if (!seen[nx][ny] && C[nx][ny] == 1) {
            dfs(nx, ny);
        }
    }
}

int main() {
    //freopen( "/Users/macuser/Documents/Programming/Contest/input.in", "r", stdin );
    
    while (cin >> w >> h) {
        if (w == 0) break;
        
        memset(C, 0, sizeof(C));
        for (int i = 0; i < h; ++i) {
            for (int j = 0; j < w; ++j) {
                cin >> C[i][j];
            }
        }
        
        res = 0;
        memset(seen, 0, sizeof(seen));
        
        for (int i = 0; i < h; ++i) {
            for (int j = 0; j < w; ++j) {
                if (!seen[i][j] && C[i][j] == 1) {
                    dfs(i, j);
                    ++res;
                }
            }
        }
        
        cout << res << endl;
    }
    
    return 0;
}

C++: #pragma GCC optimize ("O3")

#include <bits/stdc++.h>

using namespace std;

#ifdef LOCAL
#include <prettyprint.hpp>
#define debug(...)  cerr << "[" << #__VA_ARGS__ << "]: ", d_err(__VA_ARGS__);
#else
#define debug(...) 83;
#endif

void d_err() {
    cerr << endl;
}

template <typename H, typename... T>
void d_err(H h, T... t) {
    cerr << h << " ";
    d_err(t...);
}

template <typename T>
void print(T x) {
    cout << x << "\n";
}

#define ALL(x) (x).begin(), (x).end()
#define FOR(i, m, n) for (int i = (m); i < (n); ++i)
#define REVFOR(i, m, n) for (int i = (n - 1); i >= (m); --i)
#define REP(i, n) FOR(i, 0, n)
#define REVREP(i, n) REVFOR(i, 0, n)
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define eb emplace_back
#define bcnt __builtin_popcountll

typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<ll,ll> Pll;
typedef pair<int,int> Pin;

ll INF = 1e16;
int inf = 1e9;
ll MOD = 1e9+7;

int main() {
    cin.tie(0);
    ios_base::sync_with_stdio(false);
    cout << fixed << setprecision(20);

    while(true) {
        int w, h; cin >> w >> h;

        if(w == 0 && h == 0) break;

        vector<vi> m(h, vi(w));
        REP(i, h) REP(j, w) cin >> m[i][j];

        vector<vector<bool>> visit(h, vector<bool>(w, false));

        vi dx = {0, 1, -1}, dy = {0, 1, -1};
        auto check = [&] (int x, int y) -> bool {
            return x >= 0 && x < w && y >= 0 && y < h;
        };

        auto dfs = [&] (auto &&f, int cx, int cy) -> void {
            visit[cy][cx] = true;

            REP(i, 3) REP(j, 3) {
                int nx = cx + dx[i], ny = cy + dy[j];
                if (check(nx, ny)){
                    if(!visit[ny][nx] && m[ny][nx] == 1) {
                        f(f, nx, ny);
                    }
                }
            }
        };

        int ans = 0;
        REP(i, h) REP(j, w) {
            if (m[i][j] == 1 && !visit[i][j]) dfs(dfs, j, i), ans++;
        }

        print(ans);
    }

}