Go: package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"strconv"
)

const (
	initialBufSize = 100000
	maxBufSize     = 1000000
)

var sc *bufio.Scanner

func initScanner(r io.Reader) *bufio.Scanner {
	buf := make([]byte, initialBufSize)

	sc := bufio.NewScanner(r)
	sc.Buffer(buf, maxBufSize)
	sc.Split(bufio.ScanWords) // bufio.ScanLines
	return sc
}

func main() {
	sc = initScanner(os.Stdin)
	resolve()
}

func resolve() {
	results := []int{}
	for true {
		w, h := scanInt(sc), scanInt(sc)
		if w == 0 && h == 0 {
			break
		}
		grid := make([][]int, h)
		for i := 0; i < h; i++ {
			grid[i] = make([]int, w)
			for j := 0; j < w; j++ {
				grid[i][j] = scanInt(sc)
			}
		}
		num := 0
		for i := range loop0(h) {
			for j := range loop0(w) {
				start := pos{y: i, x: j}
				if grid[start.y][start.x] == 0 {
					continue
				}
				num++
				_dfs(grid, w, h, start)
			}
		}
		results = append(results, num)
	}
	for _, v := range results {
		fmt.Println(v)
	}
	return
}

func _dfs(grid [][]int, w, h int, start pos) {
	grid[start.y][start.x] = 0
	for _, df := range []pos{
		pos{1, 0}, pos{-1, 0},
		pos{0, -1}, pos{0, 1},
		pos{1, 1}, pos{-1, -1},
		pos{-1, 1}, pos{1, -1},
	} {
		np := addPos(start, df)
		if np.y < 0 || h <= np.y || np.x < 0 || w <= np.x {
			continue
		}
		if grid[np.y][np.x] == 0 {
			continue
		}
		_dfs(grid, w, h, np)
	}
}

type pos struct{ x, y int }

func addPos(p, d pos) pos {
	return pos{
		x: p.x + d.x,
		y: p.y + d.y,
	}
}

func loop0(n int) chan int {
	return loop(0, n-1, 1)
}

func loop1(n int) chan int {
	return loop(1, n, 1)
}

func loop(s, e, d int) chan int {
	ch := make(chan int)
	go func() {
		for i := s; i <= e; i += d {
			ch <- i
		}
		close(ch)
	}()
	return ch
}

// snip-scan-funcs
func scanInt(sc *bufio.Scanner) int {
	sc.Scan()
	i, _ := strconv.Atoi(sc.Text())
	return int(i)
}
func scanString(sc *bufio.Scanner) string {
	sc.Scan()
	return sc.Text()
}

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

typedef long long ll;
using namespace std;

int H, W;
vector<vector<int>> C;
vector<vector<int>> visited;
int ans = 0;





void dfs(int &i, int &j){
    visited[i][j] = 1;
    for(int y=-1; y<=1; y++){
        for(int x=-1; x<=1; x++){
            int ny = i+y;
            int nx = j+x;
            
            if(ny>=0 && ny<H && nx>=0 && nx<W && C[ny][nx] && !visited[ny][nx]) dfs(ny, nx);
        }
    }
    return;
}




int main() {
    while(1){
        ans = 0;
        visited.clear();
        
        cin >> W >> H; if((W&H)==0) break;
        C.resize(H);
        for(vector<int> &v:C) v.resize(W);
        for(vector<int> &row:C)
            for(int &c:row) cin >> c;

        visited.resize(H);
        for(vector<int> &v:visited) v.resize(W);

        for(int i=0; i<H; i++){
            for(int j=0; j<W; j++){
                if(C[i][j] && !visited[i][j]){
                    dfs(i,j);
                    ans ++;
                }
            }
        }
        
        
        cout << ans << endl;
    }
    return 0;
}

C++: #include<bits/stdc++.h>
#define rep(i,n) for(int i = 0; i < n; ++i)
#define rrep(i,n) for(int i = 1; i <= n; ++i)
using namespace std;
//using ll=long long;
const int MX = 2200000;
//const ll LINF = 1000000000000000000ll;
//const long long MOD = 1000000007;
//long long INF = 90000000001000;
int w,h;
bool seen[50][50];
int c[50][50];
int d[2]={1,-1};
void dfs(int i,int j){
    seen[i][j]=true;
    for (int k = 0; k < 2; ++k)
    {
       if (!seen[i+d[k]][j]&&i+d[k]<h&&i+d[k]>=0&&c[i+d[k]][j])dfs(i+d[k],j);
       if (!seen[i][j+d[k]]&&j+d[k]<w&&j+d[k]>=0&&c[i][j+d[k]])dfs(i,j+d[k]);
       if (!seen[i+d[k]][j-d[k]]&&i+d[k]<h&&i+d[k]>=0&&j-d[k]>=0&&j-d[k]<w&&c[i+d[k]][j-d[k]])dfs(i+d[k],j-d[k]);
       if (!seen[i+d[k]][j+d[k]]&&i+d[k]<h&&i+d[k]>=0&&j+d[k]<w&&j+d[k]>=0&&c[i+d[k]][j+d[k]])dfs(i+d[k],j+d[k]); 
    }

}


