Go: package main

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

var sc = bufio.NewScanner(os.Stdin)
var route [][]int

func scanInt() int {
	num, _ := strconv.Atoi(scanString())
	return num
}

func scanString() string {
	sc.Scan()
	return sc.Text()
}

func init() {
	sc.Split(bufio.ScanWords)
}

func dfs(h, w int) {
	if route[h][w] == 0 {
		return
	}

	route[h][w] = 0
	for _, x := range []int{-1, 0, 1} {
		for _, y := range []int{-1, 0, 1} {
			if route[h+x][w+y] == 0 {
				continue
			}
			dfs(h+x, w+y)
		}
	}
}

func main() {
	writer := bufio.NewWriter(os.Stdout)
	for {
		w, h := scanInt(), scanInt()
		if w == 0 && h == 0 {
			break
		}

		route = make([][]int, h+2)
		route[0] = make([]int, w+2)
		for i := 1; i <= h; i++ {
			route[i] = make([]int, w+2)
			for j := 1; j <= w; j++ {
				route[i][j] = scanInt()
			}
		}
		route[h+1] = make([]int, w+2)

		total := 0
		for i := 1; i <= h; i++ {
			for j := 1; j <= w; j++ {
				if route[i][j] == 1 {
					total++
					dfs(i, j)
				}
			}
		}
		fmt.Fprintln(writer, total)
	}
	writer.Flush()
}

C++: #define _CRT_SECURE_NO_WARNINGS
#include "bits/stdc++.h"
#include <random>

using namespace std;

//呪文
#define DUMPOUT cerr
#define dump(...) DUMPOUT<<"  ";DUMPOUT<<#__VA_ARGS__<<" :["<<__LINE__<<":"<<__FUNCTION__<<"]"<<endl;DUMPOUT<<"    ";dump_func(__VA_ARGS__)

typedef unsigned uint; typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> pii; typedef pair<ll, ll> pll; typedef pair<double, double> pdd; typedef pair<string, string> pss;
template <typename _KTy, typename _Ty> ostream& operator << (ostream& ostr, const pair<_KTy, _Ty>& m) { ostr << "{" << m.first << ", " << m.second << "}"; return ostr; }
template <typename _KTy, typename _Ty> ostream& operator << (ostream& ostr, const map<_KTy, _Ty>& m) { if (m.empty()) { ostr << "{ }"; return ostr; } ostr << "{" << *m.begin(); for (auto itr = ++m.begin(); itr != m.end(); itr++) { ostr << ", " << *itr; } ostr << "}"; return ostr; }
template <typename _Ty> ostream& operator << (ostream& ostr, const vector<_Ty>& v) { if (v.empty()) { ostr << "{ }"; return ostr; } ostr << "{" << v.front(); for (auto itr = ++v.begin(); itr != v.end(); itr++) { ostr << ", " << *itr; }	ostr << "}"; return ostr; }
template <typename _Ty> ostream& operator << (ostream& ostr, const set<_Ty>& s) { if (s.empty()) { ostr << "{ }"; return ostr; } ostr << "{" << *(s.begin()); for (auto itr = ++s.begin(); itr != s.end(); itr++) { ostr << ", " << *itr; }	ostr << "}"; return ostr; }
template <typename _Ty> ostream& operator << (ostream& ostr, const stack<_Ty>& s) { if (s.empty()) { ostr << "{ }"; return ostr; } stack<_Ty> t(s); ostr << "{" << t.top(); t.pop(); while (!t.empty()) { ostr << ", " << t.top(); t.pop(); } ostr << "}";	return ostr; }
template <typename _Ty> ostream& operator << (ostream& ostr, const list<_Ty>& l) { if (l.empty()) { ostr << "{ }"; return ostr; } ostr << "{" << l.front(); for (auto itr = ++l.begin(); itr != l.end(); ++itr) { ostr << ", " << *itr; } ostr << "}"; return ostr; }
template <typename _KTy, typename _Ty> istream& operator >> (istream& istr, pair<_KTy, _Ty>& m) { istr >> m.first >> m.second; return istr; }
template <typename _Ty> istream& operator >> (istream& istr, vector<_Ty>& v) { for (size_t i = 0; i < v.size(); i++) istr >> v[i]; return istr; }
namespace aux { // print tuple
	template<typename Ty, unsigned N, unsigned L> struct tp { static void print(ostream& os, const Ty& v) { os << get<N>(v) << ", "; tp<Ty, N + 1, L>::print(os, v); } };
	template<typename Ty, unsigned N> struct tp<Ty, N, N> { static void print(ostream& os, const Ty& value) { os << get<N>(value); } };
}
template<typename... Tys> ostream& operator<<(ostream& os, const tuple<Tys...>& t) { os << "{"; aux::tp<tuple<Tys...>, 0, sizeof...(Tys)-1>::print(os, t); os << "}"; return os; }

