Go: package main

import (
	"fmt"
)

func main() {
	var h, w int
	for {
		fmt.Scan(&w, &h)
		if w == 0 && h == 0 {
			return
		}
		matrix := make([][]int, h)
		Sean := make([][]bool, h)
		for i := 0; i < h; i++ {
			matrix[i] = make([]int, w)
			Sean[i] = make([]bool, w)
			for j := 0; j < w; j++ {
				fmt.Scan(&matrix[i][j])
			}
		}
		var count int
		for i := 0; i < h; i++ {
			for j := 0; j < w; j++ {
				if matrix[i][j] == 1 && Sean[i][j] == false {
					search(i, j, h, w, matrix, Sean)
					count++
				}
			}
		}
		fmt.Println(count)
	}
}
func search(x int, y int, h int, w int, matrix [][]int, Sean [][]bool) {
	if x < 0 || y < 0 || x >= h || y >= w || matrix[x][y] == 0 {
		return
	}
	if Sean[x][y] == true {
		return
	}

	Sean[x][y] = true

	search(x+1, y, h, w, matrix, Sean)
	search(x-1, y, h, w, matrix, Sean)
	search(x, y+1, h, w, matrix, Sean)
	search(x, y-1, h, w, matrix, Sean)
	search(x+1, y-1, h, w, matrix, Sean)
	search(x-1, y+1, h, w, matrix, Sean)
	search(x+1, y+1, h, w, matrix, Sean)
	search(x-1, y-1, h, w, matrix, Sean)
}

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

int main() {
    int w, h;

    stack<pair<int, int>> s;
    
    vector<int> anss(0);
    while(true) {
        cin >> w >> h;
        if (w == 0 && h == 0) {
            break;
        }
        vector<vector<int>> map(h, vector<int>(w));
        vector<vector<bool>> reached(h, vector<bool>(w));
        rep(i, h) rep(j, w) cin >> map[i][j];

        int ans = 0;
        rep(i, h) rep(j, w) {
            s.push(pair<int, int>(i, j));
            bool hasi = false;
            while(!s.empty()) {
                pair<int, int> p = s.top(); s.pop();
                int ph = p.first;
                int pw = p.second;
                if (ph < 0 || ph >= h || pw < 0 || pw >= w) {
                    continue;
                }
                if (map[ph][pw] == 0) {
                    continue;
                }
                if (reached[ph][pw]) {
                    continue;
                }
                hasi = true;
                reached[p.first][p.second] = true;
                s.push(pair<int, int>(ph - 1, pw - 1));
                s.push(pair<int, int>(ph - 1, pw));
                s.push(pair<int, int>(ph - 1, pw + 1));
                s.push(pair<int, int>(ph, pw - 1));
                s.push(pair<int, int>(ph, pw + 1));
                s.push(pair<int, int>(ph + 1, pw - 1));
                s.push(pair<int, int>(ph + 1, pw));
                s.push(pair<int, int>(ph + 1, pw + 1));
            }
            if (hasi) ans++;
        }
        anss.push_back(ans);
    }
    
    for(int i = 0; i < anss.size(); i++ ) {
        cout << anss[i] << endl;
    } 
    return 0;
}

C++: #include <iostream>
#include <algorithm>
#include <queue>

using namespace std;

struct node{
  int x,y;
};

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

int main(){
  int w,h,i,j,k,ans=0;
  while(1){
    queue<node> que;
    cin >> w >> h;
    if(w+h == 0)break;
    int c[h][w];
    ans = 0;
    node now,next,to;
    for(i=0;i<h;i++){
      for(j=0;j<w;j++)cin >> c[i][j];
    }
    for(i=0;i<h;i++){
      for(j=0;j<w;j++){
        if(c[i][j]){
          ++ans;
          now.x = j; now.y = i;
          que.push(now);
          while(!que.empty()){
            next = que.front();
            c[next.y][next.x] = 0;
            que.pop();
            for(k=0;k<8;k++){
              to.x = next.x + dx[k];
              to.y = next.y + dy[k];
              if(to.x<0 || to.x >=w || to.y<0 || to.y >=h)continue;
              if(c[to.y][to.x]){
                que.push(to);
              }
            }
          }
        }
      }
    }
    cout << ans << endl;
  }
  return 0;
}

