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

using ll = long long;
using ull = unsigned long long;

constexpr int MOD = 1e9 + 7;
constexpr int MAXN = 1024 * 4 + 4;

int N, M, K, Q;
char h[2050];
unsigned char mat[MAXN][1024 * 2 + 2];
unsigned char vis[MAXN][1024 * 2 + 2];

unsigned char get_num(int i) {
    unsigned char num = 0;
    if (isdigit(h[i])) {
        num = (h[i] - '0');
    } else {
        num = (h[i] - 'A' + 10);
    }
    num *= 16;
    --i;
    if (i >= 0) {
        if (isdigit(h[i])) {
            num += (h[i] - '0');
        } else {
            num += (h[i] - 'A' + 10);
        }
    }
    return num;
}

void dfs(int i, int j, unsigned char idx) {
    vis[i][j] |= idx;
    if (j < K && idx == 1 && (mat[i][j+1] & 0x80) && !(vis[i][j+1] & 0x80))
        dfs(i, j+1, 0x80);
    if (idx != 1 && ((mat[i][j] & (idx >> 1))) && !(vis[i][j] & (idx >> 1)))
        dfs(i, j, idx >> 1);
    if (j > 0 && idx == 0x80 && (mat[i][j-1] & 0x01) && !(vis[i][j-1] & 0x01))
        dfs(i, j+1, 0x80);
    if (idx != 0x80 && (mat[i][j] & (idx << 1)) && !(vis[i][j] & (idx << 1)))
        dfs(i, j, idx << 1);
    if (i > 0 && (mat[i-1][j] & idx) && !(vis[i-1][j] & idx))
        dfs(i-1, j, idx);
    if (i < N && (mat[i+1][j] & idx) && !(vis[i+1][j] & idx))
        dfs(i+1, j, idx);
}

ull solution() {
    ull ans = 0;
    K = M / 4;
    if (K & 1) K = (K >> 1) + 1;
    else K >>= 1;
    for (int i = 0; i < N; ++i) {
        for (int j = 0; j < K; ++j) {
            unsigned char idx = 0x80;
            while (idx != 0) {
                if ((mat[i][j] & idx) && !(vis[i][j] & idx)) {
                    dfs(i, j, idx);
                    ans += 1;
                }
                idx >>= 1;
            }
        }
    }
    return ans;
}

int main() {
    // freopen("in.txt", "r", stdin);
    scanf("%d%d", &N, &M);
    for (int i = 0; i < N; ++i) {
        scanf("%s", h);
        int l = strlen(h);
        int c = 0;
        for (int j = l-1; j >= 0; j -= 2) {
            mat[i][c++] = get_num(j);
        }
    }
    printf("%llu", solution());
    return 0;
}


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

using ll = long long;
using ull = unsigned long long;

constexpr int MOD = 1e9 + 7;
constexpr int MAXN = 1 << 12 + 2;

int N, M, K, Q;
char h[3000];
unsigned char mat[MAXN][3000];

unsigned char get_num(int i, int len) {
    unsigned char num = 0;
    if (isdigit(h[i])) {
        num = (h[i] - '0');
    } else {
        num = (h[i] - 'A' + 10);
    }
    num *= 16;
    ++i;
    if (i < len) {
        if (isdigit(h[i])) {
            num += (h[i] - '0');
        } else {
            num += (h[i] - 'A' + 10);
        }
    }
    return num;
}

void dfs(int i, int j, unsigned char idx) {
    mat[i][j] &= ~idx;
    if (j+1 < K && idx == 0x01 && (mat[i][j+1] & 0x80))
        dfs(i, j+1, 0x80);
    if (j-1 >= 0 && idx == 0x80 && (mat[i][j-1] & 0x01))
        dfs(i, j-1, 0x01);

    if (idx != 0x01 && (mat[i][j] & (idx >> 1)))
        dfs(i, j, idx >> 1);
    if (idx != 0x80 && (mat[i][j] & (idx << 1)))
        dfs(i, j, idx << 1);

    if (i-1 >= 0 && (mat[i-1][j] & idx))
        dfs(i-1, j, idx);
    if (i+1 < N && (mat[i+1][j] & idx))
        dfs(i+1, j, idx);
}

ull solution() {
    ull ans = 0;
    if (M % 8) K = (M >> 3) + 1;
    else K = M >> 3;
    for (int i = 0; i < N; ++i) {
        for (int j = 0; j < K; ++j) {
            unsigned char idx = 0x80;
            while (idx != 0) {
                if ((mat[i][j] & idx)) {
                    dfs(i, j, idx);
                    ans += 1;
                }
                idx >>= 1;
            }
        }
    }
    return ans;
}

int main() {
    // freopen("in.txt", "r", stdin);
    scanf("%d%d", &N, &M);
    for (int i = 0; i < N; ++i) {
        scanf("%s", h);
        int l = M / 4;
        int c = 0;
        for (int j = 0; j < l; j += 2)
            mat[i][c++] = get_num(j, l);
    }
    printf("%llu", solution());
    return 0;
}


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

using ll = long long;
using ull = unsigned long long;

constexpr int MOD = 1e9 + 7;
constexpr int MAXN = (1 << 12) + 2;

int N, M, K, Q;
char h[4100];
unsigned char mat[MAXN][2050];

unsigned char get_num(int i, int len) {
    unsigned char num = 0;
    if (isdigit(h[i])) {
        num = (h[i] - '0');
    } else {
        num = (h[i] - 'A' + 10);
    }
    num *= 16;
    ++i;
    if (i < len) {
        if (isdigit(h[i])) {
            num += (h[i] - '0');
        } else {
            num += (h[i] - 'A' + 10);
        }
    }
    return num;
}

void dfs(int i, int j, unsigned char idx) {
    mat[i][j] &= ~idx;
    if (j+1 < K && idx == 0x01 && (mat[i][j+1] & 0x80))
        dfs(i, j+1, 0x80);
    if (j-1 >= 0 && idx == 0x80 && (mat[i][j-1] & 0x01))
        dfs(i, j-1, 0x01);

    if (idx != 0x01 && (mat[i][j] & (idx >> 1)))
        dfs(i, j, idx >> 1);
    if (idx != 0x80 && (mat[i][j] & (idx << 1)))
        dfs(i, j, idx << 1);

    if (i-1 >= 0 && (mat[i-1][j] & idx))
        dfs(i-1, j, idx);
    if (i+1 < N && (mat[i+1][j] & idx))
        dfs(i+1, j, idx);
}

ull solution() {
    ull ans = 0;
    if (M % 8) K = (M >> 3) + 1;
    else K = M >> 3;
    for (int i = 0; i < N; ++i) {
        for (int j = 0; j < K; ++j) {
            unsigned char idx = 0x80;
            while (idx != 0) {
                if ((mat[i][j] & idx)) {
                    dfs(i, j, idx);
                    ans += 1;
                }
                idx >>= 1;
            }
        }
    }
    return ans;
}

int main() {
    // freopen("in.txt", "r", stdin);
    scanf("%d%d", &N, &M);
    for (int i = 0; i < N; ++i) {
        scanf("%s", h);
        int l = M / 4;
        int c = 0;
        for (int j = 0; j < l; j += 2)
            mat[i][c++] = get_num(j, l);
    }
    printf("%llu", solution());
    return 0;
}


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

using ll = long long;
using ull = unsigned long long;

constexpr int MOD = 1e9 + 7;
constexpr int MAXN = 1024 * 4 + 4;

int N, M, K, Q;
char h[2050];
unsigned char mat[MAXN][1024 * 2 + 2];

unsigned char get_num(int i, int len) {
    unsigned char num = 0;
    if (isdigit(h[i])) {
        num = (h[i] - '0');
    } else {
        num = (h[i] - 'A' + 10);
    }
    num *= 16;
    ++i;
    if (i < len) {
        if (isdigit(h[i])) {
            num += (h[i] - '0');
        } else {
            num += (h[i] - 'A' + 10);
        }
    }
    return num;
}

void dfs(int i, int j, unsigned char idx) {
    mat[i][j] &= ~idx;
    if (j < K && idx == 1 && (mat[i][j+1] & 0x80))
        dfs(i, j+1, 0x80);
    if (j > 0 && idx == 0x80 && (mat[i][j-1] & 0x01))
        dfs(i, j-1, 0x01);

    if (idx != 1 && ((mat[i][j] & (idx >> 1))))
        dfs(i, j, idx >> 1);
    if (idx != 0x80 && (mat[i][j] & (idx << 1)))
        dfs(i, j, idx << 1);
    if (i > 0 && (mat[i-1][j] & idx))
        dfs(i-1, j, idx);
    if (i < N && (mat[i+1][j] & idx))
        dfs(i+1, j, idx);
}

ull solution() {
    ull ans = 0;
    if (K % 8) K = (K >> 3) + 1;
    else K >>= 3;
    for (int i = 0; i < N; ++i) {
        for (int j = 0; j < K; ++j) {
            unsigned char idx = 0x80;
            while (idx != 0) {
                if ((mat[i][j] & idx)) {
                    dfs(i, j, idx);
                    ans += 1;
                }
                idx >>= 1;
            }
        }
    }
    return ans;
}

int main() {
    // freopen("in.txt", "r", stdin);
    scanf("%d%d", &N, &M);
    for (int i = 0; i < N; ++i) {
        scanf("%s", h);
        int l = M / 4;
        int c = 0;
        for (int j = 0; j < l; j += 2)
            mat[i][c++] = get_num(j, l);
    }
    printf("%llu", solution());
    return 0;
}


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

using ll = long long;
using ull = unsigned long long;

constexpr int MOD = 1e9 + 7;
constexpr int MAXN = 1024 * 4 + 4;

int N, M, K, Q;
char h[2050];
unsigned char mat[MAXN][1024 * 2 + 2];

unsigned char get_num(int i, int len) {
    unsigned char num = 0;
    if (isdigit(h[i])) {
        num = (h[i] - '0');
    } else {
        num = (h[i] - 'A' + 10);
    }
    num *= 16;
    ++i;
    if (i < len) {
        if (isdigit(h[i])) {
            num += (h[i] - '0');
        } else {
            num += (h[i] - 'A' + 10);
        }
    }
    return num;
}

void dfs(int i, int j, unsigned char idx) {
    mat[i][j] &= ~idx;
    if (j < K && idx == 1 && (mat[i][j+1] & 0x80))
        dfs(i, j+1, 0x80);
    if (j > 0 && idx == 0x80 && (mat[i][j-1] & 0x01))
        dfs(i, j-1, 0x01);

    if (idx != 1 && ((mat[i][j] & (idx >> 1))))
        dfs(i, j, idx >> 1);
    if (idx != 0x80 && (mat[i][j] & (idx << 1)))
        dfs(i, j, idx << 1);
    if (i > 0 && (mat[i-1][j] & idx))
        dfs(i-1, j, idx);
    if (i < N && (mat[i+1][j] & idx))
        dfs(i+1, j, idx);
}

ull solution() {
    ull ans = 0;
    if (M % 8) K = (M >> 3) + 1;
    else K = M >> 3;
    for (int i = 0; i < N; ++i) {
        for (int j = 0; j < K; ++j) {
            unsigned char idx = 0x80;
            while (idx != 0) {
                if ((mat[i][j] & idx)) {
                    dfs(i, j, idx);
                    ans += 1;
                }
                idx >>= 1;
            }
        }
    }
    return ans;
}

int main() {
    // freopen("in.txt", "r", stdin);
    scanf("%d%d", &N, &M);
    for (int i = 0; i < N; ++i) {
        scanf("%s", h);
        int l = M / 4;
        int c = 0;
        for (int j = 0; j < l; j += 2)
            mat[i][c++] = get_num(j, l);
    }
    printf("%llu", solution());
    return 0;
}


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

#define ll long long
#define vi vector<int>
#define pb push_back
#define F first
#define S second
#define sd(x) scanf("%d", &(x))
#define print(s) cerr<<#s<<" : ";for(auto i:(s))cerr<<i<<" ";cerr<<"\n";

const int N = (1 << 26);
bitset<N> present;
int n, m;
inline int node(int a, int b){
	return (a << 14) + b;
}

int par[1 << 14], storepar[1 << 14];

int root(int x){
	return par[x] == x ? x : (par[x] = root(par[x]));
}

void merge(int x, int y){
	x = root(x), y = root(y);
	if(x > y) swap(x, y);
	if(x != y) par[x] = y;
}
char s[1 << 14];

inline int get(char x){
	for(int i = 0; i < 6; i++)
		if(x == 'A' + i)
			return i + 10;
	return x - '0';
}
int main(){
	int v, ans = 0;
	scanf("%d %d", &n, &m);
	for(int i = 0; i < n; i++){
		scanf("%s", s);
		for(int j = 0; j < m; j += 4){
			v = get(s[j >> 2]);
			for(int k = j + 3; k >= j; k--){
				present[node(i, k)] = v & 1;
				v >>= 1;
			}
		}
	}

	/*for(int i = 0; i < n; i++){
		for(int j = 0; j < m; j++){
			cerr << present[node(i, j)];
		}cerr << endl;
	}*/
	for(int i = 0; i < 2 * n; i++)
		par[i] = i;

	for(int j = 0; j < m; j++){
		if(j){
			for(int i = n; i < 2 * n; i++){
				storepar[i - n] = root(par[i]) - n;
			}
			for(int i = 0; i < n; i++){
				par[i] = storepar[i];
				assert(par[i] >= 0);
				par[n + i] = n + i;
			}
		}
		for(int i = 0; i < n; i++){
			if(!present[node(i, j)])
				continue;
			if(i < n - 1 && present[node(i + 1, j)]){
				merge(n + i, n + i + 1);
			}
			if(j != 0 && present[node(i, j - 1)]){
				merge(n + i, i);
			}
		}

		if(j){
			for(int i = 0; i < n; i++)
				if(par[i] == i && present[node(i, j - 1)]){
					cerr << i << endl;
					ans++;
				}
		}
		// if(j == 3)cerr << j << " "  << ans << " " << root(2) << " " << root(7) << " " << root(5) << endl;
	}

	for(int i = 0; i < n; i++){
		if(par[n + i] == n + i && present[node(i, m - 1)]){
			// cerr << i << " " << present[node(0, 3)] << endl;
			ans++;
		}
	}

	printf("%d\n", ans);
}


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