template<typename A, size_t N, typename T> inline void Fill(A(&array)[N], const T &val) { std::fill((T*)array, (T*)(array + N), val); }

void dump_func() { DUMPOUT << endl; }
template <class Head, class... Tail> void dump_func(Head&& head, Tail&&... tail) { DUMPOUT << head; if (sizeof...(Tail) == 0) { DUMPOUT << " "; } else { DUMPOUT << ", "; } dump_func(std::move(tail)...); }

#define PI 3.14159265358979323846
#define EPS 1e-11
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n)  FOR(i,0,n)
#define all(x) (x).begin(), (x).end()
#define SZ(x) ((int)(x).size())
#define fake false



const int di[] = { 0, -1, -1, -1, 0, 1, 1, 1 };
const int dj[] = { 1, 1, 0, -1, -1, -1, 0, 1 };

int main()
{
	//clock_t start, end;
	//start = clock();

	cin.tie(0);
	ios::sync_with_stdio(false);

	while (true) {
		int w, h;
		cin >> w >> h;
		if (w == 0) break;

		vector<vector<int>> A(h, vector<int>(w));
		cin >> A;

		int cnt = 0;
		REP(i, h) REP(j, w) {
			if (A[i][j] == 1) {
				cnt++;

				queue<pii> qu;
				qu.push(pii(i, j));

				while (!qu.empty()) {
					pii p = qu.front(); qu.pop();
					int ii = p.first, jj = p.second;

					A[ii][jj] = 0;

					REP(d, 8) {
						int ni = ii + di[d], nj = jj + dj[d];
						if (ni < 0 || h <= ni || nj < 0 || w <= nj || A[ni][nj] == 0) continue;
						qu.push(pii(ni, nj));
					}
				}

			}
		}
		cout << cnt << endl;
	}
	
	//end = clock();
	//printf("%d msec.\n", end - start);

	return 0;
}

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

struct dsu {
  const int n;
  vector<int> p, sz;
  dsu(int _n) : n(_n), p(n, -1), sz(n, 1) {}
  int root(int v) { return p[v] == -1 ? v : v = root(p[v]); }
  void unite(int u, int v) {
    u = root(u), v = root(v);
    if (u == v) return;
    if (sz[u] < sz[v]) swap(u, v);
    p[v] = u;
    sz[u] += sz[v];
  }
  int size(int v) { return sz[root(v)]; }
};

int main() {
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  int h, w;
  while (cin >> w >> h, w) {
    vector<vector<int>> a(h, vector<int>(w));
    for (auto&& v : a) {
      for (auto&& e : v) {
        cin >> e;
      }
    }
    dsu d(h * w);
    for (int i = 0; i < h; ++i) {
      for (int j = 0; j < w; ++j) {
        if (a[i][j]) {
          for (int di = -1; di <= 1; ++di) {
            for (int dj = -1; dj <= 1; ++dj) {
              if (di or dj) {
                int ni = i + di, nj = j + dj;
                if (0 <= ni and ni < h and 0 <= nj and nj < w and a[ni][nj]) {
                  d.unite(i * w + j, ni * w + nj);
                }
              }
            }
          }
        }
      }
    }
    set<int> se;
    for (int i = 0; i < h; ++i) {
      for (int j = 0; j < w; ++j) {
        if (a[i][j]) {
          se.insert(d.root(i * w + j));
        }
      }
    }
    cout << se.size() << '\n';
  }
}

C++: #include <iostream>
#include <algorithm>
#include <cctype>
#include <cstdio>
#include <math.h>
using namespace std;

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

int w,h,cnt,l[50][50];

void f(int x,int y){
	l[y][x]=0;
	for(int i=0;i<8;i++){
		int nx=x+dx[i];
		int ny=y+dy[i];
		if(nx>=0&&nx<w&&ny>=0&&ny<h&&l[ny][nx]==1)f(nx,ny);
	}
}

int main(){
	while(cin>>w>>h,w||h){
		cnt=0;
		for(int i=0;i<w*h;i++)cin>>l[i/w][i%w];
		for(int i=0;i<w*h;i++)if(l[i/w][i%w]==1){cnt++;f(i%w,i/w);}
		cout<<cnt<<endl;
	}
}