C++: #define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cmath>
#include <algorithm>
#include <vector>
#include <numeric>
#include <queue>
#include <stack>
#include <map> 
#include <set>
#include <string>
#include <functional>
#include <list>
#include <random>
#include <time.h>
#include <iomanip>
#include <assert.h>
#include <numeric>
#include <new>
#include <sstream>
#include <complex>
#define BIT(nr) (1ULL << (nr))
#define int long long
#define ll long long
#define double long double
#define mod 1000000007
#define MAXN (int)1e+5 * 2+1
#define LL_MAX 9223372036854775807	
#define LL_HALFMAX 9223372036854775807 / 2	
#define MIN -(9223372036854775807 / 2)
#define REP(i,a,n) for(int i=(a); i<(int)(n); i++)
#define rep(i,n) REP(i,0,n)
#define FOR(it,c) for(__typeof((c).begin()) it=(c).begin(); it!=(c).end(); ++it)
#define ALLOF(c) (c).begin(), (c).end()
#define REPS(i,x) for(int i=1;i<=(int)(x);i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RREPS(i,x) for(int i=((int)(x));i>0;i--)
#define repl(i,a,b) for(int i=(int)(a);i<(int)(b);i++)
#define mp make_pair
template<typename T1, typename T2> inline void chmin(T1 & a, T2 b) { if (a > b) a = b; }
template<typename T1, typename T2> inline void chmax(T1& a, T2 b) { if (a < b) a = b; }

using namespace std;

using Weight = int;
using Flow = int;
struct Edge {
	int src, dst;

	// libalgo のものに追加、メンバを追加するだけなので互換性は崩さないはず、逆辺のG[e.dstの]インデックスを保持
	int rev;
	Weight weight;
	Flow cap;
	Edge() : src(0), dst(0), weight(0) {}
	Edge(int s, int d, Weight w) : src(s), dst(d), weight(w) {}
	bool operator<(const Edge& right) const {
		return dst < right.dst;
	}
};

using Edges = std::vector<Edge>;
using Graph = std::vector<Edges>;
using Array = std::vector<Weight>;
using Matrix = std::vector<Array>;

void add_edge(Graph& g, int a, int b, Weight w = 1) {
	g[a].emplace_back(a, b, w);
	g[b].emplace_back(b, a, w);
}
void add_arc(Graph& g, int a, int b, Weight w = 1) { g[a].emplace_back(a, b, w); }

int dx[8] = { 0, 1, 0,-1, 1, 1,-1,-1 }; // x軸方向への変位
int dy[8] = { 1, 0,-1, 0, 1,-1, 1,-1 }; // y軸方向への変位

signed main() {
	int w, h;
	while (1) {
		cin >> w >> h;
		if (w == 0 && h == 0) {
			break;
		}
		vector<vector<int>> m;
		rep(i, h) {
			vector<int> add(w, 0);
			rep(j, w) {
				cin >> add[j];
			}
			m.push_back(add);
		}

		vector<vector<int>> visited(h, vector<int>(w, false));
		function<void(int, int)> dfs = [&](int x, int y) {
			if (visited[y][x]) {
				return;
			}
			visited[y][x] = true;

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

				if (nx < 0 || ny < 0 || nx >= w || ny >= h) {
					continue;
				}
				if (!m[y][x]) {
					continue;
				}
				dfs(nx, ny);
			}
		};
		int ans = 0;
		rep(y, h) {
			rep(x, w) {
				if (visited[y][x]) {
					continue;
				}
				else if(m[y][x]) {
					dfs(x, y);
					ans++;
				}
			}
		}
		cout << ans << "\n";
	}

	return 0;
}