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>
using namespace std;
#define rep(i,n) for(ll i=0;i<n;i++)
#define repl(i,l,r) for(ll i=(l);i<(r);i++)
#define per(i,n) for(ll i=n-1;i>=0;i--)
#define lper(i,r,l) for(ll i=r-1;i>=l;i--)
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define ins insert
#define all(x) (x).begin(),(x).end()
#define CST(x) cout<<fixed<<setprecision(x)
using ll=long long;
using vl=vector<ll>;
using vvl=vector<vector<ll>>;
using pl=pair<ll,ll>;
using vpl=vector<pl>;
const ll MOD=1000000007;
const ll MOD9=998244353;
const int inf=1e9+10;
const ll INF=4e18;
const ll dy[8]={1,0,-1,0,1,1,-1,-1};
const ll dx[8]={0,-1,0,1,1,-1,1,-1};
ll modfac(ll a){
    ll ans=1;
    while(a>1){
        ans*=a;
        ans%=1000000007;
        a--;
    }
    return ans;
}
ll modinv(ll a,ll m) {
    ll b = m, u = 1, v = 0;
    while (b) {
        ll t = a / b;
        a -= t * b; swap(a, b);
        u -= t * v; swap(u, v);
    }
    u %= m; 
    if (u < 0) u += m;
    return u;
}
struct UnionFind {
    vector<int> par;
    
    UnionFind(int n) : par(n, -1) {}

    int root(int x) {
        if (par[x] < 0) return x;
        else return par[x] = root(par[x]);
    }
    
    bool same(int x, int y) {
        return root(x) == root(y);
    }
    
    bool merge(int x, int y) {
        x = root(x); y = root(y);
        if (x == y) return false;
        if (par[x] > par[y]) swap(x, y);
        par[x] += par[y];
        par[y] = x;
        return true;
    }
    
    int size(int x) {
        return -par[root(x)];
    }
};
ll modpow(ll a, ll n, ll mod) {
    ll res = 1;
    while (n > 0) {
        if (n & 1) res = res * a % mod;
        a = a * a % mod;
        n >>= 1;
    }
    return res;
}
template<class T> inline bool chmin(T& a, T b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}
template<class T> inline bool chmax(T& a, T b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}
ll h,w;
vvl field(h,vl(w));
void dfs(ll y,ll x){
    field[y][x]=0;
    rep(i,8){
        ll ny=y+dy[i],nx=x+dx[i];
        if(ny<0||nx<0||ny>=h||nx>=w)continue;
        if(field[ny][nx]==1){
            dfs(ny,nx);
        }
    }
}
int main(){
    while(true){
        ll ans=0;
        cin >> w >>h;
        if(w==0&&h==0)break;
        field.assign(h,vl(w));
        rep(i,h){
            rep(j,w)cin >> field[i][j];
        }
        rep(i,h){
            rep(j,w){
                if(field[i][j]==1){
                    dfs(i,j);
                    ans++;
                }
            }
        }
        cout <<ans <<endl;
    }
}

C++: #include<iostream>
#include<vector>
#include<stdio.h>
using namespace std;
#define DUMP(x)  cerr << #x << " = " << (x) << endl;
#define DEBUG(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << ")" << " " << __FILE__ << endl;

vector<vector<int> > map;
vector<vector<bool> > reach;
int w,h;

void dfs(int i, int j){
    if((reach[i][j]) or (map[i][j]==0))
        return;
    reach[i][j] = true;
    if(0<i && 0<j) dfs(i-1,j-1);
    if(0<i) dfs(i-1,j);
    if(0<i && j<w-1) dfs(i-1,j+1);
    if(0<j) dfs(i, j-1);
    if(j<w-1) dfs(i, j+1);
    if(i<h-1 && 0<j) dfs(i+1,j-1);
    if(i<h-1) dfs(i+1,j);
    if(i<h-1 && j<w-1) dfs(i+1,j+1);
}

