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 <bits/stdc++.h>
using namespace std;
#define REP(i,n) for(int (i) = 0;(i) < (n) ; ++(i))
#define REPS(a,i,n) for(int (i) = (a) ; (i) < (n) ; ++(i))
#define REVERSE(i,n) for(int (i) = n-1;(i) >= 0 ; --i)
#define ALL(c) (c).begin() , (c).end()
#define LL long long
#define int LL
#define inf  (1LL << 60)
#define mod 1000000007
#define QUICK_CIN ios::sync_with_stdio(false); cin.tie(0);
#define lower lower_bound
#define upper upper_bound
#define ZERO(c,n) memset(&c[0],0,sizeof(int)*n)
#define ZERO2(c,n) memset(&c[0][0],0,sizeof(int)*n
#define pl(a) cout << ""#a": " << a << endl;
#ifdef _DEBUG
#define debug_io fstream cin("input.txt");ofstream cout("output.txt");
template<class T>fstream& operator>>(fstream& is, vector<T>& v)
{
	int n = v.size();
	REP(i, n) {
		is >> v[i];
	}
	return is;
}
#else
#define debug_io ;
#endif
#define debug_input debug_io
#define DOWN(T) std::greater<T>()
template<class T>istream& operator>>(istream& is, vector<T>& v)
{
	int n = v.size();
	REP(i, n) {
		is >> v[i];
	}
	return is;
}
using vs = vector<string>; using vi = vector<int>; using pii = pair<int, int>;
using psi = pair<string, int>; using vvi = vector<vi>; using pss = pair<string, string>;
using vpii = vector<pii>;
template<class T>bool valid(T x, T w) { return 0 <= x&&x < w; }
//int dx[4] = { 1, -1, 0, 0 }; int dy[4] = { 0, 0, 1, -1 };
//-----------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------

bool ed[55][55];
int dx[8] = { 0,0,1,-1,1,-1,1,-1 };
int dy[8] = { 1,-1,0,0,1,1,-1,-1 };

signed main()
{
	QUICK_CIN;
	debug_input;
	int w, h;
	while (cin >> w >> h, w + h) {
		vector<vi> tile(h,vi(w));
		REP(i, h) {
			REP(j, w) {
				cin >> tile[i][j];
			}
		}

		int ans = 0;
		REP(i, 55) {
			REP(j, 55) {
				ed[i][j] = false;
			}
		}

		REP(i, h) {
			REP(j, w) {
				if (tile[i][j] != 1)
					continue;
				queue<pii> q;
				q.push({ i,j });
				while (q.size()) {
					auto t = q.front();
					q.pop();
					auto y = t.first;
					auto x = t.second;
					tile[y][x] = 2;
					ed[y][x] = true;
					REP(k, 8) {
						auto nx = min(w-1,max(0LL,x + dx[k]));
						auto ny = min(h-1,max(0LL,y + dy[k]));
						if (!ed[ny][nx]&&tile[ny][nx]==1) {
							q.push({ ny,nx });
						}
					}
				}
				ans++;
			}
		}
		cout << ans << endl;
	}
}

C++: #include <iostream>
#include <iomanip>
#include <sstream>
#include <stdio.h>
#include <list>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <algorithm>
#include <math.h>
#include <utility>
#include <string>
#include <ctype.h>
#include <cstring>
#include <cstdio>
#include <sstream>
#include <functional>

using namespace std;

#define FOR(i,k,n) for(int i = (k); i < (n); i++)
#define REP(i,n) FOR(i,0,n)

int w, h;
int isl[55][55];
int di[] = { -1 - 1, -1, 0, 0, 1, 1, 1 }; int dj[] = { -1, 0, 1, -1, 1, -1, 0, 1 };

void ume(int i, int j)
{
	if (i >= 0 && i < h&&j >= 0 && j < w && isl[i][j] == 1)
	{
		isl[i][j] = 0;
		REP(k, 8)
		{
			ume(i + di[k], j + dj[k]);
		}
	}

}

int main()
{
	while (cin >> w >> h, w)
	{
		REP(i, h)REP(j, w) cin >> isl[i][j];
		int cnt = 0;
		REP(i, h)REP(j, w)
		{
			if (isl[i][j] == 1)
			{
				cnt++;
				ume(i, j);

			}
		}
		cout << cnt << endl;
	}


	return 0;
}

C++: #include <iostream>
#include <iomanip>
#include <vector>
#include <set>
#include <string>
#include <queue>
#include <algorithm>
#include <map>
#include <cmath>
#include <numeric>
#include <list>
#include <stack>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <tuple>

#define rep(i, n) for (int i = 0; i < (n); i++)
#define rep1(i, n) for (int i = 1; i <= (n); i++)
#define show(a, n) rep(i,n) {cout<<a[i]<<' ';} cout<<endl;

using namespace std;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef long long ll;
typedef vector<ll> vll;
typedef pair<long long, long long> pll;

const int INF = 1 << 30;
const long long INFL = 1LL << 62;
const int MOD = 1000000007;
const int MAX = 100000;
const int N = 100010;

void dfs(vector<vi>& c, vector<vi>& d, int i, int j, int cnt) {
	stack<pii> st;
	st.push(pii(i, j));
	int di[] = {0, 1, 1, 1, 0, -1, -1, -1};
	int dj[] = {1, 1, 0, -1, -1, -1, 0, 1};
	while(!st.empty()) {
		pii p = st.top();
		st.pop();
		int si = p.first;
		int sj = p.second;
		rep(k, 8) {
			if(c[si+di[k]][sj+dj[k]] == 0) continue;
			if(d[si+di[k]][sj+dj[k]] != 0) continue;
			d[si+di[k]][sj+dj[k]] = cnt;
			st.push(pii(si+di[k], sj+dj[k]));
		}
	}
}

int cnt(vector<vi>& c) {
	int h = c.size();
	int w = c[0].size();
	vector<vi> d(h, vi(w, 0));
	int cnt = 0;
	rep(i, h) rep(j, w) if(c[i][j] && d[i][j] == 0) dfs(c, d, i, j, ++cnt);
	return cnt;
}

int main() {
//	cout << fixed << setprecision(15);
	int w, h;
	vi ans;
	while(true) {
		cin >> w >> h;
		if(w == 0 && h == 0) break;
		vector<vi> c(h + 2, vi(w + 2, 0));
		rep(i, h) rep(j, w) cin >> c[i+1][j+1];
		ans.push_back(cnt(c));
	}
	for(auto i : ans) cout << i << endl;
}

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

int main() {
	int n;
	while (cin >> n, n) {

		vector<vector<int>>list(n, vector<int>(n, -1));
		int number;

		for (int i = 0;i < n;i++) {
			cin >> number;
			for (int j = 0;j < number;j++) {
				int codename;
				cin >> codename;
				list[i][codename - 1] = 1;
			}
		}//list[a][b]:a know b

		cin >> number;
		
		vector<int>ans(n,1);
		int leaked;
		for (int i = 0;i < number;i++) {
			cin >> leaked;
			for (int j = 0;j < n;j++) {
				if (list[j][leaked - 1] <= 0) ans[j] = 0;
			}
		}//who is imposible
		int sum = 0,telltale;

		for (int i = 0;i < n;i++) {
			sum += ans[i];
			if (ans[i] == 1) telltale = i + 1;
		}

		if (sum == 1)cout << telltale << endl;
		else cout << -1 << endl;

	}
	return 0;
}