Go: package main

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

func getScanner(fp *os.File) *bufio.Scanner {
	scanner := bufio.NewScanner(fp)
	scanner.Split(bufio.ScanWords)
	scanner.Buffer(make([]byte, 1000005), 1000005)
	return scanner
}

func getNextString(scanner *bufio.Scanner) string {
	scanner.Scan()
	return scanner.Text()
}

func getNextInt(scanner *bufio.Scanner) int {
	i, _ := strconv.Atoi(getNextString(scanner))
	return i
}

func getNextInt64(scanner *bufio.Scanner) int64 {
	i, _ := strconv.ParseInt(getNextString(scanner), 10, 64)
	return i
}

func getNextUint64(scanner *bufio.Scanner) uint64 {
	i, _ := strconv.ParseUint(getNextString(scanner), 10, 64)
	return i
}

func getNextFloat64(scanner *bufio.Scanner) float64 {
	i, _ := strconv.ParseFloat(getNextString(scanner), 64)
	return i
}

func main() {
	fp := os.Stdin
	wfp := os.Stdout
	cnt := 0

	if os.Getenv("MASPY") == "ますピ" {
		fp, _ = os.Open(os.Getenv("BEET_THE_HARMONY_OF_PERFECT"))
		cnt = 0
	}
	if os.Getenv("MASPYPY") == "ますピッピ" {
		wfp, _ = os.Create(os.Getenv("NGTKANA_IS_GENIUS10"))
	}

	scanner := getScanner(fp)
	writer := bufio.NewWriter(wfp)
	for solve(scanner, writer) {

	}
	for i := 0; i < cnt; i++ {
		fmt.Fprintln(writer, "-----------------------------------")
		solve(scanner, writer)
	}
	writer.Flush()
}

func solve(scanner *bufio.Scanner, writer *bufio.Writer) bool {
	sol := solver{}
	sol.w = getNextInt(scanner)
	sol.h = getNextInt(scanner)
	if sol.w == 0 && sol.h == 0 {
		return false
	}
	sol.land = makeInts(sol.h, sol.w)
	for y := 0; y < sol.h; y++ {
		for x := 0; x < sol.w; x++ {
			sol.land[y][x] = getNextInt(scanner)
		}
	}
	ans := 0
	for y := 0; y < sol.h; y++ {
		for x := 0; x < sol.w; x++ {
			if sol.land[y][x] == 0 {
				continue
			}
			ans++
			sol.dfs(y, x)
		}
	}
	fmt.Fprintln(writer, ans)
	return true
}

type solver struct {
	w, h int
	land [][]int
}

func (sol *solver) dfs(y, x int) {
	if y < 0 {
		return
	}
	if y >= sol.h {
		return
	}
	if x < 0 {
		return
	}
	if x >= sol.w {
		return
	}
	if sol.land[y][x] == 0 {
		return
	}
	sol.land[y][x] = 0
	dy := [8]int{-1, -1, -1, 0, 0, 1, 1, 1}
	dx := [8]int{-1, 0, 1, -1, 1, -1, 0, 1}
	for i := 0; i < 8; i++ {
		sol.dfs(y+dy[i], x+dx[i])
	}
}
func makeInts(h, w int) [][]int {
	index := make([][]int, h, h)
	data := make([]int, h*w, h*w)
	for i := 0; i < h; i++ {
		index[i] = data[i*w : (i+1)*w]
	}
	return index
}

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

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

void dfs(int y, int x)
{
	f[y][x] = 0;
	for(int i=0; i<8; i++)
	{
		int ny = y+dy[i];
		int nx = x+dx[i];
		if(f[ny][nx])
		{
			dfs(ny,nx);
		}
	}
}

int main()
{
	int w,h,c,x,y;
	while(cin >> w >> h, w||h)
	{
		memset(f,0,sizeof(f));

		for(y=1; y<=h; y++)
		for(x=1; x<=w; x++)
		{
			cin >> f[y][x];
		}

		c=0;
		for(y=1; y<=h; y++)
		for(x=1; x<=w; x++)
		{
			if(f[y][x])
			{
				c++;
				dfs(y,x);
			}
		}
		cout << c << endl;
	}
}

C++: #include<bits/stdc++.h>
using namespace std;

#define rep(i,n) for(long long i=0;i<n;i++)
#define REP(i,s,n) for(long long i=(s);i<=(n);i++)
#define repr(i,n) for(long long i=n-1;i>=0;i--)
#define REPR(i,s,n) for(long long i=(s);i>=(n);i--)
#define all(a) (a).begin(),(a).end()
#define rall(a) (a).rbegin(),(a).rend()
#define Eunique(v) v.erase(unique(all(v)),v.end())
#define Eback(s) s.erase(s.end()-1,s.end())
#define minvec(v) *min_element(all(v))
#define maxvec(v) *max_element(all(v))
#define sumvec(v) accumulate(all(v),0LL)
#define pb push_back
#define pf push_front
#define m_p make_pair
#define DOUBLE fixed << setprecision(15)
#define OK cerr<<"OK\n"
#define OK1 cerr<<"OK1\n"
#define OK2 cerr<<"OK2\n"
#define sz(s) (long long)s.size()
#define INF ((1LL<<62)-(1LL<<31))
#define zero(x,n) setw(x) << setfill('0') << n
//#define endl '\n'

typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef vector<long long> vll;
typedef vector<double> vd;
typedef vector<char> vc;
typedef vector<bool> vb;
typedef vector<string> vs;
typedef vector<vi> vvi;
typedef vector<vll> vvll;
typedef vector<vd> vvd;
typedef vector<vc> vvc;
typedef vector<vb> vvb;
typedef pair<ll,ll> P;
typedef vector<P> vP;
typedef queue<ll> qll;
typedef priority_queue<ll> pqll;

template<class A, class B>
ostream& operator<<(ostream& ost, const pair<A, B>&p) {
	ost << "{" << p.first << ", " << p.second << "} ";
	return ost;
}

template<class T>
ostream& operator<<(ostream& ost, const vector<T>&v) {
	ost << "{";
	for (int i = 0; i<(int)v.size(); i++) {
		if (i)ost << " ";
		ost << v[i];
	}
	ost << "} \n";
	return ost;
}

template<class A, class B>
ostream& operator<<(ostream& ost, const map<A, B>&v) {
	ost << "{";
	for (auto p:v) {
		ost << "{" << p.first << ", " << p.second << "} ";
	}
	ost << "} ";
	return ost;
}

void out(){cout << "\n";}
template<class T,class... Args>
void out(const T &x,const Args &... args){
	cout << x << " ";
	out(args...);
}

template<typename T>
istream& operator >> (istream& is, vector<T>& vec){
	for(T& e: vec) is >> e;
	return is;
}

template<typename T>
string join(vector<T>& vec, string sep=" "){
	stringstream ss;
	for(int i=0;i<(int)vec.size();i++){
		ss << vec[i] << (i+1==(int)vec.size()?"\n":sep);
	}
	return ss.str();
}

template<class T>
inline bool chmax(T& a, T b){if(a<b){a=b;return true;} return false;}

template<class T>
inline bool chmin(T& a, T b){if(a>b){a=b;return true;} return false;}

#define INT(...) int __VA_ARGS__;IN(__VA_ARGS__)
#define LL(...) long long __VA_ARGS__;IN(__VA_ARGS__)
#define CHR(...) char __VA_ARGS__;IN(__VA_ARGS__)
#define DBR(...) double __VA_ARGS__;IN(__VA_ARGS__)
#define STR(...) string __VA_ARGS__;IN(__VA_ARGS__)
#define LD(...) long double __VA_ARGS__;IN(__VA_ARGS__)

void scan(int& a){ cin >> a; }
void scan(long long& a){ cin >> a; }
void scan(char& a){ cin >> a; }
void scan(double& a){ cin >> a; }
void scan(string& a){ cin >> a; }
void scan(long double& a){ cin >> a; }

void IN(){}
template<class Head,class... Tail> void IN(Head& head,Tail&... tail){ scan(head); IN(tail...); }

void YES(bool b) {cout << ((b)?"YES\n":"NO\n");}
void Yes(bool b) {cout << ((b)?"Yes\n":"No\n");}
void yes(bool b) {cout << ((b)?"yes\n":"no\n");}
void Yay(bool b) {cout << ((b)?"Yay!\n":":(\n");}

const long double pi = acos(-1.0);
const ll mod=1000000007;
//const ll mod=998244353;

ll powmod(ll a,ll b){ll c=1; while(b>0){ if(b&1){ c=a*c%mod; } a=a*a%mod; b>>=1; } return c;}
ll invmod(ll a){ return powmod(a,mod-2); }
ll nCrmod(ll n,ll r){ll x=1,y=1; for(ll i=0;i<r;i++) {x=x*(n-i)%mod; y=y*(i+1)%mod; } return x*powmod(y,mod-2)%mod;}
ll gcd(ll a,ll b){ while(b){ ll c=b; b=a%b; a=c; } return a; }
ll lcm(ll a,ll b){ if(!a || !b) return 0; return a*b/gcd(a,b); }
vll divisor(ll x){ vll v; for(int i=1;i*i<=x;i++)if(x%i==0){ v.pb(i);if(i*i!=x)v.pb(x/i); } sort(all(v)); return v; };
map<ll,ll> prime_factor(ll n){ map<ll,ll> m; for(ll i=2;i*i<=n;i++){ while(n%i==0){ m[i]++; n /= i; } }if(n!=1) m[n]=1; return m; }

int main()
{
	ll h,w;
	vll ans;
	ll dy[]={-1,-1,-1,0,0,1,1,1};
	ll dx[]={-1,0,1,-1,1,-1,0,1};
	while(cin >> w >> h, h && w){
		vvll a(h,vll(w)),visited(h,vll(w));
		ll cnt=0;
		rep(i,h)rep(j,w) cin >> a[i][j];
		rep(i,h){
			rep(j,w){
				if(visited[i][j] || a[i][j]==0) continue;
				cnt++;
				queue<P> q;
				q.push({i,j});
				visited[i][j]=cnt;
				while(!q.empty()){
					ll y=q.front().first;
					ll x=q.front().second;
					q.pop();
					rep(k,8){
						ll ny=y+dy[k];
						ll nx=x+dx[k];
						if(ny<0 || ny>=h || nx<0 || nx>=w) continue;
						if(a[ny][nx]==1 && !visited[ny][nx]){
							visited[ny][nx]=cnt;
							q.push({ny,nx});
						}
					}
				}
			}
		}
		ans.push_back(cnt);
	}
	cout << join(ans,"\n");
	return 0;
}