int main(){

    while((cin >> w >> h) && (w>0 && h>0)){
        int res=0;
        for (int i = 0; i < h; i++) {
            vector<int> temp(w,0);
            for (int j = 0; j < w; j++)
                cin >> temp[j];
            map.push_back(temp);
        }
        for (int i = 0; i < h; i++){
            vector<bool> temp(0,false);
            reach.push_back(temp);
        }
        for (int i = 0; i < h; i++) {
            for (int j = 0; j < w; j++) {
                if(map[i][j]==1 && !reach[i][j]){
                    res++;
                    dfs(i,j);
                }
            }
        }
        cout << res << endl;
        map.clear();
        reach.clear();

    }
    return 0;
}

C++: #include "bits/stdc++.h"

using namespace std;

#define ll long long
#define vi  vector<int>
#define vvi vector<vi>
#define pi  pair<int,int>
#define mp  make_pair
#define pb  push_back
#define MOD 1e9 + 7
#define PAI  3.1415
#define all(x) (x).begin(),(x).end()
#define chmax(x,y) x = max(x,y)
#define chmin(x,y) x = min(x,y)
#define pr(x) cout << x << endl
#define Endl endl
#define rep(i,n) for(int i = 0 ; i < n; i++)

const int dx[4] = {1,0,-1,0};
const int dy[4] = {0,1,0,-1};
const int ddx[8] = {-1,0,1,-1,1,-1,0,1};
const int ddy[8] = {-1,-1,-1,0,0,1,1,1};
const int inf = 99999999;
const ll linf = 1LL << 62;

ll gcd(ll a,ll b){
  if(a < b)swap(a , b);
  if(a % b == 0) return b;
  else gcd(b, a%b);
}

ll lcm(ll a,ll b){
  if(a < b)swap(a , b);
  return (a/gcd(a , b))*b;
}

struct UnionFind {
  vi par; //par[i] : iの親番号（例）par[3] = 2 : 3の親は2

  UnionFind(int N) : par(N) { //最初は全てが根として初期化
    rep(i,N) par[i] = i;
  }

  int root(int x){ //データxが属する木の根を再帰で得る : root(x) = {xの木の根}
    if(par[x] == x)return x;
    return par[x] = root(par[x]);
  }

  void unite(int x, int y){ //xとyの木を併合
    int rx = root(x); //xの根をrx
    int ry = root(y); //yの根をry
    if(rx == ry)return; //xとyの根が同じ
    par[rx] = ry; //xとyの根が同じでない時、xの根rxをyの根にryにつける。
  }

  bool same(int x, int y){//2つのデータx，yが属する木が同じならtrueを返す
    int rx = root(x);
    int ry = root(y);
    return rx == ry;
  }
};

int h,w;
vector<vector<int> > v(60, vector<int>(60, 0));
vector<vector<bool> > visited(60, vector<bool>(60,false));

int dfs(int i, int j){
  if(visited[i][j])return 0;

  visited[i][j] = true;
  rep(x,8){
    rep(y,8){
      int posx = j + ddx[x];
      int posy = i + ddy[y];
      if(0 <= posx && posx < w && 0 <= posy && posy < h){
        if(!visited[posy][posx] and v[posy][posx]){
          dfs(posy,posx);
        }
      }
    }
  }
  return 1;
}

int main(){

   while(cin >> w >> h, w and h){
    int ans = 0;
    rep(i,60){
      rep(j,60){
         visited[i][j] = false;
      }
    }

    rep(i,h){
      rep(j,w){
        cin >> v[i][j];
      }
    }

    rep(i,h){
      rep(j,w){
        if( !visited[i][j] && v[i][j])ans += dfs(i,j);
      }
    }
   cout << ans << endl;
   }

  return 0;

}

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

void f(int n){
if(n%100==0){
cerr<<n<<endl;
}
}

int main(){
f(1);
}