#define ll long long
#define vi vector<int>
#define pb push_back
#define F first
#define S second
#define sd(x) scanf("%d", &(x))
#define print(s) cerr<<#s<<" : ";for(auto i:(s))cerr<<i<<" ";cerr<<"\n";

const int N = (1 << 26);
bitset<N> present;
int n, m;
inline int node(int a, int b){
	return (a << 14) + b;
}

int par[1 << 14], storepar[1 << 14];

int root(int x){
	return par[x] == x ? x : (par[x] = root(par[x]));
}

void merge(int x, int y){
	x = par[x], y = par[y];
	if(x > y) swap(x, y);
	if(x != y) par[x] = y;
}
char s[1 << 14];

inline int get(char x){
	for(int i = 0; i < 6; i++)
		if(x == 'A' + i)
			return i + 10;
	return x - '0';
}
int main(){
	int v, ans = 0;
	scanf("%d %d", &n, &m);
	for(int i = 0; i < n; i++){
		scanf("%s", s);
		for(int j = 0; j < m; j += 4){
			v = get(s[j >> 2]);
			for(int k = j + 3; k >= j; k--){
				present[node(i, k)] = v & 1;
				v >>= 1;
			}
		}
	}

	/*for(int i = 0; i < n; i++){
		for(int j = 0; j < m; j++){
			cerr << present[node(i, j)];
		}cerr << endl;
	}*/
	for(int i = 0; i < 2 * n; i++)
		par[i] = i;

	for(int j = 0; j < m; j++){
		if(j){
			for(int i = n; i < 2 * n; i++){
				storepar[i - n] = root(par[i]) - n;
			}
			for(int i = 0; i < n; i++){
				par[i] = storepar[i];
				par[n + i] = n + i;
			}
		}
		for(int i = 0; i < n; i++){
			if(!present[node(i, j)])
				continue;
			if(i < n - 1 && present[node(i + 1, j)]){
				merge(n + i, n + i + 1);
			}
			if(j != 0 && present[node(i, j - 1)])
				merge(n + i, i);
		}

		if(j){
			for(int i = 0; i < n; i++)
				if(par[i] == i && present[node(i, j - 1)])
					ans++;
		}
		// cerr << j << " "  << ans << endl;
	}

	for(int i = 0; i < n; i++){
		if(par[n + i] == n + i && present[node(i, m - 1)]){
			// cerr << i << " " << present[node(0, 3)] << endl;
			ans++;
		}
	}

	printf("%d\n", ans);
}


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

#define ll long long
#define vi vector<int>
#define pb push_back
#define F first
#define S second
#define sd(x) scanf("%d", &(x))
#define print(s) cerr<<#s<<" : ";for(auto i:(s))cerr<<i<<" ";cerr<<"\n";

const int N = (1 << 26);
bitset<N> present;
int n, m;
inline int node(int a, int b){
	return (a << 14) + b;
}

int par[1 << 13];

int root(int x){
	return par[x] == x ? x : (par[x] = root(par[x]));
}

void merge(int x, int y){
	x = par[x], y = par[y];
	if(x > y) swap(x, y);
	if(x != y) par[x] = y;
}
char s[1 << 14];

inline int get(char x){
	for(int i = 0; i < 6; i++)
		if(x == 'A' + i)
			return i + 10;
	return x - '0';
}
int main(){
	int v, ans = 0;
	scanf("%d %d", &n, &m);
	for(int i = 0; i < n; i++){
		scanf("%s", s);
		for(int j = 0; j < m; j += 4){
			v = get(s[j >> 2]);
			for(int k = j + 3; k >= j; k--){
				present[node(i, k)] = v & 1;
				v >>= 1;
			}
		}
	}

	/*for(int i = 0; i < n; i++){
		for(int j = 0; j < m; j++){
			cerr << present[node(i, j)];
		}cerr << endl;
	}*/
	for(int i = 0; i < 2 * n; i++)
		par[i] = i;

	for(int j = 0; j < m; j++){
		for(int i = 0; i < n; i++){
			par[i] = par[n + i] - n;
			par[n + i] = n + i;
			// cerr << par[i] << " ";
		}
		// cerr << endl;
		for(int i = 0; i < n; i++){
			if(!present[node(i, j)])
				continue;
			if(i < n - 1 && present[node(i + 1, j)]){
				// cerr << "merging " << i << " " << i + 1 << endl;
				merge(n + i, n + i + 1);
			}
			if(j != 0 && present[node(i, j - 1)])
				merge(n + i, i);
		}

		if(j){
			for(int i = 0; i < n; i++)
				if(par[i] == i && present[node(i, j - 1)])
					ans++;
		}
		// cerr << "yes " << j << " " << ans << endl;
	}

	for(int i = 0; i < n; i++)
		if(par[n + i] == n + i && present[node(i, n - 1)])
			ans++;

	printf("%d\n", ans);
}


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

#define ll long long
#define vi vector<int>
#define pb push_back
#define F first
#define S second
#define sd(x) scanf("%d", &(x))
#define print(s) cerr<<#s<<" : ";for(auto i:(s))cerr<<i<<" ";cerr<<"\n";

const int N = (1 << 26);
bitset<N> present;
int n, m;
inline int node(int a, int b){
	return (a << 14) + b;
}

int par[1 << 14];

int root(int x){
	return par[x] == x ? x : (par[x] = root(par[x]));
}

void merge(int x, int y){
	x = root(x), y = root(y);
	if(x > y) swap(x, y);
	if(x != y) par[x] = y;
}

char s[1 << 14];

inline int get(char x){
	if(x >= 'A') return x - 'A' + 10;
	return x - '0';

}

bool valid1[1 << 12], valid2[1 << 12];
void load(int j){
	memcpy(valid2, valid1, sizeof valid1);
	for(int i = 0; i < n; i++)
		valid1[i] = present[node(i, j)];
}

int main(){
	int v, ans = 0;
	scanf("%d %d", &n, &m);
	for(int i = 0; i < n; i++){
		scanf("%s", s);
		for(int j = 0; j < m; j += 4){
			v = get(s[j >> 2]);
			for(int k = j + 3; k >= j; k--){
				present[node(i, k)] = v & 1;
				v >>= 1;
			}
		}
	}
	for(int i = 0; i < 2 * n; i++)
		par[i] = i;

	for(int j = 0; j < m; j++){
		load(j);
		if(j){
			for(int i = 0; i < n; i++){
				par[i] = root(par[i + n]) - n;
				par[n + i] = n + i;
			}
		}
		for(int i = 0; i < n; i++){
			if(!valid1[i])
				continue;
			if(i < n - 1 && valid1[i + 1]){
				merge(n + i, n + i + 1);
			}
			if(j != 0 && valid2[i]){
				merge(n + i, i);
			}
		}

		if(j){
			for(int i = 0; i < n; i++)
				if(par[i] == i && valid2[i]){
					ans++;
				}
		}
	}

	for(int i = 0; i < n; i++){
		if(par[n + i] == n + i && present[node(i, m - 1)]){
			ans++;
		}
	}

	printf("%d\n", ans);
}


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

#define ll long long
#define vi vector<int>
#define pb push_back
#define F first
#define S second
#define sd(x) scanf("%d", &(x))
#define print(s) cerr<<#s<<" : ";for(auto i:(s))cerr<<i<<" ";cerr<<"\n";

const int N = (1 << 26);
bitset<N> present;
int n, m;
inline int node(int a, int b){
	return (a << 14) + b;
}

int par[1 << 13];

int root(int x){
	return par[x] == x ? x : (par[x] = root(par[x]));
}

void merge(int x, int y){
	x = par[x], y = par[y];
	if(x > y) swap(x, y);
	if(x != y) par[x] = y;
}
char s[1 << 14];