int main(){


while(1){
cin >> w >> h;
if(w==0&&h==0) break;
for (int i = 0; i < h; ++i)
{
   for (int j = 0; j < w; ++j)
   {
       cin >> c[i][j];
       seen[i][j]=false;
   }
}
int cnt=0;
for (int i = 0; i < h; ++i)
{
  for (int j = 0; j < w; ++j)
  {
    if(c[i][j]==1&&!seen[i][j]){cnt++;dfs(i,j);}
  }
}
cout << cnt << endl;
}

return 0;

}

C++: #include<cstdio>
#include<stack>

using namespace std;

struct Coord {
  int row;
  int col;
};

int solve (int W, int H);
  
int main () {
  int W, H;

  while(1)
    {
      scanf("%d%d", &W, &H);
      if(W==0 && H==0) break;	
      printf("%d\n", solve(W,H));	
    }
}

int solve (int W, int H) {
  int n=0;
  char M[H+2][W+2];
  Coord start;
  for (int i=0; i<=W+1; i++) { M[0][i] = '0'; M[H+1][i] = '0'; }
  for (int i=1; i<=H; i++) { M[i][0] = '0'; M[i][W+1] = '0'; } 
  for (int i=1; i<=H; i++) {
    for (int j=1; j<=W; j++) {
      scanf(" %c", &M[i][j]);
    }
  }
  for(int i=1 ; i<=H ; i++) {
    for(int j=1 ; j<=W ; j++){
      if(M[i][j]=='1'){	
        start.row=i;
        start.col=j;
        M[start.row][start.col]='@';

        stack<Coord> S;
        S.push(start);
        while (!S.empty()) {
          Coord current = S.top(); S.pop();
          int D1[]={1,1,0,-1,-1,-1,0,1}; int D2[]={0,-1,-1,-1,0,1,1,1};
          for (int d=0; d<8; d++) {
            Coord nc = current;
            nc.row += D1[d];
            nc.col += D2[d];
            if(M[nc.row][nc.col]!='0' && M[nc.row][nc.col]!='*' && M[nc.row][nc.col]!='@')
	      {
	        M[nc.row][nc.col] = '*';
	        S.push(nc);
	      }
          } 
        }
        n++;
      }
    }
  }
  return n;
}

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

int fill(int field[50][50], int x, int y, int w, int h){
    if(field[x][y] == 1){
        field[x][y] = 0;
        if(x+1<w) fill(field, x+1, y, w, h);
        if(y+1<h) fill(field, x, y+1, w, h);
        if(x-1>=0) fill(field, x-1, y, w, h);
        if(y-1>=0) fill(field, x, y-1, w, h);
        if(x+1<w && y+1<h) fill(field, x+1, y+1, w, h);
        if(x+1<w && y-1>=0) fill(field, x+1, y-1, w, h);
        if(x-1>=0 && y+1<h) fill(field, x-1, y+1, w, h);
        if(x-1>=0 && y-1>=0) fill(field, x-1, y-1, w, h);
        return 1;
    }
    return 0;
}

int main(){
    int w, h;
    int field[50][50];
    int result;
    cin >> w >> h;
    while(w || h){
        result = 0;
        for(int i=0;i<h;++i){
            for(int j=0;j<w;++j){
                cin >> field[j][i];
            }
        }
        for(int i=0;i<h;++i){
            for(int j=0;j<w;++j){
                result += fill(field, j, i, w, h);
            }
        }
        cout << result << endl;
        cin >> w >> h;
    }
}

C++: #include <iostream>
#include <cmath>
#include <vector>

using namespace std;

#define loop(i,a,b) for(int i=(a);i<int(b);i++)
#define rep(i,b) loop(i,0,b)

int c[200][200];
int vis[200][200];
int w,h;


void dfs(int ci, int cj){
    vis[ci][cj] = true;
    int di[] = {0,1,0,-1, 1,1,-1,-1};
    int dj[] = {1,0,-1,0, -1,1,-1,1};
    rep(d,8){
        int ni = ci+di[d];
        int nj = cj+dj[d];
        if(ni < 0 || nj < 0) continue;
        if(ni >= h || nj >= w) continue;
        if(vis[ni][nj]) continue;
        if(c[ni][nj]==0) continue;
        dfs(ni,nj);
    }
}

int main(){
    while(cin >> w >> h){
        rep(i,h)rep(j,w) cin >> c[i][j], vis[i][j] = 0;
        int ans = 0;
        rep(i,h)rep(j,w){
            if(vis[i][j]) continue;
            if(c[i][j] == 0) continue;
            dfs(i,j);
            ans++;
        }
        cout << ans << endl;
    }
}