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++: /*
AizuOnline A1160
How many islands
13/03/13 RUNTIME Error
*/
#include <stdio.h>
#include <stdlib.h>

int width = 10;
int height = 10;

char kajuen[100][101];

char search_next(int * x,int * y)
{
  int i,j;
/* printf("SEARCH =%d %d\n",*x,*y); */
  i = *x;j = *y;
  goto START;
  for(i=0;i<height;i++)
    for(j=0;j<width;j++)
      {
      START:
	//	printf("SEARCH =%d %d:",i,j);
	if(kajuen[i][j]=='1')
	  { *x=i;*y=j;
	    return(kajuen[i][j]);
	  }
      }
  return(0);
}

void paint(int p,char f,int x,int y)
{
  int i,j;

#ifdef DEBUG2
  printf("P=%d %d %c %c",x,y,p,f);
  printf("F=%c N=%c %c %c\n",kajuen[x+1][y],kajuen[x][y+1],owner[x+1][y],owner[x][y+1]);
#endif
  //owner[x][y]=p+'A';
  kajuen[x][y]='0';
  for(i=x-1;i<=x+1;i++)
    for(j=y-1;j<=y+1;j++)
      if((i >=0) && (i <height) && (j >= 0) && (j <width) && !(x==i&&y==j))
	{
	  //printf("p:%d %d %d %d",x,y,i,j);
	if(kajuen[i][j] == f)
	  paint(p,f,i,j);
	}
}

int devide_kajuen()
{
  int x,y;
  char person;
  char f;

  
  x=0;y=0;
  person = 0;
  while(f=search_next(&x,&y) != 0)
    {   
      f = kajuen[x][y];
      paint(person,f,x,y);
      person ++;

    }
  return(person);
}
void clear_table()
{
  int i,j;
  for(i=0;i<100;i++)
      for(j=0;j<101;j++)
      {
        kajuen[i][j]='\0';
      }   
}
main()
{
  int n;
  int i,j;


  while(EOF != scanf("%d %d",&width,&height) && (width || height))
    {
      clear_table();
      for(i=0;i<height;i++)
	for(j=0;j<width;j++)
	  {  scanf(" %c",&(kajuen[i][j])); 
	  }      

      n = devide_kajuen();
      printf("%d\n",n);      
    }

  return(0);
}

C++: /**
 * code generated by JHelper
 * More info: https://github.com/AlexeyDmitriev/JHelper
 * @author champon
 */

#include <iostream>
#include <fstream>
#include<bits/stdc++.h>
#define se cout << "test ok" << endl;
#define sp << " " <<
#define enl "\n"
using namespace std;
using ll=long long;
using ld=long double;
ll mod = ll(1e9)+7;
ll inf = ll(1e18);
void bl(bool b, ostream& out=cout){ out << (b ? "Yes" : "No") << endl; }
void bl2(bool b, ostream& out=cout){ out << (b ? "YES" : "NO") << endl; }
template<typename T> inline bool chmax(T &a, T b){ if(a<b){a=b; return true;} return false; }
template<typename T> inline bool chmin(T &a, T b){ if(a>b){a=b; return true;} return false; }
int dx[] = {1, 0, -1, 0, 1, -1, 1, -1};
int dy[] = {0, 1, 0, -1, 1, -1, -1, 1};

#ifndef INCLUDE_DEBUG_HPP
#define INCLUDE_DEBUG_HPP

#include <iostream>
#include <vector>
#include <map>
using namespace std;

namespace dbg {
    using ll = long long;

    class Debug {
    public:
        Debug(){}
        template<typename T>
        void vd(vector<T> vec);
        template<typename T>
        void vd2(vector<vector<T>> vec);
        template<typename T>
        void ad(T *arr, ll n);
        template<typename T, size_t N>
        void ad2(T (&arr)[N], ll n);
        template<typename T>
        void md(T mp);
    };

    template<typename T>
    void Debug::vd(vector<T> vec) {
        for (auto vv : vec) cout << vv << " ";
        cout << endl;
    }

    template<typename T>
    void Debug::vd2(vector<vector<T>> vec) {
        for (auto vv : vec) {
            for (auto vvv : vv) cout << vvv << " ";
            cout << endl;
        }
    }

    template<typename T>
    void Debug::ad(T *arr, ll n) {
        for (int i = 0; i <= n; i++) cout << arr[i] << " ";
        cout << endl;
    }

    template<typename T, size_t N>
    void Debug::ad2(T (&arr)[N], ll n) {
        for (int i = 0; i <= N; i++) for (int j = 0; j <= n; j++) cout << arr[i][j] << " ";
        cout << endl;
    }

    template<typename T>
    void Debug::md(T mp) {
        cout << "key : value" << endl;
        for (auto const &m : mp) cout << m.first << " : " << m.second << endl;
        cout << endl;
    }

}

#endif //INCLUDE_DEBUG_HPP

using dbg::Debug;
Debug debug;

class a {
public:
    int w, h;
    vector<vector<int>> g;
    vector<vector<int>> visited;

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

	void solve(std::istream& in, std::ostream& out) {
        while(true) {
            in >> w >> h;
            if(!w && !h) break;
            g.assign(h, vector<int>(w));
            visited.assign(h, vector<int>(w, 0));

            for (int i = 0; i < h; i++) {
                for (int j = 0; j < w; j++) {
                    in >> g[i][j];
                }
            }

            ll cnt = 0;
            for(int i=0; i<h; i++){
                for(int j=0; j<w; j++){
                    if(visited[i][j] || !g[i][j]) continue;
                    dfs(i, j);
                    cnt++;
                }
            }

            out << cnt << enl;
        }
	}
};


int main() {
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);
	a solver;
	std::istream& in(std::cin);
	std::ostream& out(std::cout);
	solver.solve(in, out);
	return 0;
}