inline int get(char x){
	for(int i = 0; i < 6; i++)
		if(x == 'A' + i)
			return i + 10;
	return x - '0';
}
int main(){
	int v, ans = 0;
	scanf("%d %d", &n, &m);
	for(int i = 0; i < n; i++){
		scanf("%s", s);
		for(int j = 0; j < m; j += 4){
			v = get(s[j >> 2]);
			for(int k = j + 3; k >= j; k--){
				present[node(i, k)] = v & 1;
				v >>= 1;
			}
		}
	}

	for(int i = 0; i < n; i++){
		for(int j = 0; j < m; j++){
			cerr << present[node(i, j)];
		}cerr << endl;
	}
	for(int i = 0; i < 2 * n; i++)
		par[i] = i;

	for(int j = 0; j < m; j++){
		for(int i = 0; i < n; i++){
			par[i] = par[n + i] - n;
			par[n + i] = n + i;
		}
		for(int i = 0; i < n; i++){
			if(!present[node(i, j)])
				continue;
			if(i < n - 1 && present[node(i + 1, j)]){
				merge(n + i, n + i + 1);
			}
			if(j != 0 && present[node(i, j - 1)])
				merge(n + i, i);
		}

		if(j){
			for(int i = 0; i < n; i++)
				if(par[i] == i && present[node(i, j - 1)])
					ans++;
		}
		// cerr << j << " "  << ans << endl;
	}

	for(int i = 0; i < n; i++){
		if(par[n + i] == n + i && present[node(i, m - 1)]){
			// cerr << i << " " << present[node(0, 3)] << endl;
			ans++;
		}
	}

	printf("%d\n", ans);
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define f(i, x, n) for(int i = x; i < (int)(n); ++i)

char in[1 << 12 | 1];
bitset<1 << 14> g[1 << 12];
int dx[4] = { 0, 1, -1, 0 }, dy[4] = { 1, 0, 0, -1 }, n, m;

inline int id(char c){
	if (c >= '0' && c <= '9')return c - '0';
	return 10 + c - 'A';
}

void go(int x, int y){
	queue<pair<int, int> > q;
	q.push(make_pair(x, y));
	g[x][y] = false;
	while (!q.empty()){
		x = q.front().first, y = q.front().second;
		q.pop();
		f(i, 0, 4){
			int a = x + dx[i], b = y + dy[i];
			if (a == -1 || a == n || b == -1 || b == m || !g[a][b])continue;
			g[a][b] = false;
			q.push(make_pair(a, b));
		}
	}
}

int main(){
	scanf("%d%d", &n, &m);
	f(i, 0, n){
		scanf("%s", in);
		f(j, 0, m >> 2){
			int c = id(in[j]);
			for (int k = 3; k >= 0; --k)if (c >> k & 1)g[i][j << 2 | (3 - k)] = true;
		}
	}
	int an = 0;
	f(i, 0, n)f(j, 0, m)if (g[i][j])++an, go(i, j);
	printf("%d\n", an);
}


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

//https://codeforces.com/contest/884/problem/E

int n, m;
string s, A;

void dfs(vector<string>& grid, int i, int j, int n, int m)
{
	if (grid[i][j] == '0') {
		//cout << "abf"<<endl;
		return;
	}
	grid[i][j] = '0';
	if (i + 1 < n) dfs(grid, i + 1, j, n, m);
	if (j + 1 < m) dfs(grid, i, j + 1, n, m);
	if (i - 1 >= 0) dfs(grid, i - 1, j, n, m);
	if (j - 1 >= 0) dfs(grid, i, j - 1, n, m);
}

int countIsland(vector<string>& grid)
{
	int ans = 0;
	int n = grid.size();
	int m = grid[0].size();

	for (int i = 0; i < n; i++)
		for (int j = 0; j < m; j++)
			if (grid[i][j] == '1') {
				ans++;
				dfs(grid, i, j, n, m);
			}
	return ans;
}

int main() {
	ios::sync_with_stdio(0); cin.tie(0);
	cin >> n >> m;
	vector<string> ss;

	for (int k = 0; k < n; k++) {
		//fflush(stdin);
		cin >> s;
		A = "";
		for (int j = 0; j < m / 4; j++)
		{
			int t = s[j] >= 'A' ? s[j] - 'A' + 10 : s[j] - '0';//doi s[j] ra so thap phan
			for (int i = 8; i; i /= 2)// doi t ra day nhi phan
				A += (t & i) > 0 ? '1' : '0';
		}
		ss.push_back(A);
	}

	cout << countIsland(ss);

}


#include <iostream>
using namespace std;

int n, m;
string s, A, B;
int d[1 << 15];
int ans;

int get(int v) {
	return d[v] == v ? v : d[v] = get(d[v]);
}
int mrg(int v, int u) {
	v = get(v), u = get(u);
	if (v == u) return 0;
	d[u] = v;
	return 1;
}
void solve() {
	cin >> n >> m;
	for (int i = m - 1; i >= 0; i--)B += '0';
	for (int i = m * 2 - 1; i >= 0; i--) d[i] = i;
	int x = 0, y = 1;
	for (int k = 0; k < n; k++) {

		cin >> s;
		A = "";
		for (int j = 0; j < m / 4; j++)
		{
			int t = s[j] >= 'A' ? s[j] - 'A' + 10 : s[j] - '0';//doi s[j] ra so thap phan
			for (int i = 8; i; i /= 2)// doi x ra day nhi phan
				A += char('0' + ((t & i) > 0));
		}
		swap(x, y);
		for (int j = m; j--;)
			if (A[j] - '0') {
				ans++;
				if (B[j] - '0')
					ans -= mrg(2 * j + x, 2 * j + y);
				if (j && (A[j - 1] - '0'))
					ans -= mrg(2 * j + x, 2 * j + x - 2);
			}
		for (int j = m; j--;)
			d[2 * j + y] = 2 * j + y;
		B = A;
	}
	cout << ans;
}

int main() {
	solve();

	return 0;
}


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

//https://codeforces.com/contest/884/problem/E
int n, m;
string s, A, B;
int d[1 << 15];
int ans;

int get(int v) {
	return d[v] == v ? v : d[v] = get(d[v]);
}
int mrg(int v, int u) {
	v = get(v), u = get(u);
	if (v == u) return 0;
	return d[u] = v,1;
}

int main() {
	ios::sync_with_stdio(0); cin.tie(0);
	cin >> n >> m;
	for (int i = m - 1; i >= 0; i--)B += '0';
	for (int i = m * 2 - 1; i >= 0; i--) d[i] = i;
	int x = 0, y = 1;
	for (int k = 0; k < n; k++) {

		cin >> s;
		A = "";
		for (int j = 0; j < m / 4; j++)
		{
			int t = s[j] >= 'A' ? s[j] - 'A' + 10 : s[j] - '0';//doi s[j] ra so thap phan
			for (int i = 8; i; i /= 2)// doi x ra day nhi phan
				A += char('0' + ((t & i) > 0));
		}
		swap(x, y);
		for (int j = m; j--;)
			if (A[j] - '0') {
				ans++;
				if (B[j] - '0')
					ans -= mrg(2 * j + x, 2 * j + y);
				if (j && (A[j - 1] - '0'))
					ans -= mrg(2 * j + x, 2 * j + x - 2);
			}
		for (int j = m; j--;)
			d[2 * j + y] = 2 * j + y;
		B = A;
	}
	cout << ans;

	return 0;
}


#include <iostream>
#include <vector>
#include <string>
#include <cmath>
#include <map>
#include <queue>
#include <unordered_set>
#include <unordered_map>
#include <array>
using namespace std;

//https://codeforces.com/contest/884/problem/E

int n, m;
string s, A;

void dfs(vector<string>& grid, int i, int j, int n, int m)
{
	if (grid[i][j] == '0') {
		//cout << "abf"<<endl;
		return;
	}
	grid[i][j] == '0';
	if (i + 1 < n) dfs(grid, i + 1, j, n, m);
	if (j + 1 < m) dfs(grid, i, j + 1, n, m);
	if (i - 1 >= 0) dfs(grid, i - 1, j, n, m);
	if (j - 1 >= 0) dfs(grid, i, j - 1, n, m);
}

int countIsland(vector<string> grid)
{
	int ans = 0;
	int n = grid.size();
	int m = grid[0].size();

	for (int i = 0; i < n; i++)
		for (int j = 0; j < m; j++)
			if (grid[i][j] == '1') {
				ans++;
				dfs(grid, i, j, n, m);
			}
	return ans;
}

int main() {
	ios::sync_with_stdio(0); cin.tie(0);
	cin >> n >> m;
	vector<string> ss;

	for (int k = 0; k < n; k++) {
		//fflush(stdin);
		cin >> s;
		A = "";
		for (int j = 0; j < m / 4; j++)
		{
			int t = s[j] >= 'A' ? s[j] - 'A' + 10 : s[j] - '0';//doi s[j] ra so thap phan
			for (int i = 8; i; i /= 2)// doi t ra day nhi phan
				A += (t & i) > 0 ? '1' : '0';
		}
		ss.push_back(A);
	}
	for (int i = 0; i < ss.size(); i++) {
		for (int j = 0; j < ss[0].size(); j++) {
			cout << ss[i][j];
		}
		cout << endl;
	}

	cout << countIsland(ss);

}


#include <iostream>
using namespace std;

//https://codeforces.com/contest/884/problem/E
int n, m;
string s, A, B;
int d[1 << 15];
int ans;

int get(int v) {
	return d[v] < 0 ? v : d[v] = get(d[v]);
}
int mrg(int v, int u) {
	v = get(v), u = get(u);
	if (v == u) return 0;
	//if (d[v] > d[u])swap(v, u);//neu so dinh cua cay goc u > goc v
	d[v] += d[u];
	d[u] = v;
	return 1;
}

int main() {
	ios::sync_with_stdio(0); cin.tie(0);
	cin >> n >> m;
	for (int i = m - 1; i >= 0; i--)B += '0';
	for (int i = m * 2 - 1; i >= 0; i--) d[i] = -1;

	int x = 0, y = 1;
	for (int k = 0; k < n; k++) {
		//fflush(stdin);
		cin >> s;
		A = "";
		for (int j = 0; j < m / 4; j++)
		{
			int t = s[j] >= 'A' ? s[j] - 'A' + 10 : s[j] - '0';//doi s[j] ra so thap phan
			for (int i = 8; i; i /= 2)// doi t ra day nhi phan
				A += char('0' + ((t & i) > 0));
		}
		swap(x, y);
		for (int j = m; j--;)
			if (A[j] - '0') {
				ans++;
				if (B[j] - '0')
					ans -= mrg(2 * j + x, 2 * j + y);
				if (j && (A[j - 1] - '0'))
					ans -= mrg(2 * j + x, 2 * j + x - 2);
			}
		for (int j = m; j--;)
			d[2 * j + y] = -1;
		B = A;
	}
	cout << ans;

}


#include <iostream>
using namespace std;

//https://codeforces.com/contest/884/problem/E
int n, m;
string s, A, B;
int d[1 << 15];
int ans;

int get(int v) {
	return d[v] == v ? v : d[v] = get(d[v]);
}
int mrg(int v, int u) {
	v = get(v), u = get(u);
	if (v == u) return 0;
	return d[u] = v,1;
}
void solve() {
	cin >> n >> m;
	for (int i = m - 1; i >= 0; i--)B += '0';
	for (int i = m * 2 - 1; i >= 0; i--) d[i] = i;
	int x = 0, y = 1;
	for (int k = 0; k < n; k++) {

		cin >> s;
		A = "";
		for (int j = 0; j < m / 4; j++)
		{
			int t = s[j] >= 'A' ? s[j] - 'A' + 10 : s[j] - '0';//doi s[j] ra so thap phan
			for (int i = 8; i; i /= 2)// doi x ra day nhi phan
				A += char('0' + ((t & i) > 0));
		}
		swap(x, y);
		for (int j = m; j--;)
			if (A[j] - '0') {
				ans++;
				if (B[j] - '0')
					ans -= mrg(2 * j + x, 2 * j + y);
				if (j && (A[j - 1] - '0'))
					ans -= mrg(2 * j + x, 2 * j + x - 2);
			}
		for (int j = m; j--;)
			d[2 * j + y] = 2 * j + y;
		B = A;
	}
	cout << ans;
}

int main() {
	solve();

	return 0;
}


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

//https://codeforces.com/contest/884/problem/E
int n, m;
string s, A, B;
int d[1 << 15];
int ans;

int get(int v) {
	return d[v] < 0 ? v : d[v] = get(d[v]);
}
int mrg(int v, int u) {
	v = get(v), u = get(u);
	if (v == u) return 0;
	d[v] += d[u];
	d[u] = v;
	return 1;
}

int main() {
	ios::sync_with_stdio(0); cin.tie(0);
	cin >> n >> m;
	for (int i = m - 1; i >= 0; i--)B += '0';
	for (int i = m * 2 - 1; i >= 0; i--) d[i] = -1;

	int x = 0, y = 1;
	for (int k = 0; k < n; k++) {
		//fflush(stdin);
		cin >> s;
		A = "";
		for (int j = 0; j < m / 4; j++)
		{
			int t = s[j] >= 'A' ? s[j] - 'A' + 10 : s[j] - '0';//doi s[j] ra so thap phan
			for (int i = 8; i; i /= 2)// doi x ra day nhi phan
				A += char('0' + ((t & i) > 0));
		}
		swap(x, y);
		for (int j = m; j--;)
			if (A[j] - '0') {
				ans++;
				if (B[j] - '0')
					ans -= mrg(2 * j + x, 2 * j + y);
				if (j && (A[j - 1] - '0'))
					ans -= mrg(2 * j + x, 2 * j + x - 2);
			}
		for (int j = m; j--;)
			d[2 * j + y] = -1;
		B = A;
	}
	cout << ans;

}


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

//https://codeforces.com/contest/884/problem/E
int n, m;
string s, A, B;
int d[1 << 15];
int ans;

int get(int v) {
	return d[v] < 0 ? v : d[v] = get(d[v]);
}
int mrg(int v, int u) {
	v = get(v), u = get(u);
	if (v == u) return 0;
	if (d[v] > d[u])swap(v, u);//neu so dinh cua cay goc u > goc v
	d[v] += d[u];
	d[u] = v;
	return 1;
}

int main() {
	ios::sync_with_stdio(0); cin.tie(0);
	cin >> n >> m;
	for (int i = m - 1; i >= 0; i--)B += '0';
	for (int i = m * 2 - 1; i >= 0; i--) d[i] = -1;

	int x = 0, y = 1;
	for (int k = 0; k < n; k++) {
		//fflush(stdin);
		cin >> s;
		A = "";
		for (int j = 0; j < m / 4; j++)
		{
			int t = s[j] >= 'A' ? s[j] - 'A' + 10 : s[j] - '0';//doi s[j] ra so thap phan
			for (int i = 8; i; i /= 2)// doi x ra day nhi phan
				A += char('0' + ((t & i) > 0));
		}
		swap(x, y);
		for (int j = m; j--;)
			if (A[j] - '0') {
				ans++;
				if (B[j] - '0')
					ans -= mrg(2 * j + x, 2 * j + y);
				if (j && (A[j - 1] - '0'))
					ans -= mrg(2 * j + x, 2 * j + x - 2);
			}
		for (int j = m; j--;)
			d[2 * j + y] = -1;
		B = A;
	}
	cout << ans;

}


#include <iostream>
using namespace std;
int n, m;
string s, A, B;
int d[1 << 15];
int ans;

int get(int v) {
	return d[v] == v ? v : d[v] = get(d[v]);
}
int mrg(int v, int u) {
	v = get(v), u = get(u);
	if (v == u) return 0;
	return d[u] = v, 1;
}

int main() {

	cin >> n >> m;
	for (int i = m - 1; i >= 0; i--)B += '0';
	for (int i = m * 2 - 1; i >= 0; i--) d[i] = i;
	int x = 0, y = 1;
	for (int k = 0; k < n; B = A, k++) {
		fflush(stdin);
		cin >> s;
		A = "";
		for (int j = 0; j < m / 4; j++)
		{
			int x = s[j] >= 'A' ? s[j] - 'A' + 10 : s[j] - '0';//doi s[j] ra so thap phan
			for (int i = 8; i; i /= 2)// doi x ra day nhi phan
				A += char('0' + ((x & i) > 0));
		}
		swap(x, y);
		for (int j = m; j--;)
			if (A[j] - '0') {
				ans++;
				if (B[j] - '0')
					ans -= mrg(2 * j + x, 2 * j + y);
				if (j and A[j - 1] - '0')
					ans -= mrg(2 * j + x, 2 * j + x - 2);
			}
		for (int j = m; j--;)
			d[2 * j + y] = 2 * j + y;
	}
	cout << ans;
}


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

//https://codeforces.com/contest/884/problem/E
int n, m;
string s, A, B;
int d[1 << 15];
int ans;

int get(int v) {
	return d[v] < 0 ? v : d[v] = get(d[v]);
}
int mrg(int v, int u) {
	v = get(v), u = get(u);
	if (v == u) return 0;

	d[v] += d[u];
	d[u] = v;

	return 1;
}

int main() {
	ios::sync_with_stdio(0); cin.tie(0);
	cin >> n >> m;
	for (int i = m - 1; i >= 0; i--)B += '0';
	for (int i = m * 2 - 1; i >= 0; i--) d[i] = -1;

	int x = 0, y = 1;
	for (int k = 0; k < n; k++) {
		//fflush(stdin);
		cin >> s;
		A = "";
		for (int j = 0; j < m / 4; j++)
		{
			int t = s[j] >= 'A' ? s[j] - 'A' + 10 : s[j] - '0';//doi s[j] ra so thap phan
			for (int i = 8; i; i /= 2)// doi t ra day nhi phan
				A += (t & i) > 0 ? '1' : '0';
		}
		swap(x, y);
		for (int j = m; j--;)
			if (A[j] - '0') {
				ans++;
				if (B[j] - '0')
					ans -= mrg(2 * j + x, 2 * j + y);
				if (j && (A[j - 1] - '0'))
					ans -= mrg(2 * j + x, 2 * j + x - 2);
			}
		for (int j = m; j--;)
			d[2 * j + y] = -1;
		B = A;
	}
	cout << ans;

}


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

//https://codeforces.com/contest/884/problem/E
int n, m;
string s, A, B;
int d[1 << 15];
int ans;

int get(int v) {
	return d[v] < 0 ? v : d[v] = get(d[v]);
}
int mrg(int v, int u) {
	v = get(v), u = get(u);
	if (v == u) return 0;
	if (d[v] < d[u])
	{
		d[v] += d[u];
		d[u] = v;
	}
	else {
		d[u] += d[v];
		d[v] = u;
	}
	return 1;
}

int main() {
	ios::sync_with_stdio(0); cin.tie(0);
	cin >> n >> m;
	for (int i = m - 1; i >= 0; i--)B += '0';
	for (int i = m * 2 - 1; i >= 0; i--) d[i] = -1;

	int x = 0, y = 1;
	for (int k = 0; k < n; k++) {
		//fflush(stdin);
		cin >> s;
		A = "";
		for (int j = 0; j < m / 4; j++)
		{
			int t = s[j] >= 'A' ? s[j] - 'A' + 10 : s[j] - '0';//doi s[j] ra so thap phan
			for (int i = 8; i; i /= 2)// doi x ra day nhi phan
				A += char('0' + ((t & i) > 0));
		}
		swap(x, y);
		for (int j = m; j--;)
			if (A[j] - '0') {
				ans++;
				if (B[j] - '0')
					ans -= mrg(2 * j + x, 2 * j + y);
				if (j && (A[j - 1] - '0'))
					ans -= mrg(2 * j + x, 2 * j + x - 2);
			}
		for (int j = m; j--;)
			d[2 * j + y] = -1;
		B = A;
	}
	cout << ans;

}


#include <iostream>
#include <vector>
#include <string>
#include <cmath>
#include <map>
#include <queue>
#include <unordered_set>
#include <unordered_map>
#include <array>
using namespace std;

//https://codeforces.com/contest/884/problem/E
int n, m;
string s, A, B;
int d[1 << 15];
int ans;

int get(int v) {
	return d[v] < 0 ? v : d[v] = get(d[v]);
}
int mrg(int v, int u) {
	v = get(v), u = get(u);
	if (v == u) return 0;

	d[v] += d[u];
	d[u] = v;

	return 1;
}

int main() {
	ios::sync_with_stdio(0); cin.tie(0);
	cin >> n >> m;
	for (int i = m - 1; i >= 0; i--)B += '0';
	for (int i = m * 2 - 1; i >= 0; i--) d[i] = -1;

	int x = 0, y = 1;
	for (int k = 0; k < n; k++) {
		//fflush(stdin);
		cin >> s;
		A = "";
		for (int j = 0; j < m / 4; j++)
		{
			int t = s[j] >= 'A' ? s[j] - 'A' + 10 : s[j] - '0';//doi s[j] ra so thap phan
			for (int i = 8; i; i /= 2)// doi t ra day nhi phan
				A = (t & i) > 0 ? '0' : '1';
		}
		swap(x, y);
		for (int j = m; j--;)
			if (A[j] - '0') {
				ans++;
				if (B[j] - '0')
					ans -= mrg(2 * j + x, 2 * j + y);
				if (j && (A[j - 1] - '0'))
					ans -= mrg(2 * j + x, 2 * j + x - 2);
			}
		for (int j = m; j--;)
			d[2 * j + y] = -1;
		B = A;
	}
	cout << ans;

}


#include <iostream>
#include <array>
using namespace std;

int n, m;
string s, A, B;
int d[1 << 15];
int ans;

int get(int v) {
	return d[v] == v ? v : d[v] = get(d[v]);
}
int mrg(int v, int u) {
	v = get(v), u = get(u);
	if (v == u) return 0;
	d[u] = v;
	return 1;
}
void solve() {
	cin >> n >> m;
	for (int i = m - 1; i >= 0; i--)B += '0';
	for (int i = m * 2 - 1; i >= 0; i--) d[i] = i;
	int x = 0, y = 1;
	for (int k = 0; k < n; k++) {
		cin >> s;
		A = "";
		for (int j = 0; j < m / 4; j++)
		{
			int x = s[j] >= 'A' ? s[j] - 'A' + 10 : s[j] - '0';//doi s[j] ra so thap phan
			for (int i = 8; i; i /= 2)// doi x ra day nhi phan
				A += char('0' + ((x & i) > 0));
		}
		swap(x, y);
		for (int j = m; j--;)
			if (A[j] - '0') {
				ans++;
				if (B[j] - '0')
					ans -= mrg(2 * j + x, 2 * j + y);
				if (j && (A[j - 1] - '0'))
					ans -= mrg(2 * j + x, 2 * j + x - 2);
			}
		for (int j = m; j--;)
			d[2 * j + y] = 2 * j + y;
		B = A;
	}
	cout << ans;
}

int main() {
	solve();

	return 0;
}


int n, m;
string s, A, B;
int d[1 << 15];
int ans;

int get(int v) {
	return d[v] == v ? v : d[v] = get(d[v]);
}
int mrg(int v, int u) {
	v = get(v), u = get(u);
	if (v == u) return 0;
	return d[u] = v, 1;
}

int main() {

	cin >> n >> m;
	for (int i = m - 1; i >= 0; i--)B += '0';
	for (int i = m * 2 - 1; i >= 0; i--) d[i] = i;
	int x = 0, y = 1;
	for (int k = 0; k < n; B = A, k++) {
		fflush(stdin);
		cin >> s;
		A = "";
		for (int j = 0; j < m / 4; j++)
		{
			int x = s[j] >= 'A' ? s[j] - 'A' + 10 : s[j] - '0';//doi s[j] ra so thap phan
			for (int i = 8; i; i /= 2)// doi x ra day nhi phan
				A += char('0' + ((x & i) > 0));
		}
		swap(x, y);
		for (int j = m; j--;)
			if (A[j] - '0') {
				ans++;
				if (B[j] - '0')
					ans -= mrg(2 * j + x, 2 * j + y);
				if (j and A[j - 1] - '0')
					ans -= mrg(2 * j + x, 2 * j + x - 2);
			}
		for (int j = m; j--;)
			d[2 * j + y] = 2 * j + y;
	}
	cout << ans;
}


#include<bits/stdc++.h>

using namespace std;

int n,m;
string s,A,B;
int d[1<<15];
int ans;

int get(int v){
  return d[v]==v?v:d[v]=get(d[v]);
}
int mrg(int v,int u){
  v=get(v),u=get(u);
  if(v==u) return 0;
  return d[u]=v,1;
}

int main(){
  ios::sync_with_stdio(0);cin.tie(0);
  cin>>n>>m;
  for (int i = m - 1; i >= 0; i--)B += '0';
  for (int i = m * 2 - 1; i >= 0; i--) d[i] = i;
  for(int x=0,y=1;cin>>s;B=A){
    A="";
    for(int j=0;j<m/4;j++)
      {
	int x=s[j]>='A'?s[j]-'A'+10:s[j]-'0';
	for(int i=8;i;i/=2)
	  A+=char('0'+((x&i)>0));
      }
    swap(x,y);
    for(int j=m;j--;)
      if(A[j]-'0'){
	ans++;
	if(B[j]-'0')
	  ans-=mrg(2*j+x,2*j+y);
	if(j && (A[j-1]-'0'))
	  ans-=mrg(2*j+x,2*j+x-2);
      }
    for(int j=m;j--;)
      d[2*j+y]=2*j+y;
  }
  cout<<ans;
}


#include <iostream>
#include <array>
using namespace std;

int n, m;
string s, A, B;
int d[1 << 15];
int ans;

int get(int v) {
	return d[v] == v ? v : d[v] = get(d[v]);
}
int mrg(int v, int u) {
	v = get(v), u = get(u);
	if (v == u) return 0;
	d[u] = v;
	return 1;
}
void solve() {
	cin >> n >> m;
	for (int i = m - 1; i >= 0; i--)B += '0';
	for (int i = m * 2 - 1; i >= 0; i--) d[i] = i;
	int x = 0, y = 1;
	for (int k = 0; k < n; k++) {
		fflush(stdin);
		cin >> s;
		A = "";
		for (int j = 0; j < m / 4; j++)
		{
			int x = s[j] >= 'A' ? s[j] - 'A' + 10 : s[j] - '0';//doi s[j] ra so thap phan
			for (int i = 8; i; i /= 2)// doi x ra day nhi phan
				A += char('0' + ((x & i) > 0));
		}
		swap(x, y);
		for (int j = m; j--;)
			if (A[j] - '0') {
				ans++;
				if (B[j] - '0')
					ans -= mrg(2 * j + x, 2 * j + y);
				if (j && (A[j - 1] - '0'))
					ans -= mrg(2 * j + x, 2 * j + x - 2);
			}
		for (int j = m; j--;)
			d[2 * j + y] = 2 * j + y;
		B = A;
	}
	cout << ans;
}

int main() {
	solve();

	return 0;
}


int n, m;
string s, A, B;
int d[1 << 15];
int ans;

int get(int v) {
	return d[v] == v ? v : d[v] = get(d[v]);
}
int mrg(int v, int u) {
	v = get(v), u = get(u);
	if (v == u) return 0;
	d[u] = v;
	return 1;
}
void solve() {
	cin >> n >> m;
	for (int i = m - 1; i >= 0; i--)B += '0';
	for (int i = m * 2 - 1; i >= 0; i--) d[i] = i;
	int x = 0, y = 1;
	for (int k = 0; k < n; k++) {

		cin >> s;
		A = "";
		for (int j = 0; j < m / 4; j++)
		{
			int x = s[j] >= 'A' ? s[j] - 'A' + 10 : s[j] - '0';//doi s[j] ra so thap phan
			for (int i = 8; i; i /= 2)// doi x ra day nhi phan
				A += char('0' + ((x & i) > 0));
		}
		swap(x, y);
		for (int j = m; j--;)
			if (A[j] - '0') {
				ans++;
				if (B[j] - '0')
					ans -= mrg(2 * j + x, 2 * j + y);
				if (j && (A[j - 1] - '0'))
					ans -= mrg(2 * j + x, 2 * j + x - 2);
			}
		for (int j = m; j--;)
			d[2 * j + y] = 2 * j + y;
		B = A;
	}
	cout << ans;
}


#include<bits/stdc++.h>

using namespace std;

int n,m;
string s,A,B;
int d[1<<15];
int ans;

int get(int v){
  return d[v]==v?v:d[v]=get(d[v]);
}
int mrg(int v,int u){
  v=get(v),u=get(u);
  if(v==u) return 0;
  return d[u]=v,1;
}

int main(){
  ios::sync_with_stdio(0);cin.tie(0);
  cin>>n>>m;
  for (int i = m - 1; i >= 0; i--)B += '0';
  for (int i = m * 2 - 1; i >= 0; i--) d[i] = i;
  for(int x=0,y=1;cin>>s;B=A){
    A="";
    for(int j=0;j<m/4;j++)
      {
	int x=s[j]>='A'?s[j]-'A'+10:s[j]-'0';
	for(int i=8;i;i/=2)
	  A+=char('0'+((x&i)>0));
      }
    swap(x,y);
    for(int j=m;j--;)
      if(A[j]-'0'){
	ans++;
	if(B[j]-'0')
	  ans-=mrg(2*j+x,2*j+y);
	if(j and A[j-1]-'0')
	  ans-=mrg(2*j+x,2*j+x-2);
      }
    for(int j=m;j--;)
      d[2*j+y]=2*j+y;
  }
  cout<<ans;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <cmath>
#include <map>
#include <queue>
#include <unordered_set>
#include <unordered_map>
#include <array>
using namespace std;

//https://codeforces.com/contest/884/problem/E
int n, m;
string s, A, B;
int d[1 << 15];
int ans;

int get(int v) {
	return d[v] == v ? v : d[v] = get(d[v]);
}
int mrg(int v, int u) {
	v = get(v), u = get(u);
	if (v == u) return 0;
	d[u] = v;
	return 1;
}
void solve() {
	cin >> n >> m;
	for (int i = m - 1; i >= 0; i--)B += '0';
	for (int i = m * 2 - 1; i >= 0; i--) d[i] = i;
	int x = 0, y = 1;
	for (int k = 0; k < n; k++) {
		fflush(stdin);
		cin >> s;
		A = "";
		for (int j = 0; j < m / 4; j++)
		{
			int t = s[j] >= 'A' ? s[j] - 'A' + 10 : s[j] - '0';//doi s[j] ra so thap phan
			for (int i = 8; i; i /= 2)// doi x ra day nhi phan
				A += char('0' + ((t & i) > 0));
		}
		swap(x, y);
		for (int j = m; j--;)
			if (A[j] - '0') {
				ans++;
				if (B[j] - '0')
					ans -= mrg(2 * j + x, 2 * j + y);
				if (j && (A[j - 1] - '0'))
					ans -= mrg(2 * j + x, 2 * j + x - 2);
			}
		for (int j = m; j--;)
			d[2 * j + y] = 2 * j + y;
		B = A;
	}
	cout << ans;
}

int main() {
	solve();

	return 0;
}


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

//https://codeforces.com/contest/884/problem/E
int n, m;
string s, A, B;
int d[1 << 15];
int ans;

int get(int v) {
	return d[v] < 0 ? v : d[v] = get(d[v]);
}
int mrg(int v, int u) {
	v = get(v), u = get(u);
	if (v == u) return 0;

	d[v] += d[u];
	d[u] = v;

	return 1;
}

int main() {
	ios::sync_with_stdio(0); cin.tie(0);
	cin >> n >> m;
	for (int i = m - 1; i >= 0; i--)B += '0';
	for (int i = m * 2 - 1; i >= 0; i--) d[i] = -1;

	int x = 0, y = 1;
	for (int k = 0; k < n; k++) {
		//fflush(stdin);
		cin >> s;
		A = "";
		for (int j = 0; j < m / 4; j++)
		{
			int t = s[j] >= 'A' ? s[j] - 'A' + 10 : s[j] - '0';//doi s[j] ra so thap phan
			for (int i = 8; i; i /= 2)// doi t ra day nhi phan
				A = (t & i) > 0 ? '1' : '0';
		}
		swap(x, y);
		for (int j = m; j--;)
			if (A[j] - '0') {
				ans++;
				if (B[j] - '0')
					ans -= mrg(2 * j + x, 2 * j + y);
				if (j && (A[j - 1] - '0'))
					ans -= mrg(2 * j + x, 2 * j + x - 2);
			}
		for (int j = m; j--;)
			d[2 * j + y] = -1;
		B = A;
	}
	cout << ans;

}


#include<bits/stdc++.h>

using namespace std;

int n,m;
string s,A,B;
int d[1<<15];
int ans;

int get(int v){
  return d[v]==v?v:d[v]=get(d[v]);
}
int mrg(int v,int u){
  v=get(v),u=get(u);
  if(v==u) return 0;
  return d[u]=v,1;
}

int main(){
  ios::sync_with_stdio(0);cin.tie(0);
  cin>>n>>m;
  for (int i = m - 1; i >= 0; i--)B += '0';
  for (int i = m * 2 - 1; i >= 0; i--) d[i] = i;
  for(int x=0,y=1;cin>>s;B=A){
    A="";
    for(int j=0;j<m/4;j++)
      {
	int x=s[j]>='A'?s[j]-'A'+10:s[j]-'0';
	for(int i=8;i;i/=2)
	  A+=char('0'+((x&i)>0));
      }
    swap(x,y);
    for(int j=m;j--;)
      if(A[j]-'0'){
	ans++;
	if(B[j]-'0')
	  ans-=mrg(2*j+x,2*j+y);
	if(j && A[j-1]-'0')
	  ans-=mrg(2*j+x,2*j+x-2);
      }
    for(int j=m;j--;)
      d[2*j+y]=2*j+y;
  }
  cout<<ans;
}


#include <iostream>
using namespace std;

//https://codeforces.com/contest/884/problem/E
int n, m;
string s, A, B;
int d[1 << 15];
int ans;

int get(int v) {
	return d[v] == v ? v : d[v] = get(d[v]);
}
int mrg(int v, int u) {
	v = get(v), u = get(u);
	if (v == u) return 0;
	return d[u] = v,1;
}
void solve() {
	cin >> n >> m;
	for (int i = m - 1; i >= 0; i--)B += '0';
	for (int i = m * 2 - 1; i >= 0; i--) d[i] = i;
	int x = 0, y = 1;
	for (int x = 0, y = 1; cin >> s; B = A) {
	A = "";
	for (int j = 0; j < m / 4; j++)
	{
		int t = s[j] >= 'A' ? s[j] - 'A' + 10 : s[j] - '0';
		for (int i = 8; i; i /= 2)
			A += char('0' + ((t & i) > 0));
	}
	swap(x, y);
	for (int j = m; j--;)
		if (A[j] - '0') {
			ans++;
			if (B[j] - '0')
				ans -= mrg(2 * j + x, 2 * j + y);
			if (j && (A[j - 1] - '0'))
				ans -= mrg(2 * j + x, 2 * j + x - 2);
		}
	for (int j = m; j--;)
		d[2 * j + y] = 2 * j + y;
}
	cout << ans;
}

int main() {
	solve();

	return 0;
}


#include<bits/stdc++.h>

using namespace std;

int n,m;
string s,A,B;
int d[1<<15];
int ans;

int get(int v){
  return d[v]==v?v:d[v]=get(d[v]);
}
int mrg(int v,int u){
  v=get(v),u=get(u);
  if(v==u) return 0;
  return d[u]=v,1;
}

int main(){
  ios::sync_with_stdio(0);cin.tie(0);
  cin>>n>>m;
  for (int i = m - 1; i >= 0; i--)B += '0';
  for (int i = m * 2 - 1; i >= 0; i--) d[i] = i;
  for(int x=0,y=1;cin>>s;B=A){
    A="";
    for(int j=0;j<m/4;j++)
      {
	int x=s[j]>='A'?s[j]-'A'+10:s[j]-'0';
	for(int i=8;i;i/=2)
	  A+=char('0'+((x&i)>0));
      }
    swap(x,y);
    for(int j=m;j--;)
      if(A[j]-'0'){
	ans++;
	if(B[j]-'0')
	  ans-=mrg(2*j+x,2*j+y);
	if(j & A[j-1]-'0')
	  ans-=mrg(2*j+x,2*j+x-2);
      }
    for(int j=m;j--;)
      d[2*j+y]=2*j+y;
  }
  cout<<ans;
}


#include <bits/stdc++.h>

using namespace std;

typedef long double ld;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<ll> vll;
typedef vector<ull> vull;
typedef vector<vll> vvll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
typedef vector<ld> vld;
typedef vector<bool> vb;

#define _ inline
#define f first
#define sec second
#define pb push_back
#define ins insert
#define ers erase
#define mk make_pair
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define sz size
#define rsz resize
#define pw(x) (1 << (x))
#define sqr(x) ((x) * (x))
#define fro for
#define itn int
//#define int ll
#define forn(i, n) for (register int i(1); i <= n; i++)
#define fore(i, n) for (register int i(0); i < n; i++)
#define chcpy(Vec) copy(Vec.begin(), Vec.end(), ostream_iterator<char>(cout))
#define intcpy(Vec) copy(Vec.begin(), Vec.end(), ostream_iterator<int>(cout, " "))
#define endl "\n"
#define right rightt
#define left leftt
#define prev prevv
#define next nextt

const int INF = 1e9 + 10;
const int MOD = 1e9 + 7;
const int MAXN = 1e6 + 10;
const int LOG = 20;
const int P = 239017;
const long long BINF = 1e18 + 10;
const long long LINF = LLONG_MAX;
const long double EPS = 1e-9;
const long double PI = acos(-1);

_ void error()
{
    cout << -1;
    exit(0);
}

#define TASK "printing"

bitset<16370> arr[4097], used[4097];
int n, m, ans;
void dfs(int a, int b)
{
    used[a].set(b);
    if (a > 1 && !used[a - 1].test(b) && arr[a - 1].test(b))
    {
        used[a - 1].set(b);
        dfs(a - 1, b);
    }
    if (a < n && !used[a + 1].test(b) && arr[a + 1].test(b))
    {
        used[a + 1].set(b);
        dfs(a + 1, b);
    }
    if (b > 1 && !used[a].test(b - 1) && arr[a].test(b - 1))
    {
        used[a].set(b - 1);
        dfs(a, b - 1);
    }
    if (b < m && !used[a].test(b + 1) && arr[a].test(b + 1))
    {
        used[a].set(b + 1);
        dfs(a, b + 1);
    }
}

string get(char ch)
{
    int a;
    if (ch >= '0' && ch <= '9')
    {
        a = ch - '0';
    }
    else
    {
        a = 10 + (ch - 'A');
    }
    string res;
    while (a)
    {
        if (a % 2 == 1)
        {
            res += "1";
        }
        else
        {
            res += "0";
        }
        a /= 2;
    }
    reverse(all(res));
    while (res.size() < 4)
    {
        res.ins(res.begin(), '0');
    }
    return res;
}

_ void source()
{
    cin >> n >> m;
    forn(i, n)
    {
        int cnt = 0;
        char ch;
        forn(j, m / 4)
        {
            cin >> ch;
            string s = get(ch);
            cnt++;
            if (s[0] == '1')
            {
                arr[i].set(cnt);
            }
            cnt++;
            if (s[1] == '1')
            {
                arr[i].set(cnt);
            }
            cnt++;
            if (s[2] == '1')
            {
                arr[i].set(cnt);
            }
            cnt++;
            if (s[3] == '1')
            {
                arr[i].set(cnt);
            }
        }
    }
    forn(i, n)
    {
        forn(j, m)
        {
            if (!used[i].test(j) && arr[i].test(j))
            {
                ans++;
                dfs(i, j);
            }
        }
    }
    cout << ans;
}

signed main()
{
#ifdef EXTRATERRESTRIAL_
    freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
#else
    //freopen(TASK".in", "r", stdin);
    //freopen(TASK".out", "w", stdout);
#endif
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    srand(time(0));
    source();
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long double ld;
typedef long long ll;

#define _ inline
#define f first
#define sec second
#define pb push_back
#define ins insert
#define ers erase
#define mk make_pair
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define rsz resize
//#define int ll
#define forn(i, n) for (register int i(1); i <= n; i++)
#define fore(i, n) for (register int i(0); i < n; i++)
#define endl "\n"

#define right rightt
#define left leftt
#define prev prevv
#define next nextt

const int INF = 1e9 + 10;
const int MOD = 1e9 + 7;
const int P = 239017;
const long long BINF = 1e18 + 10;

string get(char ch) {
    int a;
    if (ch >= '0' && ch <= '9') {
        a = ch - '0';
    }
    else {
        a = 10 + (ch - 'A');
    }
    string res;
    while (a) {
        if (a % 2 == 1) {
            res += "1";
        }
        else {
            res += "0";
        }
        a /= 2;
    }
    reverse(all(res));
    while (res.size() < 4) {
        res.ins(res.begin(), '0');
    }
    return res;
}

const int N = (1 << 15) + 10;

int p[N], rk[N];

void make(int v) {
    p[v] = v;
    rk[v] = 1;
}

int find(int v) {
    if (p[v] == v) {
        return v;
    }
    return p[v] = find(p[v]);
}

bool merge(int a, int b) {
    a = find(a), b = find(b);
    if (a == b) {
        return false;
    }
    if (rk[a] < rk[b]) {
        swap(a, b);
    }
    else if (rk[a] == rk[b]) {
        rk[a]++;
    }
    p[b] = a;
    return true;
}

_ void source() {
    int n, m, ans = 0;
    vector<int> arr[2];
    cin >> n >> m;
    forn(i, m / 4) {
        char ch;
        cin >> ch;
        string s = get(ch);
        for (int j = 0; j < s.size(); j++) {
            if (s[j] == '1') {
                ans++;
            }
            arr[0].pb(s[j] - '0');
            int a = arr[0].size();
            make(a);
        }
    }
    for (int i = 1; i < m; i++) {
        if (arr[0][i] && arr[0][i - 1]) {
            ans -= merge(i, i + 1);
        }
    }
    forn(i, m / 4) {
        char ch;
        cin >> ch;
        string s = get(ch);
        for (int j = 0; j < s.size(); j++) {
            if (s[j] == '1') {
                ans++;
            }
            arr[1].pb(s[j] - '0');
            int a = arr[1].size();
            make(a + m);
        }
    }
    for (int i = 0; i < m; i++) {
        if (arr[0][i] && arr[1][i]) {
            ans -= merge(i + 1, i + m + 1);
        }
        if (i && arr[1][i] && arr[1][i - 1]) {
            ans -= merge(i + m, i + m + 1);
        }
    }
    for (int i = 3; i <= n; i++) {
        int col[2 * m + 10];
        for (int j = 1; j <= 2 * m; j++) {
            col[j] = find(j);
        }
        for (int j = 1; j <= m; j++) {
            make(j);
        }
        for (int j = 1; j < m; j++) {
            if (arr[1][j] && arr[1][j - 1] && col[j + m] == col[j + m + 1]) {
                merge(j, j + 1);
            }
        }
        arr[0] = arr[1];
        arr[1].clear();
        for (int j = 0; j < m / 4; j++) {
            char ch;
            cin >> ch;
            string s = get(ch);
            for (int k = 0; k < s.size(); k++) {
                if (s[k] == '1') {
                    ans++;
                }
                arr[1].pb(s[k] - '0');
                int a = arr[1].size();
                make(a + m);
            }
        }
        for (int j = 0; j < m; j++) {
            if (arr[0][j] && arr[1][j]) {
                ans -= merge(j + m, j + m + 1);
            }
            if (j && arr[1][j] && arr[1][j - 1]) {
                ans -= merge(j + m, j + m + 1);
            }
        }
    }
    cout << ans;
}

signed main() {
#ifdef EXTRATERRESTRIAL_
    freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
#else
    //freopen(TASK".in", "r", stdin);
    //freopen(TASK".out", "w", stdout);
#endif
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    srand(time(0));
    source();
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long double ld;
typedef long long ll;

#define _ inline
#define f first
#define sec second
#define pb push_back
#define ins insert
#define ers erase
#define mk make_pair
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define rsz resize
//#define int ll
#define forn(i, n) for (register int i(1); i <= n; i++)
#define fore(i, n) for (register int i(0); i < n; i++)
#define endl "\n"

#define right rightt
#define left leftt
#define prev prevv
#define next nextt

const int INF = 1e9 + 10;
const int MOD = 1e9 + 7;
const int P = 239017;
const long long BINF = 1e18 + 10;

string get(char ch) {
    int a;
    if (ch >= '0' && ch <= '9') {
        a = ch - '0';
    }
    else {
        a = 10 + (ch - 'A');
    }
    string res;
    while (a) {
        if (a % 2 == 1) {
            res += "1";
        }
        else {
            res += "0";
        }
        a /= 2;
    }
    reverse(all(res));
    while (res.size() < 4) {
        res.ins(res.begin(), '0');
    }
    //cout << res << endl;
    return res;
}

const int N = (1 << 15) + 10;

int p[N], rk[N];

void make(int v) {
    p[v] = v;
    rk[v] = 1;
}

int find(int v) {
    if (p[v] == v) {
        return v;
    }
    return p[v] = find(p[v]);
}

bool merge(int a, int b) {
    a = find(a), b = find(b);
    if (a == b) {
        return false;
    }
    if (rk[a] < rk[b]) {
        swap(a, b);
    }
    else if (rk[a] == rk[b]) {
        rk[a]++;
    }
    p[b] = a;
    return true;
}

_ void source() {
    int n, m, ans = 0;
    vector<int> arr[2];
    cin >> n >> m;
    forn(i, m / 4) {
        char ch;
        cin >> ch;
        string s = get(ch);
        //cout << s << endl;
        for (int j = 0; j < s.size(); j++) {
            if (s[j] == '1') {
                ans++;
            }
            arr[1].pb(s[j] - '0');
            int a = arr[1].size();
            make(a + m);
        }
    }
    for (int i = 1; i < m; i++) {
        if (arr[1][i] && arr[1][i - 1]) {
            ans -= merge(i + m, i + m + 1);
        }
    }
    //cout << ans << endl;
    for (int i = 2; i <= n; i++) {
        //cout << ans << endl;
        int col[2 * m + 10];
        for (int j = 1; j <= 2 * m; j++) {
            col[j] = find(j);
        }
        for (int j = 1; j <= 2 * m; j++) {
            make(j);
        }
        for (int j = 1; j < m; j++) {
            if (col[j + m] == col[j + m + 1]) {
                merge(j, j + 1);
            }
        }
        arr[0] = arr[1];
        arr[1].clear();
        for (int j = 0; j < m / 4; j++) {
            char ch;
            cin >> ch;
            string s = get(ch);
            assert(s.size() == 4);
            //cout << s << endl;
            for (int k = 0; k < s.size(); k++) {
                if (s[k] == '1') {
                    ans++;
                }
                arr[1].pb(s[k] - '0');
                int a = arr[1].size();
                make(a + m);
            }
        }
        //cout << ans << endl;
        for (int j = 0; j < m; j++) {
            if (arr[0][j] && arr[1][j]) {
                ans -= merge(j + 1, j + m + 1);
            }
            if (j && arr[1][j] && arr[1][j - 1]) {
                ans -= merge(j + m, j + m + 1);
            }
        }
    }
    cout << ans;
}

signed main() {
#ifdef EXTRATERRESTRIAL_
    freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
#else
    //freopen(TASK".in", "r", stdin);
    //freopen(TASK".out", "w", stdout);
#endif
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    srand(time(0));
    source();
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long double ld;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<ll> vll;
typedef vector<ull> vull;
typedef vector<vll> vvll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
typedef vector<ld> vld;
typedef vector<bool> vb;

#define _ inline
#define f first
#define sec second
#define pb push_back
#define ins insert
#define ers erase
#define mk make_pair
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define sz size
#define rsz resize
#define pw(x) (1 << (x))
#define sqr(x) ((x) * (x))
#define fro for
#define itn int
//#define int ll
#define forn(i, n) for (register int i(1); i <= n; i++)
#define fore(i, n) for (register int i(0); i < n; i++)
#define chcpy(Vec) copy(Vec.begin(), Vec.end(), ostream_iterator<char>(cout))
#define intcpy(Vec) copy(Vec.begin(), Vec.end(), ostream_iterator<int>(cout, " "))
#define endl "\n"
#define right rightt
#define left leftt
#define prev prevv
#define next nextt

const int INF = 1e9 + 10;
const int MOD = 1e9 + 7;
const int MAXN = 1e6 + 10;
const int LOG = 20;
const int P = 239017;
const long long BINF = 1e18 + 10;
const long long LINF = LLONG_MAX;
const long double EPS = 1e-9;
const long double PI = acos(-1);

_ void error()
{
    cout << -1;
    exit(0);
}

#define TASK "printing"

vector<bitset<16400> > arr, used;
int n, m, ans;
void dfs(int a, int b)
{
    used[a].set(b);
    if (a > 1 && !used[a - 1].test(b) && arr[a - 1].test(b))
    {
        used[a - 1].set(b);
        dfs(a - 1, b);
    }
    if (a < n && !used[a + 1].test(b) && arr[a + 1].test(b))
    {
        used[a + 1].set(b);
        dfs(a + 1, b);
    }
    if (b > 1 && !used[a].test(b - 1) && arr[a].test(b - 1))
    {
        used[a].set(b - 1);
        dfs(a, b - 1);
    }
    if (b < m && !used[a].test(b + 1) && arr[a].test(b + 1))
    {
        used[a].set(b + 1);
        dfs(a, b + 1);
    }
}

string get(char ch)
{
    int a;
    if (ch >= '0' && ch <= '9')
    {
        a = ch - '0';
    }
    else
    {
        a = 10 + (ch - 'A');
    }
    string res;
    while (a)
    {
        if (a % 2 == 1)
        {
            res += "1";
        }
        else
        {
            res += "0";
        }
        a /= 2;
    }
    reverse(all(res));
    while (res.size() < 4)
    {
        res.ins(res.begin(), '0');
    }
    return res;
}

_ void source()
{
    cin >> n >> m;
    arr.rsz(n + 1);
    used.rsz(n + 1);
    forn(i, n)
    {
        int cnt = 0;
        char ch;
        forn(j, m / 4)
        {
            cin >> ch;
            string s = get(ch);
            cnt++;
            if (s[0] == '1')
            {
                arr[i].set(cnt);
            }
            cnt++;
            if (s[1] == '1')
            {
                arr[i].set(cnt);
            }
            cnt++;
            if (s[2] == '1')
            {
                arr[i].set(cnt);
            }
            cnt++;
            if (s[3] == '1')
            {
                arr[i].set(cnt);
            }
        }
    }
    forn(i, n)
    {
        forn(j, m)
        {
            if (!used[i].test(j) && arr[i].test(j))
            {
                ans++;
                dfs(i, j);
            }
        }
    }
    cout << ans;
}

signed main()
{
#ifdef EXTRATERRESTRIAL_
    freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
#else
    //freopen(TASK".in", "r", stdin);
    //freopen(TASK".out", "w", stdout);
#endif
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    srand(time(0));
    source();
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long double ld;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<ll> vll;
typedef vector<ull> vull;
typedef vector<vll> vvll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
typedef vector<ld> vld;
typedef vector<bool> vb;

#define _ inline
#define f first
#define sec second
#define pb push_back
#define ins insert
#define ers erase
#define mk make_pair
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define sz size
#define rsz resize
#define pw(x) (1 << (x))
#define sqr(x) ((x) * (x))
#define fro for
#define itn int
//#define int ll
#define forn(i, n) for (register int i(1); i <= n; i++)
#define fore(i, n) for (register int i(0); i < n; i++)
#define chcpy(Vec) copy(Vec.begin(), Vec.end(), ostream_iterator<char>(cout))
#define intcpy(Vec) copy(Vec.begin(), Vec.end(), ostream_iterator<int>(cout, " "))
#define endl "\n"
#define right rightt
#define left leftt
#define prev prevv
#define next nextt

const int INF = 1e9 + 10;
const int MOD = 1e9 + 7;
const int MAXN = 1e6 + 10;
const int LOG = 20;
const int P = 239017;
const long long BINF = 1e18 + 10;
const long long LINF = LLONG_MAX;
const long double EPS = 1e-9;
const long double PI = acos(-1);

_ void error()
{
    cout << -1;
    exit(0);
}

#define TASK "printing"

bitset<16500> arr[4100], used[4100];
int n, m, ans;
void dfs(int a, int b)
{
    used[a].set(b);
    if (a > 1 && !used[a - 1].test(b) && arr[a - 1].test(b))
    {
        used[a - 1].set(b);
        dfs(a - 1, b);
    }
    if (a < n && !used[a + 1].test(b) && arr[a + 1].test(b))
    {
        used[a + 1].set(b);
        dfs(a + 1, b);
    }
    if (b > 1 && !used[a].test(b - 1) && arr[a].test(b - 1))
    {
        used[a].set(b - 1);
        dfs(a, b - 1);
    }
    if (b < m && !used[a].test(b + 1) && arr[a].test(b + 1))
    {
        used[a].set(b + 1);
        dfs(a, b + 1);
    }
}

string get(char ch)
{
    int a;
    if (ch >= '0' && ch <= '9')
    {
        a = ch - '0';
    }
    else
    {
        a = 10 + (ch - 'A');
    }
    string res;
    while (a)
    {
        if (a % 2 == 1)
        {
            res += "1";
        }
        else
        {
            res += "0";
        }
        a /= 2;
    }
    reverse(all(res));
    while (res.size() < 4)
    {
        res.ins(res.begin(), '0');
    }
    return res;
}

_ void source()
{
    cin >> n >> m;
    forn(i, n)
    {
        int cnt = 0;
        char ch;
        forn(j, m / 4)
        {
            cin >> ch;
            string s = get(ch);
            cnt++;
            if (s[0] == '1')
            {
                arr[i].set(cnt);
            }
            cnt++;
            if (s[1] == '1')
            {
                arr[i].set(cnt);
            }
            cnt++;
            if (s[2] == '1')
            {
                arr[i].set(cnt);
            }
            cnt++;
            if (s[3] == '1')
            {
                arr[i].set(cnt);
            }
        }
    }
    forn(i, n)
    {
        forn(j, m)
        {
            if (!used[i].test(j) && arr[i].test(j))
            {
                ans++;
                dfs(i, j);
            }
        }
    }
    cout << ans;
}

signed main()
{
#ifdef EXTRATERRESTRIAL_
    freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
#else
    //freopen(TASK".in", "r", stdin);
    //freopen(TASK".out", "w", stdout);
#endif
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    srand(time(0));
    source();
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long double ld;
typedef long long ll;

#define _ inline
#define f first
#define sec second
#define pb push_back
#define ins insert
#define ers erase
#define mk make_pair
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define rsz resize
//#define int ll
#define forn(i, n) for (register int i(1); i <= n; i++)
#define fore(i, n) for (register int i(0); i < n; i++)
#define endl "\n"

#define right rightt
#define left leftt
#define prev prevv
#define next nextt

const int INF = 1e9 + 10;
const int MOD = 1e9 + 7;
const int P = 239017;
const long long BINF = 1e18 + 10;

string get(char ch) {
    int a;
    if (ch >= '0' && ch <= '9') {
        a = ch - '0';
    }
    else {
        a = 10 + (ch - 'A');
    }
    string res;
    while (a) {
        if (a % 2 == 1) {
            res += "1";
        }
        else {
            res += "0";
        }
        a /= 2;
    }
    reverse(all(res));
    while (res.size() < 4) {
        res.ins(res.begin(), '0');
    }
    return res;
}

const int N = (1 << 15) + 10;

int p[N], rk[N];

void make(int v) {
    p[v] = v;
    rk[v] = 1;
}

int find(int v) {
    if (p[v] == v) {
        return v;
    }
    return p[v] = find(p[v]);
}

bool merge(int a, int b) {
    a = find(a), b = find(b);
    if (a == b) {
        return false;
    }
    if (rk[a] < rk[b]) {
        swap(a, b);
    }
    else if (rk[a] == rk[b]) {
        rk[a]++;
    }
    p[b] = a;
    return true;
}

_ void source() {
    int n, m, ans = 0;
    vector<int> arr[2];
    cin >> n >> m;
    forn(i, m / 4) {
        char ch;
        cin >> ch;
        string s = get(ch);
        for (int j = 0; j < s.size(); j++) {
            if (s[j] == '1') {
                ans++;
            }
            arr[1].pb(s[j] - '0');
            int a = arr[1].size();
            make(a + m);
        }
    }
    for (int i = 1; i < m; i++) {
        if (arr[1][i] && arr[1][i - 1]) {
            ans -= merge(i + m, i + m + 1);
        }
    }
    for (int i = 3; i <= n; i++) {
        int col[2 * m + 10];
        for (int j = 1; j <= 2 * m; j++) {
            col[j] = find(j);
        }
        for (int j = 1; j <= m; j++) {
            make(j);
        }
        for (int j = 1; j < m; j++) {
            if (arr[1][j] && arr[1][j - 1] && col[j + m] == col[j + m + 1]) {
                merge(j, j + 1);
            }
        }
        arr[0] = arr[1];
        arr[1].clear();
        for (int j = 0; j < m / 4; j++) {
            char ch;
            cin >> ch;
            string s = get(ch);
            for (int k = 0; k < s.size(); k++) {
                if (s[k] == '1') {
                    ans++;
                }
                arr[1].pb(s[k] - '0');
                int a = arr[1].size();
                make(a + m);
            }
        }
        for (int j = 0; j < m; j++) {
            if (arr[0][j] && arr[1][j]) {
                ans -= merge(j + 1, j + m + 1);
            }
            if (j && arr[1][j] && arr[1][j - 1]) {
                ans -= merge(j + m, j + m + 1);
            }
        }
    }
    cout << ans;
}

signed main() {
#ifdef EXTRATERRESTRIAL_
    freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
#else
    //freopen(TASK".in", "r", stdin);
    //freopen(TASK".out", "w", stdout);
#endif
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    srand(time(0));
    source();
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long double ld;
typedef long long ll;

#define _ inline
#define f first
#define sec second
#define pb push_back
#define ins insert
#define ers erase
#define mk make_pair
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define rsz resize
//#define int ll
#define forn(i, n) for (register int i(1); i <= n; i++)
#define fore(i, n) for (register int i(0); i < n; i++)
#define endl "\n"

#define right rightt
#define left leftt
#define prev prevv
#define next nextt

const int INF = 1e9 + 10;
const int MOD = 1e9 + 7;
const int P = 239017;
const long long BINF = 1e18 + 10;

const int N = (1 << 15) + 10;

int p[N], rk[N];

_ void make(int v) {
    p[v] = v;
    rk[v] = 1;
}

_ int find(int v) {
    if (p[v] == v) {
        return v;
    }
    return p[v] = find(p[v]);
}

_ bool merge(int a, int b) {
    a = find(a), b = find(b);
    if (a == b) {
        return false;
    }
    if (rk[a] < rk[b]) {
        swap(a, b);
    }
    else if (rk[a] == rk[b]) {
        rk[a]++;
    }
    p[b] = a;
    return true;
}

_ void source() {
    int n, m, ans = 0;
    vector<int> arr[2];
    cin >> n >> m;
    int lim = m / 4, a = 0, lim2 = 2 * m;
    for (int i = 1; i <= lim; i++) {
        char ch;
        int pp;
        cin >> ch;
        if (ch <= '9') {
            pp = ch - '0';
        }
        else {
            pp = ch - 'A' + 10;
        }
        for (int j = 3; j >= 0; j--) {
            int ppp = (pp >> j) & 1;
            if (ppp) {
                ans++;
            }
            arr[1].pb(ppp);
            a++;
            make(a + m);
        }
    }
    for (int i = 1; i < m; i++) {
        if (arr[1][i] && arr[1][i - 1]) {
            ans -= merge(i + m, i + m + 1);
        }
    }
    for (int i = 2; i <= n; i++) {
        int col[lim2 + 10];
        vector<int> now(lim2 + 10, 0);
        for (int j = m + 1; j <= lim2; j++) {
            col[j] = find(j);
        }
        for (int j = 1; j <= lim2; j++) {
            make(j);
        }
        for (int j = 1; j <= m; j++) {
            if (!arr[1][j - 1]) {
                continue;
            }
            if (now[col[j + m]]) {
                merge(j, now[col[j + m]]);
            }
            else {
                now[col[j + m]] = j;
            }
        }
        arr[0] = arr[1];
        arr[1].clear();
        for (int j = 0; j < lim; j++) {
            char ch;
            int pp;
            cin >> ch;
            if (ch <= '9') {
                pp = ch - '0';
            }
            else {
                pp = ch - 'A' + 10;
            }
            for (int k = 3; k >= 0; k--) {
                int ppp = (pp >> k) & 1;
                if (ppp) {
                    ans++;
                }
                arr[1].pb(ppp);
            }
        }
        if (arr[0][0] && arr[1][0]) {
            ans -= merge(1, m + 1);
        }
        for (int j = 1; j < m; j++) {
            if (!arr[1][j]) {
                continue;
            }
            if (arr[0][j]) {
                ans -= merge(j + 1, j + m + 1);
            }
            if (arr[1][j - 1]) {
                ans -= merge(j + m, j + m + 1);
            }
        }
    }
    cout << ans;
}

signed main() {
#ifdef EXTRATERRESTRIAL_
    freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
#else
    //freopen(TASK".in", "r", stdin);
    //freopen(TASK".out", "w", stdout);
#endif
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    srand(time(0));
    source();
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long double ld;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<ll> vll;
typedef vector<ull> vull;
typedef vector<vll> vvll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
typedef vector<ld> vld;
typedef vector<bool> vb;

#define _ inline
#define f first
#define sec second
#define pb push_back
#define ins insert
#define ers erase
#define mk make_pair
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define sz size
#define rsz resize
#define pw(x) (1 << (x))
#define sqr(x) ((x) * (x))
#define fro for
#define itn int
//#define int ll
#define forn(i, n) for (register int i(1); i <= n; i++)
#define fore(i, n) for (register int i(0); i < n; i++)
#define chcpy(Vec) copy(Vec.begin(), Vec.end(), ostream_iterator<char>(cout))
#define intcpy(Vec) copy(Vec.begin(), Vec.end(), ostream_iterator<int>(cout, " "))
#define endl "\n"
#define right rightt
#define left leftt
#define prev prevv
#define next nextt

const int INF = 1e9 + 10;
const int MOD = 1e9 + 7;
const int MAXN = 1e6 + 10;
const int LOG = 20;
const int P = 239017;
const long long BINF = 1e18 + 10;
const long long LINF = LLONG_MAX;
const long double EPS = 1e-9;
const long double PI = acos(-1);

_ void error()
{
    cout << -1;
    exit(0);
}

#define TASK "printing"

vector<bitset<16400> > arr, used;
int n, m, ans;
void dfs(int a, int b)
{
    used[a].set(b);
    if (a > 1 && !used[a - 1].test(b) && arr[a - 1].test(b))
    {
        used[a - 1].set(b);
        dfs(a - 1, b);
    }
    if (a < n && !used[a + 1].test(b) && arr[a + 1].test(b))
    {
        used[a + 1].set(b);
        dfs(a + 1, b);
    }
    if (b > 1 && !used[a].test(b - 1) && arr[a].test(b - 1))
    {
        used[a].set(b - 1);
        dfs(a, b - 1);
    }
    if (b < m && !used[a].test(b + 1) && arr[a].test(b + 1))
    {
        used[a].set(b + 1);
        dfs(a, b + 1);
    }
}

string get(char ch)
{
    int a;
    if (ch >= '0' && ch <= '9')
    {
        a = ch - '0';
    }
    else
    {
        a = 10 + (ch - 'A');
    }
    string res;
    while (a)
    {
        if (a % 2 == 1)
        {
            res += "1";
        }
        else
        {
            res += "0";
        }
        a /= 2;
    }
    reverse(all(res));
    while (res.size() < 4)
    {
        res.ins(res.begin(), '0');
    }
    return res;
}

_ void source()
{
    cin >> n >> m;
    arr.rsz(n + 1);
    used.rsz(m + 1);
    forn(i, n)
    {
        int cnt = 0;
        char ch;
        forn(j, m / 4)
        {
            cin >> ch;
            string s = get(ch);
            cnt++;
            if (s[0] == '1')
            {
                arr[i].set(cnt);
            }
            cnt++;
            if (s[1] == '1')
            {
                arr[i].set(cnt);
            }
            cnt++;
            if (s[2] == '1')
            {
                arr[i].set(cnt);
            }
            cnt++;
            if (s[3] == '1')
            {
                arr[i].set(cnt);
            }
        }
    }
    forn(i, n)
    {
        forn(j, m)
        {
            if (!used[i].test(j) && arr[i].test(j))
            {
                ans++;
                dfs(i, j);
            }
        }
    }
    cout << ans;
}

signed main()
{
#ifdef EXTRATERRESTRIAL_
    freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
#else
    //freopen(TASK".in", "r", stdin);
    //freopen(TASK".out", "w", stdout);
#endif
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    srand(time(0));
    source();
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long double ld;
typedef long long ll;

#define _ inline
#define f first
#define sec second
#define pb push_back
#define ins insert
#define ers erase
#define mk make_pair
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define rsz resize
//#define int ll
#define forn(i, n) for (register int i(1); i <= n; i++)
#define fore(i, n) for (register int i(0); i < n; i++)
#define endl "\n"

#define right rightt
#define left leftt
#define prev prevv
#define next nextt

const int INF = 1e9 + 10;
const int MOD = 1e9 + 7;
const int P = 239017;
const long long BINF = 1e18 + 10;

const int N = (1 << 15) + 10;

int p[N], rk[N];

_ void make(int v) {
    p[v] = v;
    rk[v] = 1;
}

_ int find(int v) {
    if (p[v] == v) {
        return v;
    }
    return p[v] = find(p[v]);
}

_ bool merge(int a, int b) {
    a = find(a), b = find(b);
    if (a == b) {
        return false;
    }
    if (rk[a] < rk[b]) {
        swap(a, b);
    }
    else if (rk[a] == rk[b]) {
        rk[a]++;
    }
    p[b] = a;
    return true;
}

_ void source() {
    int n, m, ans = 0;
    vector<int> arr[2];
    cin >> n >> m;
    forn(i, m / 4) {
        char ch;
        int pp;
        cin >> ch;
        if (ch <= '9') {
            pp = ch - '0';
        }
        else {
            pp = ch - 'A' + 10;
        }
        for (int j = 3; j >= 0; j--) {
            int ppp = (pp >> j) & 1;
            if (ppp) {
                ans++;
            }
            arr[1].pb(ppp);
            int a = arr[1].size();
            make(a + m);
        }
    }
    for (int i = 1; i < m; i++) {
        if (arr[1][i] && arr[1][i - 1]) {
            ans -= merge(i + m, i + m + 1);
        }
    }
    for (int i = 2; i <= n; i++) {
        int col[2 * m + 10];
        vector<int> now(2 * m + 10);
        fill(all(now), 0);
        for (int j = 1; j <= 2 * m; j++) {
            col[j] = find(j);
        }
        for (int j = 1; j <= 2 * m; j++) {
            make(j);
        }
        for (int j = 1; j <= m; j++) {
            if (!arr[1][j - 1]) {
                continue;
            }
            if (now[col[j + m]]) {
                merge(j, now[col[j + m]]);
            }
            else {
                now[col[j + m]] = j;
            }
        }
        arr[0] = arr[1];
        arr[1].clear();
        for (int j = 0; j < m / 4; j++) {
            char ch;
            int pp;
            cin >> ch;
            if (ch <= '9') {
                pp = ch - '0';
            }
            else {
                pp = ch - 'A' + 10;
            }
            for (int k = 3; k >= 0; k--) {
                int ppp = (pp >> k) & 1;
                if (ppp) {
                    ans++;
                }
                arr[1].pb(ppp);
                int a = arr[1].size();
                make(a + m);
            }
        }

        if (arr[0][0] && arr[1][0]) {
            ans -= merge(1, m + 1);
        }
        for (int j = 1; j < m; j++) {
            if (!arr[1][j]) {
                continue;
            }
            if (arr[0][j]) {
                ans -= merge(j + 1, j + m + 1);
            }
            if (arr[1][j - 1]) {
                ans -= merge(j + m, j + m + 1);
            }
        }
    }
    cout << ans;
}

signed main() {
#ifdef EXTRATERRESTRIAL_
    freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
#else
    //freopen(TASK".in", "r", stdin);
    //freopen(TASK".out", "w", stdout);
#endif
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    srand(time(0));
    source();
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long double ld;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<ll> vll;
typedef vector<ull> vull;
typedef vector<vll> vvll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
typedef vector<ld> vld;
typedef vector<bool> vb;

#define _ inline
#define f first
#define sec second
#define pb push_back
#define ins insert
#define ers erase
#define mk make_pair
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define sz size
#define rsz resize
#define pw(x) (1 << (x))
#define sqr(x) ((x) * (x))
#define fro for
#define itn int
//#define int ll
#define forn(i, n) for (register int i(1); i <= n; i++)
#define fore(i, n) for (register int i(0); i < n; i++)
#define chcpy(Vec) copy(Vec.begin(), Vec.end(), ostream_iterator<char>(cout))
#define intcpy(Vec) copy(Vec.begin(), Vec.end(), ostream_iterator<int>(cout, " "))
#define endl "\n"
#define right rightt
#define left leftt
#define prev prevv
#define next nextt

const int INF = 1e9 + 10;
const int MOD = 1e9 + 7;
const int MAXN = 1e6 + 10;
const int LOG = 20;
const int P = 239017;
const long long BINF = 1e18 + 10;
const long long LINF = LLONG_MAX;
const long double EPS = 1e-9;
const long double PI = acos(-1);

_ void error()
{
    cout << -1;
    exit(0);
}

#define TASK "printing"

bitset<16400> used[4100];
char arr[4100][4100];
int n, m, ans;

string get(char ch)
{
    int a;
    if (ch >= '0' && ch <= '9')
    {
        a = ch - '0';
    }
    else
    {
        a = 10 + (ch - 'A');
    }
    string res;
    while (a)
    {
        if (a % 2 == 1)
        {
            res += "1";
        }
        else
        {
            res += "0";
        }
        a /= 2;
    }
    reverse(all(res));
    while (res.size() < 4)
    {
        res.ins(res.begin(), '0');
    }
    return res;
}

bool get2(int a, int b)
{
    int c = b / 4 + bool(b % 4), d = (b - 1) % 4;
    //cout << b << " " << c << endl;
    string s = get(arr[a][c]);
    //cout << s << endl;
    return s[d] == '1';
}

void dfs(int a, int b)
{
    used[a].set(b);
    if (a > 1 && !used[a - 1].test(b) && get2(a - 1, b))
    {
        used[a - 1].set(b);
        dfs(a - 1, b);
    }
    if (a < n && !used[a + 1].test(b) && get2(a + 1, b))
    {
        used[a + 1].set(b);
        dfs(a + 1, b);
    }
    if (b > 1 && !used[a].test(b - 1) && get2(a, b - 1))
    {
        used[a].set(b - 1);
        dfs(a, b - 1);
    }
    if (b < m && !used[a].test(b + 1) && get2(a, b + 1))
    {
        used[a].set(b + 1);
        dfs(a, b + 1);
    }
}

_ void source()
{
    cin >> n >> m;
    forn(i, n)
    {
        forn(j, m / 4)
        {
            cin >> arr[i][j];
        }
    }
    forn(i, n)
    {
        forn(j, m)
        {
            if (!used[i].test(j) && get2(i, j))
            {
                ans++;
                dfs(i, j);
            }
        }
    }
    cout << ans;
}

signed main()
{
#ifdef EXTRATERRESTRIAL_
    freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
#else
    //freopen(TASK".in", "r", stdin);
    //freopen(TASK".out", "w", stdout);
#endif
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    srand(time(0));
    source();
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long double ld;
typedef long long ll;

#define _ inline
#define f first
#define sec second
#define pb push_back
#define ins insert
#define ers erase
#define mk make_pair
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define rsz resize
//#define int ll
#define forn(i, n) for (register int i(1); i <= n; i++)
#define fore(i, n) for (register int i(0); i < n; i++)
#define endl "\n"

#define right rightt
#define left leftt
#define prev prevv
#define next nextt

const int INF = 1e9 + 10;
const int MOD = 1e9 + 7;
const int P = 239017;
const long long BINF = 1e18 + 10;

string get(char ch) {
    int a;
    if (ch >= '0' && ch <= '9') {
        a = ch - '0';
    }
    else {
        a = 10 + (ch - 'A');
    }
    string res;
    while (a) {
        if (a % 2 == 1) {
            res += "1";
        }
        else {
            res += "0";
        }
        a /= 2;
    }
    reverse(all(res));
    while (res.size() < 4) {
        res.ins(res.begin(), '0');
    }
    //cout << res << endl;
    return res;
}

const int N = (1 << 15) + 10;

int p[N], rk[N];

void make(int v) {
    p[v] = v;
    rk[v] = 1;
}

int find(int v) {
    if (p[v] == v) {
        return v;
    }
    return p[v] = find(p[v]);
}

bool merge(int a, int b) {
    a = find(a), b = find(b);
    if (a == b) {
        return false;
    }
    if (rk[a] < rk[b]) {
        swap(a, b);
    }
    else if (rk[a] == rk[b]) {
        rk[a]++;
    }
    p[b] = a;
    return true;
}

_ void source() {
    int n, m, ans = 0;
    vector<int> arr[2];
    cin >> n >> m;
    forn(i, m / 4) {
        char ch;
        cin >> ch;
        string s = get(ch);
        //cout << s << endl;
        for (int j = 0; j < s.size(); j++) {
            if (s[j] == '1') {
                ans++;
            }
            arr[1].pb(s[j] - '0');
            int a = arr[1].size();
            make(a + m);
        }
    }
    for (int i = 1; i < m; i++) {
        if (arr[1][i] && arr[1][i - 1]) {
            ans -= merge(i + m, i + m + 1);
        }
    }
    //cout << ans << endl;
    for (int i = 2; i <= n; i++) {
        int col[2 * m + 10];
        for (int j = 1; j <= 2 * m; j++) {
            col[j] = find(j);
        }
        for (int j = 1; j <= m; j++) {
            make(j);
        }
        for (int j = 1; j < m; j++) {
            if (col[j + m] == col[j + m + 1]) {
                merge(j, j + 1);
            }
        }
        arr[0] = arr[1];
        arr[1].clear();
        for (int j = 0; j < m / 4; j++) {
            char ch;
            cin >> ch;
            string s = get(ch);
            //cout << s << endl;
            for (int k = 0; k < s.size(); k++) {
                if (s[k] == '1') {
                    ans++;
                }
                arr[1].pb(s[k] - '0');
                int a = arr[1].size();
                make(a + m);
            }
        }
        //cout << ans << endl;
        for (int j = 0; j < m; j++) {
            if (arr[0][j] && arr[1][j]) {
                ans -= merge(j + 1, j + m + 1);
            }
            if (j && arr[1][j] && arr[1][j - 1]) {
                ans -= merge(j + m, j + m + 1);
            }
        }
    }
    cout << ans;
}

signed main() {
#ifdef EXTRATERRESTRIAL_
    freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
#else
    //freopen(TASK".in", "r", stdin);
    //freopen(TASK".out", "w", stdout);
#endif
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    srand(time(0));
    source();
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long double ld;
typedef long long ll;

#define _ inline
#define f first
#define sec second
#define pb push_back
#define ins insert
#define ers erase
#define mk make_pair
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define rsz resize
//#define int ll
#define forn(i, n) for (register int i(1); i <= n; i++)
#define fore(i, n) for (register int i(0); i < n; i++)
#define endl "\n"

#define right rightt
#define left leftt
#define prev prevv
#define next nextt

const int INF = 1e9 + 10;
const int MOD = 1e9 + 7;
const int P = 239017;
const long long BINF = 1e18 + 10;

string get(char ch) {
    int a;
    if (ch >= '0' && ch <= '9') {
        a = ch - '0';
    }
    else {
        a = 10 + (ch - 'A');
    }
    string res;
    while (a) {
        if (a % 2 == 1) {
            res += "1";
        }
        else {
            res += "0";
        }
        a /= 2;
    }
    reverse(all(res));
    while (res.size() < 4) {
        res.ins(res.begin(), '0');
    }
    return res;
}

const int N = (1 << 15) + 10;

int p[N], rk[N];

void make(int v) {
    p[v] = v;
    rk[v] = 1;
}

int find(int v) {
    if (p[v] == v) {
        return v;
    }
    return p[v] = find(p[v]);
}

bool merge(int a, int b) {
    a = find(a), b = find(b);
    if (a == b) {
        return false;
    }
    if (rk[a] < rk[b]) {
        swap(a, b);
    }
    else if (rk[a] == rk[b]) {
        rk[a]++;
    }
    p[b] = a;
    return true;
}

_ void source() {
    int n, m, ans = 0;
    vector<int> arr[2];
    cin >> n >> m;
    forn(i, m / 4) {
        char ch;
        cin >> ch;
        string s = get(ch);
        for (int j = 0; j < s.size(); j++) {
            if (s[j] == '1') {
                ans++;
            }
            arr[0].pb(s[j] - '0');
            int a = arr[0].size();
            make(a);
        }
    }
    for (int i = 1; i < m; i++) {
        if (arr[0][i] && arr[0][i - 1]) {
            ans -= merge(i, i + 1);
        }
    }
    if (n == 1) {
        cout << ans;
        exit(0);
    }
    forn(i, m / 4) {
        char ch;
        cin >> ch;
        string s = get(ch);
        for (int j = 0; j < s.size(); j++) {
            if (s[j] == '1') {
                ans++;
            }
            arr[1].pb(s[j] - '0');
            int a = arr[1].size();
            make(a + m);
        }
    }
    for (int i = 0; i < m; i++) {
        if (arr[0][i] && arr[1][i]) {
            ans -= merge(i + 1, i + m + 1);
        }
        if (i && arr[1][i] && arr[1][i - 1]) {
            ans -= merge(i + m, i + m + 1);
        }
    }
    for (int i = 3; i <= n; i++) {
        int col[2 * m + 10];
        for (int j = 1; j <= 2 * m; j++) {
            col[j] = find(j);
        }
        for (int j = 1; j <= m; j++) {
            make(j);
        }
        for (int j = 1; j < m; j++) {
            if (arr[1][j] && arr[1][j - 1] && col[j + m] == col[j + m + 1]) {
                merge(j, j + 1);
            }
        }
        arr[0] = arr[1];
        arr[1].clear();
        for (int j = 0; j < m / 4; j++) {
            char ch;
            cin >> ch;
            string s = get(ch);
            for (int k = 0; k < s.size(); k++) {
                if (s[k] == '1') {
                    ans++;
                }
                arr[1].pb(s[k] - '0');
                int a = arr[1].size();
                make(a + m);
            }
        }
        for (int j = 0; j < m; j++) {
            if (arr[0][j] && arr[1][j]) {
                ans -= merge(j + m, j + m + 1);
            }
            if (j && arr[1][j] && arr[1][j - 1]) {
                ans -= merge(j + m, j + m + 1);
            }
        }
    }
    cout << ans;
}

signed main() {
#ifdef EXTRATERRESTRIAL_
    freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
#else
    //freopen(TASK".in", "r", stdin);
    //freopen(TASK".out", "w", stdout);
#endif
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    srand(time(0));
    source();
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long double ld;
typedef long long ll;

#define _ inline
#define f first
#define sec second
#define pb push_back
#define ins insert
#define ers erase
#define mk make_pair
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define rsz resize
//#define int ll
#define forn(i, n) for (register int i(1); i <= n; i++)
#define fore(i, n) for (register int i(0); i < n; i++)
#define endl "\n"

#define right rightt
#define left leftt
#define prev prevv
#define next nextt

const int INF = 1e9 + 10;
const int MOD = 1e9 + 7;
const int P = 239017;
const long long BINF = 1e18 + 10;

string get(char ch) {
    int a;
    if (ch >= '0' && ch <= '9') {
        a = ch - '0';
    }
    else {
        a = 10 + (ch - 'A');
    }
    string res;
    while (a) {
        if (a % 2 == 1) {
            res += "1";
        }
        else {
            res += "0";
        }
        a /= 2;
    }
    reverse(all(res));
    while (res.size() < 4) {
        res.ins(res.begin(), '0');
    }
    return res;
}

const int N = (1 << 15) + 10;

int p[N], rk[N];

void make(int v) {
    p[v] = v;
    rk[v] = 1;
}

int find(int v) {
    if (p[v] == v) {
        return v;
    }
    return p[v] = find(p[v]);
}

bool merge(int a, int b) {
    a = find(a), b = find(b);
    if (a == b) {
        return false;
    }
    if (rk[a] < rk[b]) {
        swap(a, b);
    }
    else if (rk[a] == rk[b]) {
        rk[a]++;
    }
    p[b] = a;
    return true;
}

_ void source() {
    int n, m, ans = 0;
    vector<int> arr[2];
    cin >> n >> m;
    forn(i, m / 4) {
        char ch;
        cin >> ch;
        string s = get(ch);
        for (int j = 0; j < s.size(); j++) {
            if (s[j] == '1') {
                ans++;
            }
            arr[0].pb(s[j] - '0');
            int a = arr[0].size();
            make(a);
        }
    }
    for (int i = 1; i < m; i++) {
        if (arr[0][i] && arr[0][i - 1]) {
            ans -= merge(i, i + 1);
        }
    }
    if (n == 1) {
        cout << ans;
        exit(0);
    }
    forn(i, m / 4) {
        char ch;
        cin >> ch;
        string s = get(ch);
        for (int j = 0; j < s.size(); j++) {
            if (s[j] == '1') {
                ans++;
            }
            arr[1].pb(s[j] - '0');
            int a = arr[1].size();
            make(a + m);
        }
    }
    for (int i = 0; i < m; i++) {
        if (arr[0][i] && arr[1][i]) {
            ans -= merge(i + 1, i + m + 1);
        }
        if (i && arr[1][i] && arr[1][i - 1]) {
            ans -= merge(i + m, i + m + 1);
        }
    }
    for (int i = 3; i <= n; i++) {
        int col[2 * m + 10];
        for (int j = 1; j <= 2 * m; j++) {
            col[j] = find(j);
        }
        for (int j = 1; j <= m; j++) {
            make(j);
        }
        for (int j = 1; j < m; j++) {
            if (arr[1][j] && arr[1][j - 1] && col[j + m] == col[j + m + 1]) {
                merge(j, j + 1);
            }
        }
        arr[0] = arr[1];
        arr[1].clear();
        for (int j = 0; j < m / 4; j++) {
            char ch;
            cin >> ch;
            string s = get(ch);
            for (int k = 0; k < s.size(); k++) {
                if (s[k] == '1') {
                    ans++;
                }
                arr[1].pb(s[k] - '0');
                int a = arr[1].size();
                make(a + m);
            }
        }
        for (int j = 0; j < m; j++) {
            if (arr[0][j] && arr[1][j]) {
                ans -= merge(j + 1, j + m + 1);
            }
            if (j && arr[1][j] && arr[1][j - 1]) {
                ans -= merge(j + m, j + m + 1);
            }
        }
    }
    cout << ans;
}

signed main() {
#ifdef EXTRATERRESTRIAL_
    freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
#else
    //freopen(TASK".in", "r", stdin);
    //freopen(TASK".out", "w", stdout);
#endif
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    srand(time(0));
    source();
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long double ld;
typedef long long ll;

#define _ inline
#define f first
#define sec second
#define pb push_back
#define ins insert
#define ers erase
#define mk make_pair
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define rsz resize
//#define int ll
#define forn(i, n) for (register int i(1); i <= n; i++)
#define fore(i, n) for (register int i(0); i < n; i++)
#define endl "\n"

#define right rightt
#define left leftt
#define prev prevv
#define next nextt

const int INF = 1e9 + 10;
const int MOD = 1e9 + 7;
const int P = 239017;
const long long BINF = 1e18 + 10;

string get(char ch) {
    int a;
    if (ch >= '0' && ch <= '9') {
        a = ch - '0';
    }
    else {
        a = 10 + (ch - 'A');
    }
    string res;
    while (a) {
        if (a % 2 == 1) {
            res += "1";
        }
        else {
            res += "0";
        }
        a /= 2;
    }
    reverse(all(res));
    while (res.size() < 4) {
        res.ins(res.begin(), '0');
    }
    //cout << res << endl;
    return res;
}

const int N = (1 << 15) + 10;

int p[N], rk[N];

void make(int v) {
    p[v] = v;
    rk[v] = 1;
}

int find(int v) {
    if (p[v] == v) {
        return v;
    }
    return p[v] = find(p[v]);
}

bool merge(int a, int b) {
    a = find(a), b = find(b);
    if (a == b) {
        return false;
    }
    if (rk[a] < rk[b]) {
        swap(a, b);
    }
    else if (rk[a] == rk[b]) {
        rk[a]++;
    }
    p[b] = a;
    return true;
}

_ void source() {
    int n, m, ans = 0;
    vector<int> arr[2];
    cin >> n >> m;
    forn(i, m / 4) {
        char ch;
        cin >> ch;
        string s = get(ch);
        //cout << s << endl;
        for (int j = 0; j < s.size(); j++) {
            if (s[j] == '1') {
                ans++;
            }
            arr[1].pb(s[j] - '0');
            int a = arr[1].size();
            make(a + m);
        }
    }
    for (int i = 1; i < m; i++) {
        if (arr[1][i] && arr[1][i - 1]) {
            ans -= merge(i + m, i + m + 1);
        }
    }
    for (int i = 2; i <= n; i++) {
        int col[2 * m + 10];
        vector<int> now(2 * m + 10);
        fill(all(now), 0);
        for (int j = 1; j <= 2 * m; j++) {
            col[j] = find(j);
        }
        for (int j = 1; j <= m; j++) {
            make(j);
            if (now[col[j + m]]) {
                merge(j, now[col[j + m]]);
            }
            else {
                now[col[j + m]] = j + m;
            }
        }
        arr[0] = arr[1];
        arr[1].clear();
        for (int j = 0; j < m / 4; j++) {
            char ch;
            cin >> ch;
            string s = get(ch);
            for (int k = 0; k < s.size(); k++) {
                if (s[k] == '1') {
                    ans++;
                }
                arr[1].pb(s[k] - '0');
                int a = arr[1].size();
                make(a + m);
            }
        }
        for (int j = 0; j < m; j++) {
            if (arr[0][j] && arr[1][j]) {
                ans -= merge(j + 1, j + m + 1);
            }
            if (j && arr[1][j] && arr[1][j - 1]) {
                ans -= merge(j + m, j + m + 1);
            }
        }
    }
    cout << ans;
}

signed main() {
#ifdef EXTRATERRESTRIAL_
    freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
#else
    //freopen(TASK".in", "r", stdin);
    //freopen(TASK".out", "w", stdout);
#endif
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    srand(time(0));
    source();
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long double ld;
typedef long long ll;

#define _ inline
#define f first
#define sec second
#define pb push_back
#define ins insert
#define ers erase
#define mk make_pair
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define rsz resize
//#define int ll
#define forn(i, n) for (register int i(1); i <= n; i++)
#define fore(i, n) for (register int i(0); i < n; i++)
#define endl "\n"

#define right rightt
#define left leftt
#define prev prevv
#define next nextt

const int INF = 1e9 + 10;
const int MOD = 1e9 + 7;
const int P = 239017;
const long long BINF = 1e18 + 10;

string get(char ch) {
    int a;
    if (ch >= '0' && ch <= '9') {
        a = ch - '0';
    }
    else {
        a = 10 + (ch - 'A');
    }
    string res;
    while (a) {
        if (a % 2 == 1) {
            res += "1";
        }
        else {
            res += "0";
        }
        a /= 2;
    }
    reverse(all(res));
    while (res.size() < 4) {
        res.ins(res.begin(), '0');
    }
    //cout << res << endl;
    return res;
}

const int N = (1 << 15) + 10;

int p[N], rk[N];

void make(int v) {
    p[v] = v;
    rk[v] = 1;
}

int find(int v) {
    if (p[v] == v) {
        return v;
    }
    return p[v] = find(p[v]);
}

bool merge(int a, int b) {
    a = find(a), b = find(b);
    if (a == b) {
        return false;
    }
    if (rk[a] < rk[b]) {
        swap(a, b);
    }
    else if (rk[a] == rk[b]) {
        rk[a]++;
    }
    p[b] = a;
    return true;
}

_ void source() {
    int n, m, ans = 0;
    vector<int> arr[2];
    cin >> n >> m;
    forn(i, m / 4) {
        char ch;
        cin >> ch;
        string s = get(ch);
        //cout << s << endl;
        for (int j = 0; j < s.size(); j++) {
            if (s[j] == '1') {
                ans++;
            }
            arr[1].pb(s[j] - '0');
            int a = arr[1].size();
            make(a + m);
        }
    }
    for (int i = 1; i < m; i++) {
        if (arr[1][i] && arr[1][i - 1]) {
            ans -= merge(i + m, i + m + 1);
        }
    }
    for (int i = 2; i <= n; i++) {
        int col[2 * m + 10];
        vector<int> now(2 * m + 10);
        fill(all(now), 0);
        for (int j = 1; j <= 2 * m; j++) {
            col[j] = find(j);
        }
        for (int j = 1; j <= 2 * m; j++) {
            make(j);
        }
        for (int j = 1; j <= m; j++) {
            if (!arr[1][j - 1]) {
                continue;
            }
            if (now[col[j + m]]) {
                //cout << j << endl;
                merge(j, now[col[j + m]]);
            }
            else {
                now[col[j + m]] = j;
            }
        }
        arr[0] = arr[1];
        arr[1].clear();
        for (int j = 0; j < m / 4; j++) {
            char ch;
            cin >> ch;
            string s = get(ch);
            for (int k = 0; k < s.size(); k++) {
                if (s[k] == '1') {
                    ans++;
                }
                arr[1].pb(s[k] - '0');
                int a = arr[1].size();
                make(a + m);
            }
        }
        for (int j = 0; j < m; j++) {
            if (arr[0][j] && arr[1][j]) {
                ans -= merge(j + 1, j + m + 1);
            }
            if (j && arr[1][j] && arr[1][j - 1]) {
                ans -= merge(j + m, j + m + 1);
            }
            //forn(j2, 2 * m) {cout << find(j2) << " ";};
            //cout << endl;
        }
    }
    cout << ans;
}

signed main() {
#ifdef EXTRATERRESTRIAL_
    freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
#else
    //freopen(TASK".in", "r", stdin);
    //freopen(TASK".out", "w", stdout);
#endif
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    srand(time(0));
    source();
    return 0;
}