#include <iostream>
#include <stdio.h>
using namespace std;

// 创建这个类是为了更好的理解，会比数组直观
class Point {
public:
    Point *parent;
};

// 获取当前位置的根
Point* get(Point* point) {

    if (point->parent != point) {
        // 优化数据结构，直接把自己的根直接指向获取到的根
        point->parent = get(point->parent);
        return point->parent;
    }

    return point;
}

// 尝试合并两个位置，如果本属于两个结合，则把右边的根的根指向左边的，也就是合并两个集合
int merge(Point* left, Point* right) {
    left = get(left);
    right = get(right);

    if (left == right) {
        return 0;
    }

    right->parent = left;
    return 1;
}

int value[1024*16];
int lastValue[1024*16];
char s[1024*16];
Point *root;
Point *lastRoot;

int main(int argc, const char * argv[]) {

    int n, m, sum = 0;
    scanf("%d %d",&n,&m);

    for (int row=0; row<n; ++row) {
        // 读取数据，转成2进制
        scanf("%s", s);
        for (int index=0; index<m/4; ++index) {
            char c = s[index];
            if (c >= 'A') {
                c = c - 'A' + '9' + 1;
            }

            value[index*4+0] = (c&8)>0?1:0;
            value[index*4+1] = (c&4)>0?1:0;
            value[index*4+2] = (c&2)>0?1:0;
            value[index*4+3] = (c&1)>0?1:0;
        }

        root = new Point[1024*16];
        for (int index=0; index<m; ++index) {

            root[index].parent = &root[index];

            if (value[index] == 0) {
                continue;
            }
            sum ++;

            // 尝试与左边合并
            if (index > 0 && value[index-1] == 1) {
                sum -= merge(&root[index-1], &root[index]);
            }

            // 尝试与上边合并
            if (row > 0 && lastValue[index] == 1) {
                sum -= merge(&root[index], &lastRoot[index]);
            }
        }

        // 数组滚动，把当前行的值给上一行，下次循环会新读取并计算当前行数据
        for (int index=0; index<m; ++index) {
            lastValue[index] = value[index];
        }

        // 滚动数组，存储根
        delete []lastRoot;
        lastRoot = root;
    }

    cout<<sum<<endl;

    return 0;
}


#include<iostream>
#include<string.h>
using namespace std;
int n,m,common,lastnum=0,nownum=0,ans=0;
char num[10];
inline int countnum(char num[]){
	int ans=0,flag=1;
	for(int i=strlen(num)-1;i>=0;i--){
		if(num[i]<='9'&&num[i]>='0')ans+=flag*(num[i]-'0');
		else ans+=flag*(num[i]-'A'+10);
		flag*=16;
	}
	return ans;
}
inline int count_part(int n){
	int total=0,flag=0,times=0;
	while(n&&times++<m){
		if((n&1)&&!flag){flag=1;total++;}
		else if((n&1)==0)flag=0;
		n>>=1;
	}
	return total;
}
int main(){
	cin>>n>>m>>num;
	lastnum=countnum(num);
	ans+=count_part(lastnum);
	for(int i=1;i<n;i++){cin>>num;
		nownum=countnum(num);
		common=(lastnum&nownum);
		ans+=count_part(nownum)-count_part(common);
		lastnum=nownum;
		nownum=0;
	}
	cout<<ans<<endl;
}


#include <iostream>
#include <stdio.h>
using namespace std;

// 创建这个类是为了更好的理解，会比数组直观
class Point {
public:
    Point *parent;
};

// 获取当前位置的根
Point* get(Point* point) {

    if (point->parent != point) {
        // 优化数据结构，直接把自己的根直接指向获取到的根
        point->parent = get(point->parent);
        return point->parent;
    }

    return point;
}

// 尝试合并两个位置，如果本属于两个结合，则把右边的根的根指向左边的，也就是合并两个集合
int merge(Point* left, Point* right) {
    left = get(left);
    right = get(right);

    if (left == right) {
        return 0;
    }

    right->parent = left;
    return 1;
}

int value[1024*16];
int lastValue[1024*16];
char s[1024*16];
Point *root;
Point *lastRoot;

int main(int argc, const char * argv[]) {

    int n, m, sum = 0;
    cin>>n>>m;

    for (int row=0; row<n; ++row) {
        // 读取数据，转成2进制
        scanf("%s", s);
        for (int index=0; index<m/4; ++index) {
            char c = s[index];
            if (c >= 'A') {
                c = c - 'A' + '9' + 1;
            }

            value[index*4+0] = (c&8)>0?1:0;
            value[index*4+1] = (c&4)>0?1:0;
            value[index*4+2] = (c&2)>0?1:0;
            value[index*4+3] = (c&1)>0?1:0;
        }

        root = new Point[1024*16];
        for (int index=0; index<m; ++index) {

            root[index].parent = &root[index];

            if (value[index] == 0) {
                continue;
            }
            sum ++;

            // 尝试与左边合并
            if (index > 0 && value[index-1] == 1) {
                sum -= merge(&root[index-1], &root[index]);
            }

            // 尝试与上边合并
            if (row > 0 && lastValue[index] == 1) {
                sum -= merge(&root[index], &lastRoot[index]);
            }
        }

        // 数组滚动，把当前行的值给上一行，下次循环会新读取并计算当前行数据
        for (int index=0; index<m; ++index) {
            lastValue[index] = value[index];
        }

        // 滚动数组，存储根
        delete []lastRoot;
        lastRoot = root;
    }

    cout<<sum<<endl;

    return 0;
}


#include<iostream>
#include<string>
using namespace std;
inline int countnum(char num[]){
	int ans=0,flag=1;
	for(int i=strlen(num)-1;i>=0;i--){
		if(num[i]<='9'&&num[i]>='0')ans+=flag*(num[i]-'0');
		else ans+=flag*(num[i]-'A'+10);
		flag*=16;
	}
	return ans;
}
inline int count_part(int n){
	int total=0,flag=0;
	while(n){
		if((n&1)&&!flag){flag=1;total++;}
		if((n&1)==0){flag=0;}
		n>>=1;
	}
	return total;
}
int main(){
	int n,m,lastnum=0,nownum=0,ans=0;
	char num[5];
	cin>>n>>m>>num;
	lastnum=countnum(num);
	ans+=count_part(lastnum);
	for(int i=1;i<n;i++){
		cin>>num;
		nownum=countnum(num);
		int common=lastnum&nownum;
		ans+=count_part(nownum)-count_part(common);
		lastnum=nownum;
		nownum=0;
	}
	cout<<ans<<endl;
}


#include <bits/stdc++.h>
using namespace std;
int f[1<<15+1];
bool num[2][1<<14+1];
char s[1<<14+1];
int find(int x) { return x == f[x] ? x : f[x] = find(f[x]); }
int main()
{
    int n, m, sum = 0, unsum = 0;
    scanf("%d%d", &n, &m);
    for(int i = 0; i <= m*2; i++) f[i] = i;
    for(int i = 0; i < n; i++)
    {
        int now = i&1;
        scanf("%s", s);
        int cnt = 0;
        for(int j = 0; j < m/4; j++)
        {
            int tmp;
            if(s[j] >= 'A' && s[j] <= 'F')  tmp = 10+s[j]-'A';
            else                            tmp = s[j]-'0';
            for(int j = 3; j >= 0; j--)
            {
                num[now][cnt+j] = (tmp&1);
                tmp >>= 1;
            }
            cnt += 4;
        }
        for(int j = 0; j < m; j++)  f[j+now*m] = j+now*m;
        for(int j = 0; j < m; j++)
        {
            if(num[now][j]) sum++;
            if(num[now][j] && num[now^1][j])
            {
                int t1 = find(now*m+j), t2 = find((now^1)*m+j);
                if(t1 != t2)
                {
                    f[t2] = t1;
                    sum--;
                }
            }
        }
        for(int j = 0; j < m-1; j++)
        {
            if(num[now][j] && num[now][j+1])
            {
                int t1 = find(now*m+j), t2 = find(now*m+j+1);
                if(t1 != t2)
                {
                    f[t1] = t2;
                    sum--;
                }
            }
        }
    }
    printf("%d\n", sum);
}


#include <bits/stdc++.h>
using namespace std;
int f[1<<15+1];
bool num[2][1<<14+1];
char s[1<<14+1];
int find(int x) { return x == f[x] ? x : f[x] = find(f[x]); }
int main()
{
    int n, m, sum = 0, unsum = 0;
    scanf("%d%d", &n, &m);
    for(int i = 0; i <= m*2; i++) f[i] = i;
    for(int i = 0; i < n; i++)
    {
        int now = i&1;
        scanf("%s", s);
        int cnt = 0;
        for(int j = 0; j < m/4; j++)
        {
            int tmp;
            if(s[j] >= 'A' && s[j] <= 'F')  tmp = 10+s[j]-'A';
            else                            tmp = s[j]-'0';
            for(int j = 3; j >= 0; j--)
            {
                sum += (tmp&1);
                num[now][cnt+j] = (tmp&1);
                tmp >>= 1;
            }
            cnt += 4;
        }
        for(int j = 0; j < m; j++)  f[j+now*m] = j+now*m;
        for(int j = 0; j < m-1; j++)
        {
            if(num[now][j] && num[now][j+1])
            {
                int t1 = find(now*m+j), t2 = find(now*m+j+1);
                if(t1 != t2)
                {
                    f[t2] = t1;
                    sum--;
                }
            }
        }
        for(int j = 0; j < m; j++)
        {
            if(num[now][j] && num[now^1][j])
            {
                int t1 = find(now*m+j), t2 = find((now^1)*m+j);
                if(t1 != t2)
                {
                    f[t1] = t2;
                    sum--;
                }
            }
        }
    }
    printf("%d\n", sum);
}


#include <bits/stdc++.h>
using namespace std;
bool flag[1<<14];
int f[2][1<<14], num[2][1<<14];
int find(int x, int ind) { return x == f[ind][x] ? x : f[ind][x] = find(f[ind][x], ind); }
int main()
{
    int n, m, sum = 0, unsum = 0;
    cin >> n >> m;
    for(int i = 0; i <= m; i++) f[0][i] = f[1][i] = i;
    for(int i = 0; i < n; i++)
    {
        string s;
        cin >> s;
        int cnt = 0;
        for(auto ch:s)
        {
            int tmp;
            if(ch >= 'A' && ch <= 'F')  tmp = 10+ch-'A';
            else                        tmp = ch-'0';
            for(int j = 3; j >= 0; j--)
            {
                num[0][cnt+j] = (tmp&1);
                tmp >>= 1;
            }
            cnt += 4;
        }
        for(int j = 0; j < m; j++)
        {
            f[0][j] = j;
            if(num[0][j])   sum++;
            if(num[0][j] && num[1][j])
            {
                f[0][find(j, 0)] = find(j, 1);
                unsum++;
            }
            if(j > 0 && num[0][j] && num[0][j-1])
            {
                if(find(j, 0) != find(j-1, 0))
                {
                    f[0][find(j, 0)] = find(j-1, 0);
                    unsum++;
                }
            }
        }
        for(int j = 0; j < m; j++)
        {
            f[1][j] = f[0][j];
            num[1][j] = num[0][j];
        }
    }
    cout << sum-unsum << endl;
}


#include <bits/stdc++.h>
using namespace std;
int f[1<<15+1];
bool num[2][1<<14+1];
char s[1<<14+1];
int find(int x) { return x == f[x] ? x : f[x] = find(f[x]); }
int main()
{
    int n, m, sum = 0, unsum = 0;
    scanf("%d%d", &n, &m);
    for(int i = 0; i <= m*2; i++) f[i] = i;
    for(int i = 0; i < n; i++)
    {
        int now = i&1;
        scanf("%s", s);
        int cnt = 0;
        for(int j = 0; j < m/4; j++)
        {
            int tmp;
            if(s[j] >= 'A' && s[j] <= 'F')  tmp = 10+s[j]-'A';
            else                            tmp = s[j]-'0';
            for(int j = 3; j >= 0; j--)
            {
                num[now][cnt+j] = (tmp&1);
                tmp >>= 1;
            }
            cnt += 4;
        }
        for(int j = 0; j < m; j++)  f[j+now*m] = j+now*m;
        for(int j = 0; j < m; j++)
        {
            if(num[now][j]) sum++;
            if(num[now][j] && num[now^1][j])
            {
                int t1 = find(now*m+j), t2 = find((now^1)*m+j);
                if(t1 != t2)
                {
                    f[t1] = t2;
                    sum--;
                }
            }
        }
        for(int j = 0; j < m-1; j++)
        {
            if(num[now][j] && num[now][j+1])
            {
                int t1 = find(now*m+j), t2 = find(now*m+j+1);
                if(t1 != t2)
                {
                    f[t1] = t2;
                    sum--;
                }
            }
        }
    }
    printf("%d\n", sum);
}


#include <bits/stdc++.h>
using namespace std;
int f[2][1<<14];
bool num[2][1<<14];
int find(int x, int ind) { return x == f[ind][x] ? x : f[ind][x] = find(f[ind][x], ind); }
int main()
{
    int n, m, sum = 0, unsum = 0;
    cin >> n >> m;
    for(int i = 0; i <= m; i++) f[0][i] = f[1][i] = i;
    for(int i = 0; i < n; i++)
    {
        string s;
        cin >> s;
        int cnt = 0;
        for(auto ch:s)
        {
            int tmp;
            if(ch >= 'A' && ch <= 'F')  tmp = 10+ch-'A';
            else                        tmp = ch-'0';
            for(int j = 3; j >= 0; j--)
            {
                num[0][cnt+j] = (tmp&1);
                tmp >>= 1;
            }
            cnt += 4;
        }
        for(int j = 0; j < m; j++)
        {
            if(num[0][j])   sum++;
            if(num[0][j] && num[1][j])
            {
                f[0][find(j, 0)] = find(j, 1);
                unsum++;
            }
            if(j > 0 && num[0][j] && num[0][j-1])
            {
                if(find(j, 0) != find(j-1, 0))
                {
                    f[0][find(j, 0)] = find(j-1, 0);
                    unsum++;
                }
            }
        }
        for(int j = 0; j < m; j++)
        {
            f[1][j] = f[0][j];
            num[1][j] = num[0][j];
            f[0][j] = j;
        }
    }
    cout << sum-unsum << endl;
}


#include <bits/stdc++.h>
using namespace std;
bool flag[1<<14];
int f[2][1<<14], num[2][1<<14];
int find(int x, int ind) { return x == f[ind][x] ? x : f[ind][x] = find(f[ind][x], ind); }
int main()
{
    int n, m, sum = 0, unsum = 0;
    cin >> n >> m;
    for(int i = 0; i <= m; i++) f[0][i] = f[1][i] = i;
    for(int i = 0; i < n; i++)
    {
        string s;
        cin >> s;
        int cnt = 0;
        for(auto ch:s)
        {
            int tmp;
            if(ch >= 'A' && ch <= 'F')  tmp = 10+ch-'A';
            else                        tmp = ch-'0';
            for(int j = 3; j >= 0; j--)
            {
                num[0][cnt+j] = (tmp&1);
                tmp >>= 1;
            }
            cnt += 4;
        }
        for(int j = 0; j < m; j++)
        {
            if(num[0][j])   sum++;
            if(num[0][j] && num[1][j])
            {
                f[0][find(j, 0)] = find(j, 1);
                unsum++;
            }
            if(j > 0 && num[0][j] && num[0][j-1])
            {
                if(find(j, 0) != find(j-1, 0))
                {
                    f[0][find(j, 0)] = find(j-1, 0);
                    unsum++;
                }
            }
        }
        for(int j = 0; j < m; j++)
        {
            f[1][j] = f[0][j];
            num[1][j] = num[0][j];
            f[0][j] = j;
        }
    }
    cout << sum-unsum << endl;
}


#include <bits/stdc++.h>
using namespace std;
int f[1<<15+1];
bool num[2][1<<14+1];
char s[1<<14+1];
int find(int x) { return x == f[x] ? x : f[x] = find(f[x]); }
int main()
{
    int n, m, sum = 0, unsum = 0;
    scanf("%d%d", &n, &m);
    for(int i = 0; i <= m*2; i++) f[i] = i;
    for(int i = 0; i < n; i++)
    {
        int now = i&1;
        scanf("%s", s);
        int cnt = 0;
        for(int j = 0; j < m/4; j++)
        {
            int tmp;
            if(s[j] >= 'A' && s[j] <= 'F')  tmp = 10+s[j]-'A';
            else                            tmp = s[j]-'0';
            for(int j = 3; j >= 0; j--)
            {
                sum += (tmp&1);
                num[now][cnt+j] = (tmp&1);
                tmp >>= 1;
            }
            cnt += 4;
        }
        for(int j = 0; j < m; j++)  f[j+now*m] = j+now*m;
        for(int j = 0; j < m-1; j++)
        {
            if(num[now][j] && num[now][j+1])
            {
                int t1 = find(now*m+j), t2 = find(now*m+j+1);
                if(t1 != t2)
                {
                    f[t2] = t1;
                    sum--;
                }
            }
        }
        for(int j = 0; j < m; j++)
        {
            if(num[now][j] && num[now^1][j])
            {
                int t1 = find(now*m+j), t2 = find((now^1)*m+j);
                if(t1 != t2)
                {
                    f[t2] = t1;
                    sum--;
                }
            }
        }
    }
    printf("%d\n", sum);
}


#include <bits/stdc++.h>
using namespace std;
int f[1<<15+1];
bool num[2][1<<14+1];
char s[1<<14+1];
int find(int x) { return x == f[x] ? x : f[x] = find(f[x]); }
int main()
{
    int n, m, sum = 0, unsum = 0;
    scanf("%d%d", &n, &m);
    for(int i = 0; i <= m*2; i++) f[i] = i;
    for(int i = 0; i < n; i++)
    {
        int now = i&1;
        scanf("%s", s);
        int cnt = 0;
        for(int j = 0; j < m/4; j++)
        {
            int tmp;
            if(s[j] >= 'A' && s[j] <= 'F')  tmp = 10+s[j]-'A';
            else                            tmp = s[j]-'0';
            for(int j = 3; j >= 0; j--)
            {
                sum += (tmp&1);
                num[now][cnt+j] = (tmp&1);
                tmp >>= 1;
            }
            cnt += 4;
        }
        for(int j = 0; j < m; j++)  f[j+now*m] = j+now*m;
        for(int j = 0; j < m; j++)
        {
            if(num[now][j] && num[now^1][j])
            {
                int t1 = find(now*m+j), t2 = find((now^1)*m+j);
                if(t1 != t2)
                {
                    f[t1] = t2;
                    sum--;
                }
            }
        }
        for(int j = 0; j < m-1; j++)
        {
            if(num[now][j] && num[now][j+1])
            {
                int t1 = find(now*m+j), t2 = find(now*m+j+1);
                if(t1 != t2)
                {
                    f[t2] = t1;
                    sum--;
                }
            }
        }
    }
    printf("%d\n", sum);
}


#include <bits/stdc++.h>
using namespace std;
int f[1<<15+1];
bool num[2][1<<14+1];
char s[1<<14+1];
int find(int x) { return x == f[x] ? x : f[x] = find(f[x]); }
int main()
{
    int n, m, sum = 0, unsum = 0;
    scanf("%d%d", &n, &m);
    for(int i = 0; i <= m*2; i++) f[i] = i;
    for(int i = 0; i < n; i++)
    {
        int now = i&1;
        scanf("%s", s);
        int cnt = 0;
        for(int j = 0; j < m/4; j++)
        {
            int tmp;
            if(s[j] >= 'A' && s[j] <= 'F')  tmp = 10+s[j]-'A';
            else                            tmp = s[j]-'0';
            for(int j = 3; j >= 0; j--)
            {
                num[now][cnt+j] = (tmp&1);
                tmp >>= 1;
            }
            cnt += 4;
        }
        for(int j = 0; j < m; j++)  f[j+now*m] = j+now*m;
        for(int j = 0; j < m-1; j++)
        {
            if(num[now][j] && num[now][j+1])
            {
                int t1 = find(now*m+j), t2 = find(now*m+j+1);
                if(t1 != t2)
                {
                    f[t1] = t2;
                    sum--;
                }
            }
        }
        for(int j = 0; j < m; j++)
        {
            if(num[now][j]) sum++;
            if(num[now][j] && num[now^1][j])
            {
                int t1 = find(now*m+j), t2 = find((now^1)*m+j);
                if(t1 != t2)
                {
                    f[t2] = t1;
                    sum--;
                }
            }
        }
    }
    printf("%d\n", sum);
}


#include <bits/stdc++.h>
using namespace std;
int f[1<<15+1];
bool num[2][1<<14+1];
char s[1<<14+1];
int find(int x) { return x == f[x] ? x : f[x] = find(f[x]); }
int main()
{
    int n, m, sum = 0, unsum = 0;
    scanf("%d%d", &n, &m);
    for(int i = 0; i <= m*2; i++) f[i] = i;
    for(int i = 0; i < n; i++)
    {
        int now = i&1;
        scanf("%s", s);
        int cnt = 0;
        for(int j = 0; j < m/4; j++)
        {
            int tmp;
            if(s[j] >= 'A' && s[j] <= 'F')  tmp = 10+s[j]-'A';
            else                            tmp = s[j]-'0';
            for(int j = 3; j >= 0; j--)
            {
                sum += (tmp&1);
                num[now][cnt+j] = (tmp&1);
                tmp >>= 1;
            }
            cnt += 4;
        }
        for(int j = 0; j < m; j++)  f[j+now*m] = j+now*m;
        for(int j = 0; j < m-1; j++)
        {
            if(num[now][j] && num[now][j+1])
            {
                int t1 = find(now*m+j), t2 = find(now*m+j+1);
                if(t1 != t2)
                {
                    f[t1] = t2;
                    sum--;
                }
            }
        }
        for(int j = 0; j < m; j++)
        {
            if(num[now][j] && num[now^1][j])
            {
                int t1 = find(now*m+j), t2 = find((now^1)*m+j);
                if(t1 != t2)
                {
                    f[t1] = t2;
                    sum--;
                }
            }
        }
    }
    printf("%d\n", sum);
}


#include <bits/stdc++.h>
using namespace std;
int num[2][20];
int main()
{
    int n, m, sum = 0;
    scanf("%d%d", &n, &m);
    for(int i = 0; i < n; i++)
    {
        int x, cnt = 0;
        cin >> hex >> x;
        while(x)
        {
            if(x&1)
            {
                if(cnt == 0 || i == 0)
                {
                    if(cnt == 0 && i == 0)
                    {
                        sum++;
                    }
                    else if(cnt == 0)
                    {
                        if(num[0][cnt] == 0)
                            sum++;
                    }
                    else if(i == 0)
                    {
                        if(num[1][cnt-1] == 0)
                            sum++;
                    }
                }
                else
                {
                    if(num[0][i] == 0 && num[1][cnt-1] == 0)
                        sum++;
                }
                num[1][cnt] = 1;
            }
            else num[1][cnt] = 0;
            x >>= 1;
            cnt++;
        }
        for(int gg = 0; gg < cnt; gg++)
        {
            num[0][gg] = num[1][gg];
        }
    }
    cout << sum << endl;
}


/*input
2 8
5F
E3
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
int pa[32768];
int root(int i)
{
	if (pa[i] == i)
		return i;
	return pa[i] = root(pa[i]);
}
void merge(int x, int y)
{
	pa[root(x)] = root(y);
}
bool X[16384];
bool S[16384];
bool nenaudojami[16384];
int x[32768];
int y[32768];
int main()
{
	ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0), cerr.tie(0);
	int n, m;
	cin >> n >> m;
	for (int i = 0; i < 32768; i++)
		pa[i] = i;
	int ans = 0;
	for (int t = 0; t < n; t++)
	{
		string s;
		cin >> s;
		for (int i = 0; i < m / 4; i++)
		{
			int nr;
			if (s[i] >= 'A' && s[i] <= 'F')
				nr = s[i] - 'A' + 10;
			else
				nr = s[i] - '0';
			S[4 * i + 3] = nr % 2;
			nr /= 2;
			S[4 * i + 2] = nr % 2;
			nr /= 2;
			S[4 * i + 1] = nr % 2;
			nr /= 2;
			S[4 * i + 0] = nr % 2;
		}
		for (int i = 0; i < m; i++)
		{
			if (S[i] && X[i])
			{
				merge(i, i + m);
			}
		}
		for (int i = 1; i < m; i++)
		{
			if (S[i] && S[i - 1])
			{
				merge(i + m - 1, i + m);
			}
		}
		fill_n(nenaudojami, m, true);
		for (int i = 0; i < m; i++)
		{
			if (root(m + i) < m)
				nenaudojami[root(m + i)] = false;
		}
		for (int i = 0; i < m; i++)
			if (X[i] && nenaudojami[i] && (root(i) == i))
			{
				ans++;
			}

		for (int i = 0; i < m; i++)
			y[i] = root(i + m);
		for (int i = 0; i < m; i++)
			x[y[i]] = i;
		for (int i = 0; i < m; i++)
			pa[i] = x[y[i]];
		for (int i = m; i < 2 * m; i++)
			pa[i] = i;

		if (t == n - 1)
		{
			for (int i = 0; i < m; i++)
			{
				ans += (S[i] && (root(i) == i));
			}
		}
		for (int i = 0; i < m; i++)
			X[i] = S[i];
	}
	cout << ans << "\n";
}


/*input
2 8
5F
E3
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
int pa[32768];
int root(int i)
{
	if (pa[i] == i)
		return i;
	return pa[i] = root(pa[i]);
}
void merge(int x, int y)
{
	pa[root(x)] = root(y);
}
bool X[16384];
bool S[16384];
int main()
{
	ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0), cerr.tie(0);
	int n, m;
	cin >> n >> m;
	for (int i = 0; i < 32768; i++)
		pa[i] = i;
	int ans = 0;
	for (int t = 0; t < n; t++)
	{
		string s;
		cin >> s;
		for (int i = 0; i < m / 4; i++)
		{
			int nr;
			if (s[i] >= 'A' && s[i] <= 'F')
				nr = s[i] - 'A' + 10;
			else
				nr = s[i] - '0';
			S[4 * i + 3] = nr % 2;
			nr /= 2;
			S[4 * i + 2] = nr % 2;
			nr /= 2;
			S[4 * i + 1] = nr % 2;
			nr /= 2;
			S[4 * i + 0] = nr % 2;
		}
		for (int i = 0; i < m; i++)
		{
			if (S[i] && X[i])
			{
				merge(i, i + m);
			}
		}
		for (int i = 1; i < m; i++)
		{
			if (S[i] && S[i - 1])
			{
				merge(i + m - 1, i + m);
			}
		}
		bool nenaudojami[m];
		fill_n(nenaudojami, m, true);
		for (int i = 0; i < m; i++)
		{
			if (root(m + i) < m)
				nenaudojami[root(m + i)] = false;
		}
		for (int i = 0; i < m; i++)
			if (X[i] && nenaudojami[i] && (root(i) == i))
			{
				ans++;
			}
		vector<int> saknis[2 * m];
		for (int i = 0; i < m; i++)
			saknis[root(i + m)].push_back(i);
		for (int i = 0; i < 2 * m; i++)
			pa[i] = i;
		for (int i = 0; i < 2 * m; i++)
		{
			for (int j : saknis[i])
			{
				pa[j] = saknis[i][0];
			}
		}
		if (t == n - 1)
		{
			for (int i = 0; i < m; i++)
			{
				ans += (S[i] && (root(i) == i));
			}
		}
		for (int i = 0; i < m; i++)
			X[i] = S[i];
	}
	cout << ans << "\n";
}


/*input
2 8
5F
E3
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
int pa[32768];
int root(int i)
{
	if (pa[i] == i)
		return i;
	return pa[i] = root(pa[i]);
}
void merge(int x, int y)
{
	pa[root(x)] = root(y);
}
bool X[16384];
bool S[16384];
int main()
{
	ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0), cerr.tie(0);
	int n, m;
	cin >> n >> m;
	for (int i = 0; i < 32768; i++)
		pa[i] = i;
	int ans = 0;
	string x(m / 4, '0');
	for (int t = 0; t < n; t++)
	{
		string s;
		cin >> s;
		for (int i = 0; i < m / 4; i++)
		{
			int nr;
			if (s[i] >= 'A' && s[i] <= 'F')
				nr = s[i] - 'A' + 10;
			else
				nr = s[i] - '0';
			S[4 * i + 3] = nr % 2;
			nr /= 2;
			S[4 * i + 2] = nr % 2;
			nr /= 2;
			S[4 * i + 1] = nr % 2;
			nr /= 2;
			S[4 * i + 0] = nr % 2;
		}
		for (int i = 0; i < m / 4; i++)
		{
			int nr;
			if (x[i] >= 'A' && x[i] <= 'F')
				nr = x[i] - 'A' + 10;
			else
				nr = x[i] - '0';
			X[4 * i + 3] = nr % 2;
			nr /= 2;
			X[4 * i + 2] = nr % 2;
			nr /= 2;
			X[4 * i + 1] = nr % 2;
			nr /= 2;
			X[4 * i + 0] = nr % 2;
		}
		for (int i = 0; i < m; i++)
		{
			if (S[i] && X[i])
			{
				merge(i, i + m);
			}
		}
		for (int i = 1; i < m; i++)
		{
			if (S[i] && S[i - 1])
			{
				merge(i + m - 1, i + m);
			}
		}
		bool nenaudojami[m];
		fill_n(nenaudojami, m, true);
		for (int i = 0; i < m; i++)
		{
			if (root(m + i) < m)
				nenaudojami[root(m + i)] = false;
		}
		for (int i = 0; i < m; i++)
			if (X[i] && nenaudojami[i] && (root(i) == i))
			{
				ans++;
			}
		vector<int> saknis[2 * m];
		for (int i = 0; i < m; i++)
			saknis[root(i + m)].push_back(i);
		for (int i = 0; i < 2 * m; i++)
			pa[i] = i;
		for (int i = 0; i < 2 * m; i++)
		{
			for (int j : saknis[i])
			{
				pa[j] = saknis[i][0];
			}
		}
		if (t == n - 1)
		{
			for (int i = 0; i < m; i++)
			{
				ans += (S[i] && (root(i) == i));
			}
		}

		x = s;
	}
	cout << ans << "\n";
}


#pragma GCC optimize ("Ofast")
#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
// #define int long long int
#define pb push_back
#define fi first
#define se second
#define fr(i, a, b) for(int i = a; i <= b; i++)
#define all(x) x.begin(), x.end()
#define IO ios :: sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define pii pair<int,int>
const int mod = 1e9 + 7;
const int mod1 = 998244353;
typedef long double f80;
#ifndef LOCAL
#define endl '\n'
#endif
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

const int N = 16500;
int comp[N], comp1[N], dsu[N];
bitset<N> b;
int root(int u){
    return (dsu[u] == u) ? u : (dsu[u] = root(dsu[u]));
}
int n, m;
bool uni(int u,int v){
    assert(u <= 4 * m);
    assert(v <= 4 * m);
    u = root(u), v = root(v);
    if(u == v) return 0;
    dsu[root(u)] = root(v);
    return 1;
}
vector<int> cp;
void solve(){
    cin >> n >> m;
    m /= 4;
    int ans = 0;
    fr(i, 1, n){
        b.reset();
        fr(j, 1, m){ // good
            int c = 4 * j, x;
            char ch;
            cin >> ch;
            if(ch >= '0' && ch <= '9') x = ch - '0';
            else x = 10 + ch - 'A';
            while(x){
                b[c--] = (x & 1);
                x >>= 1;
            }
        }
        if(i == 1){
            fr(j, 1, 4 * m){
                if(b[j]){
                    int r = j;
                    while(b[r]) r++;
                    r--;
                    ans++;
                    fr(k, j, r)
                        comp[k] = ans;
                    j = r;
                }
            }
        }
        else{
            int maxi = 1;
            fr(j, 1, 4 * m){
                comp1[j] = 0;
                dsu[j] = j;
                if(comp[j]) maxi = max(maxi, comp[j]);
            }
            fr(j, 1, 4 * m){
                if(b[j]){
                    int r = j, p = -1;
                    while(b[r]){
                        if(comp[r]){
                            if(p != -1)
                                ans -= uni(p, comp[r]);
                            p = comp[r];
                        }
                        r++;
                    }
                    if(p == -1)
                        comp1[j] = ++maxi, ans++;
                    j = r;
                }
            }
            fr(j, 1, 4 * m){
                if(comp[j] && b[j]) comp1[j] = root(comp[j]);
            }
            fr(j, 1, 4 * m){
                if(comp1[j]){
                    int r = j;
                    while(b[r]){
                        comp1[r] = comp1[j];
                        r--;
                    }
                    r = j;
                    while(b[r]){
                        comp1[r] = comp1[j];
                        r++;
                    }
                    j = r;
                }
            }
            sort(all(cp));
            unique(all(cp));
            fr(j, 1, 4 * m){
                if(comp1[i])
                {
                    int val = 1 + lower_bound(all(cp), comp1[i]) - cp.begin();
                    comp1[i] = val;
                }
                comp[j] = comp1[j];
            }
            cp.clear();
        }
    }
    cout << ans;
}
signed main()
{
    IO;
    #ifdef LOCAL
     freopen("inp.txt", "r", stdin);
     // freopen("out.txt", "w", stdout);
    #endif
    clock_t clk = clock();
    int t;
    // cin >> t;
    t = 1;
    fr(i, 1, t){
        solve();
    }
    cerr << endl << setprecision(10) << fixed << (double)(clock() - clk) / CLOCKS_PER_SEC;
    return 0;
}


#pragma GCC optimize ("Ofast")
#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
// #define int long long int
#define pb push_back
#define fi first
#define se second
#define fr(i, a, b) for(int i = a; i <= b; i++)
#define all(x) x.begin(), x.end()
#define IO ios :: sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define pii pair<int,int>
const int mod = 1e9 + 7;
const int mod1 = 998244353;
typedef long double f80;
#ifndef LOCAL
#define endl '\n'
#endif
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

const int N = 16500;
int comp[N], comp1[N], dsu[N];
bitset<N> b;
int root(int u){
    return (dsu[u] == u) ? u : (dsu[u] = root(dsu[u]));
}
bool uni(int u,int v){
    u = root(u), v = root(v);
    if(u == v) return 0;
    dsu[root(u)] = root(v);
    return 1;
}
vector<int> cp;
void solve(){
    int n, m;
    cin >> n >> m;
    m /= 4;
    int ans = 0;
    fr(i, 1, n){
        b.reset();
        fr(j, 1, m){ // good
            int c = 4 * j, x;
            char ch;
            cin >> ch;
            if(ch >= '0' && ch <= '9') x = ch - '0';
            else x = 10 + ch - 'A';
            while(x){
                b[c--] = (x & 1);
                x >>= 1;
            }
        }
        if(i == 1){
            fr(j, 1, 4 * m){
                if(b[j]){
                    int r = j;
                    while(b[r]) r++;
                    r--;
                    ans++;
                    fr(k, j, r)
                        comp[k] = ans;
                    j = r;
                }
            }
        }
        else{
            int maxi = 1;
            fr(j, 1, 4 * m){
                comp1[j] = 0;
                dsu[j] = j;
                if(comp[j]) maxi = max(maxi, comp[j]);
            }
            fr(j, 1, 4 * m){
                if(b[j]){
                    int r = j, p = -1;
                    while(b[r]){
                        if(comp[r]){
                            if(p != -1)
                                ans -= uni(p, comp[r]);
                            p = comp[r];
                        }
                        r++;
                    }
                    if(p == -1)
                        comp1[j] = ++maxi, ans++;
                    j = r;
                }
            }
            fr(j, 1, 4 * m){
                if(comp[j] && b[j]) comp1[j] = root(comp[j]);
            }
            fr(j, 1, 4 * m){
                if(comp1[j]){
                    int r = j;
                    while(b[r]){
                        comp1[r] = comp1[j];
                        r--;
                    }
                    r = j;
                    while(b[r]){
                        comp1[r] = comp1[j];
                        r++;
                    }
                    j = r;
                    cp.pb(comp1[j]);
                }
            }
            sort(all(cp));
            unique(all(cp));
            fr(j, 1, 4 * m){
                if(comp1[i])
                {
                    int val = 1 + lower_bound(all(cp), comp1[i]) - cp.begin();
                    comp1[i] = val;
                }
                comp[j] = comp1[j];
            }
            cp.clear();
        }
    }
    cout << ans;
}
signed main()
{
    IO;
    #ifdef LOCAL
     freopen("inp.txt", "r", stdin);
     // freopen("out.txt", "w", stdout);
    #endif
    clock_t clk = clock();
    int t;
    // cin >> t;
    t = 1;
    fr(i, 1, t){
        solve();
    }
    cerr << endl << setprecision(10) << fixed << (double)(clock() - clk) / CLOCKS_PER_SEC;
    return 0;
}


#pragma GCC optimize ("Ofast")
#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
// #define int long long int
#define pb push_back
#define fi first
#define se second
#define fr(i, a, b) for(int i = a; i <= b; i++)
#define all(x) x.begin(), x.end()
#define IO ios :: sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define pii pair<int,int>
const int mod = 1e9 + 7;
const int mod1 = 998244353;
typedef long double f80;
#ifndef LOCAL
#define endl '\n'
#endif
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

const int N = 16500;
int comp[N], comp1[N], dsu[N];
bitset<N> b;
int root(int u){
    return (dsu[u] == u) ? u : (dsu[u] = root(dsu[u]));
}
int n, m;
bool uni(int u,int v){
    assert(u <= 4 * m);
    assert(v <= 4 * m);
    u = root(u), v = root(v);
    if(u == v) return 0;
    dsu[root(u)] = root(v);
    return 1;
}
vector<int> cp;
void solve(){
    cin >> n >> m;
    m /= 4;
    int ans = 0;
    fr(i, 1, n){
        b.reset();
        fr(j, 1, m){ // good
            int c = 4 * j, x;
            char ch;
            cin >> ch;
            if(ch >= '0' && ch <= '9') x = ch - '0';
            else x = 10 + ch - 'A';
            while(x){
                b[c--] = (x & 1);
                x >>= 1;
            }
        }
        if(i == 1){
            fr(j, 1, 4 * m){
                if(b[j]){
                    int r = j;
                    while(b[r]) r++;
                    r--;
                    ans++;
                    fr(k, j, r)
                        comp[k] = ans;
                    j = r;
                }
            }
        }
        else{
            int maxi = 1;
            fr(j, 1, 4 * m){
                comp1[j] = 0;
                dsu[j] = j;
                if(comp[j]) maxi = max(maxi, comp[j]);
            }
            fr(j, 1, 4 * m){
                if(b[j]){
                    int r = j, p = -1;
                    while(b[r]){
                        if(comp[r]){
                            if(p != -1)
                                ans -= uni(p, comp[r]);
                            p = comp[r];
                        }
                        r++;
                    }
                    if(p == -1)
                        comp1[j] = ++maxi, ans++;
                    j = r;
                }
            }
            fr(j, 1, 4 * m){
                if(comp[j] && b[j]) comp1[j] = root(comp[j]);
            }
            fr(j, 1, 4 * m){
                if(comp1[j]){
                    int r = j;
                    while(b[r]){
                        comp1[r] = comp1[j];
                        r--;
                    }
                    r = j;
                    while(b[r]){
                        comp1[r] = comp1[j];
                        r++;
                    }
                    j = r;
                    cp.pb(comp1[j]);
                }
            }
            sort(all(cp));
            unique(all(cp));
            fr(j, 1, 4 * m){
                if(comp1[j])
                {
                    int val = 1 + lower_bound(all(cp), comp1[j]) - cp.begin();
                    comp1[j] = val;
                }
                comp[j] = comp1[j];
            }
            cp.clear();
        }
    }
    cout << ans;
}
signed main()
{
    IO;
    #ifdef LOCAL
     freopen("inp.txt", "r", stdin);
     // freopen("out.txt", "w", stdout);
    #endif
    clock_t clk = clock();
    int t;
    // cin >> t;
    t = 1;
    fr(i, 1, t){
        solve();
    }
    cerr << endl << setprecision(10) << fixed << (double)(clock() - clk) / CLOCKS_PER_SEC;
    return 0;
}


#pragma GCC optimize ("Ofast")
#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
// #define int long long int
#define pb push_back
#define fi first
#define se second
#define fr(i, a, b) for(int i = a; i <= b; i++)
#define all(x) x.begin(), x.end()
#define IO ios :: sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define pii pair<int,int>
const int mod = 1e9 + 7;
const int mod1 = 998244353;
typedef long double f80;
#ifndef LOCAL
#define endl '\n'
#endif
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

const int N = 16500;
int comp[N], comp1[N], dsu[N];
bitset<N> b;
int root(int u){
    return (dsu[u] == u) ? u : (dsu[u] = root(dsu[u]));
}
bool uni(int u,int v){
    u = root(u), v = root(v);
    if(u == v) return 0;
    dsu[root(u)] = root(v);
    return 1;
}
vector<int> cp;
void solve(){
    int n, m;
    cin >> n >> m;
    m /= 4;
    int ans = 1;
    fr(i, 1, n){
        b.reset();
        fr(j, 1, m){ // good
            int c = 4 * j, x;
            char ch;
            cin >> ch;
            if(ch >= '0' && ch <= '9') x = ch - '0';
            else x = 10 + ch - 'A';
            while(x){
                b[c--] = (x & 1);
                x >>= 1;
            }
        }
        if(i == 1){
            fr(j, 1, 4 * m){
                if(b[j]){
                    int r = j;
                    while(b[r]) r++;
                    r--;
                    ans++;
                    fr(k, j, r)
                        comp[k] = ans;
                    j = r;
                }
            }
        }
        else{
            int maxi = 1;
            fr(j, 1, 4 * m){
                comp1[j] = 0;
                dsu[j] = j;
                if(comp[j]) maxi = max(maxi, comp[j]);
            }
            fr(j, 1, 4 * m){
                if(b[j]){
                    int r = j, p = -1;
                    while(b[r]){
                        if(comp[r]){
                            if(p != -1)
                                ans -= uni(p, comp[r]);
                            p = comp[r];
                        }
                        r++;
                    }
                    if(p == -1)
                        comp1[j] = ++maxi, ans++;
                    j = r;
                }
            }
            fr(j, 1, 4 * m){
                if(comp[j] && b[j]) comp1[j] = root(comp[j]);
            }
            fr(j, 1, 4 * m){
                if(comp1[j]){
                    int r = j + 1;
                    while(b[r] && !comp1[r]){
                        comp1[r] = comp1[j];
                        r++;
                    }
                    r = j - 1;
                    while(b[r] && !comp1[r]){
                        comp1[r] = comp1[j];
                        r--;
                    }
                    cp.pb(comp1[j]);
                }
            }
            sort(all(cp));
            unique(all(cp));
            fr(j, 1, 4 * m){
                if(comp1[i])
                {
                    int val = 2 + lower_bound(all(cp), comp1[i]) - cp.begin();
                    comp1[i] = val;
                }
                comp[j] = comp1[j];
            }
            cp.clear();
        }
    }
    cout << ans - 1;
}
signed main()
{
    IO;
    #ifdef LOCAL
     freopen("inp.txt", "r", stdin);
     // freopen("out.txt", "w", stdout);
    #endif
    clock_t clk = clock();
    int t;
    // cin >> t;
    t = 1;
    fr(i, 1, t){
        solve();
    }
    cerr << endl << setprecision(10) << fixed << (double)(clock() - clk) / CLOCKS_PER_SEC;
    return 0;
}


#pragma GCC optimize ("Ofast")
#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
// #define int long long int
#define pb push_back
#define fi first
#define se second
#define fr(i, a, b) for(int i = a; i <= b; i++)
#define all(x) x.begin(), x.end()
#define IO ios :: sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define pii pair<int,int>
const int mod = 1e9 + 7;
const int mod1 = 998244353;
typedef long double f80;
#ifndef LOCAL
#define endl '\n'
#endif
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

const int N = 16500;
int comp[N], comp1[N], dsu[N];
bitset<N> b;
int root(int u){
    return (dsu[u] == u) ? u : (dsu[u] = root(dsu[u]));
}
int n, m;
bool uni(int u,int v){
    assert(u <= 4 * m);
    assert(v <= 4 * m);
    u = root(u), v = root(v);
    if(u == v) return 0;
    dsu[root(u)] = root(v);
    return 1;
}
vector<int> cp;
void solve(){
    cin >> n >> m;
    m /= 4;
    int ans = 0;
    fr(i, 1, n){
        b.reset();
        fr(j, 1, m){ // good
            int c = 4 * j, x;
            char ch;
            cin >> ch;
            if(ch >= '0' && ch <= '9') x = ch - '0';
            else x = 10 + ch - 'A';
            while(x){
                b[c--] = (x & 1);
                x >>= 1;
            }
        }
        if(i == 1){
            fr(j, 1, 4 * m){
                if(b[j]){
                    int r = j;
                    while(b[r]) r++;
                    r--;
                    ans++;
                    fr(k, j, r)
                        comp[k] = ans;
                    j = r;
                }
            }
        }
        else{
            int maxi = 1;
            fr(j, 1, 4 * m){
                comp1[j] = 0;
                dsu[j] = j;
                if(comp[j]) maxi = max(maxi, comp[j]);
            }
            fr(j, 1, 4 * m){
                if(b[j]){
                    int r = j, p = -1;
                    while(b[r]){
                        if(comp[r]){
                            if(p != -1)
                                ans -= uni(p, comp[r]);
                            p = comp[r];
                        }
                        r++;
                    }
                    if(p == -1)
                        comp1[j] = ++maxi, ans++;
                    j = r;
                }
            }
            fr(j, 1, 4 * m){
                if(comp[j] && b[j]) comp1[j] = root(comp[j]);
            }
            fr(j, 1, 4 * m){
                if(comp1[j]){
                    int r = j;
                    while(b[r]){
                        comp1[r] = comp1[j];
                        r--;
                    }
                    r = j;
                    while(b[r]){
                        comp1[r] = comp1[j];
                        r++;
                    }
                    j = r;
                    cp.pb(comp1[j]);
                }
            }
            sort(all(cp));
            unique(all(cp));
            fr(j, 1, 4 * m){
                if(comp1[i])
                {
                    int val = 1 + lower_bound(all(cp), comp1[i]) - cp.begin();
                    comp1[i] = val;
                }
                comp[j] = comp1[j];
            }
            cp.clear();
        }
    }
    cout << ans;
}
signed main()
{
    IO;
    #ifdef LOCAL
     freopen("inp.txt", "r", stdin);
     // freopen("out.txt", "w", stdout);
    #endif
    clock_t clk = clock();
    int t;
    // cin >> t;
    t = 1;
    fr(i, 1, t){
        solve();
    }
    cerr << endl << setprecision(10) << fixed << (double)(clock() - clk) / CLOCKS_PER_SEC;
    return 0;
}


#pragma GCC optimize ("Ofast")
#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
// #define int long long int
#define pb push_back
#define fi first
#define se second
#define fr(i, a, b) for(int i = a; i <= b; i++)
#define all(x) x.begin(), x.end()
#define IO ios :: sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define pii pair<int,int>
const int mod = 1e9 + 7;
const int mod1 = 998244353;
typedef long double f80;
#ifndef LOCAL
#define endl '\n'
#endif
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

const int N = 16500;
int comp[N], comp1[N], dsu[N];
bitset<N> b;
int root(int u){
    return (dsu[u] == u) ? u : (dsu[u] = root(dsu[u]));
}
bool uni(int u,int v){
    u = root(u), v = root(v);
    if(u == v) return 0;
    dsu[root(u)] = root(v);
    return 1;
}
vector<int> cp;
void solve(){
    int n, m;
    cin >> n >> m;
    m /= 4;
    int ans = 1;
    fr(i, 1, n){
        b.reset();
        fr(j, 1, m){
            int c = 4 * j, x;
            char ch;
            cin >> ch;
            if(ch >= '0' && ch <= '9') x = ch - '0';
            else x = 10 + ch - 'A';
            while(x){
                b[c--] = (x & 1);
                x >>= 1;
            }
        }
        if(i == 1){
            fr(j, 1, 4 * m){
                if(b[j]){
                    int r = j;
                    while(b[r]) r++;
                    r--;
                    ans++;
                    fr(k, j, r)
                        comp[k] = ans;
                    j = r;
                }
            }
        }
        else{
            int maxi = 1;
            fr(j, 1, 4 * m){
                comp1[j] = 0;
                dsu[j] = j;
                if(comp[j]) maxi = max(maxi, comp[j]);
            }
            fr(j, 1, 4 * m){
                if(b[j]){
                    int r = j, p = -1;
                    while(b[r]){
                        if(comp[r]){
                            if(p != -1)
                                ans -= uni(p, comp[r]);
                            p = comp[r];
                        }
                        r++;
                    }
                    if(p == -1)
                        comp1[j] = ++maxi, ans++;
                    j = r;
                }
            }
            fr(j, 1, 4 * m){
                if(comp[j] && b[j]) comp1[j] = root(comp[j]);
            }
            cp.clear();
            fr(j, 1, 4 * m){
                if(comp1[j]){
                    int r = j + 1;
                    while(b[r] && !comp1[r]){
                        comp1[r] = comp1[j];
                        r++;
                    }
                    r = j - 1;
                    while(b[r] && !comp1[r]){
                        comp1[r] = comp1[j];
                        r--;
                    }
                    cp.pb(comp1[j]);
                }
            }
            sort(all(cp));
            fr(j, 1, 4 * m){
                if(comp1[i])
                {
                    int val = 2 + lower_bound(all(cp), comp1[i]) - cp.begin();
                    comp1[i] = val;
                }
                comp[j] = comp1[j];
            }
            cp.clear();
        }
        // fr(j, 1, 4 * m){
        //     cout << comp[j];
        // }
        // cout << endl;
    }
    cout << ans - 1;
}
signed main()
{
    IO;
    #ifdef LOCAL
     freopen("inp.txt", "r", stdin);
     // freopen("out.txt", "w", stdout);
    #endif
    clock_t clk = clock();
    int t;
    // cin >> t;
    t = 1;
    fr(i, 1, t){
        solve();
    }
    cerr << endl << setprecision(10) << fixed << (double)(clock() - clk) / CLOCKS_PER_SEC;
    return 0;
}


#pragma GCC optimize ("Ofast")
#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
// #define int long long int
#define pb push_back
#define fi first
#define se second
#define fr(i, a, b) for(int i = a; i <= b; i++)
#define all(x) x.begin(), x.end()
#define IO ios :: sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define pii pair<int,int>
const int mod = 1e9 + 7;
const int mod1 = 998244353;
typedef long double f80;
#ifndef LOCAL
#define endl '\n'
#endif
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

const int N = 16500;
int comp[N], comp1[N], dsu[N], lol[N];
bitset<N> b;
int n, m;
int root(int u){
    return (dsu[u] == u) ? u : (dsu[u] = root(dsu[u]));
}
bool uni(int u,int v){
    u = root(u), v = root(v);
    if(u == v) return 0;
    dsu[root(u)] = root(v);
    return 1;
}
vector<int> cp;
void solve(){
    cin >> n >> m;
    m /= 4;
    int ans = 0;
    fr(i, 1, n){
        b.reset();
        fr(j, 1, m){ // good
            int c = 4 * j, x;
            char ch;
            cin >> ch;
            if(ch >= '0' && ch <= '9') x = ch - '0';
            else x = 10 + ch - 'A';
            while(x){
                b[c--] = (x & 1);
                x >>= 1;
            }
        }
        if(i == 1){ // good
            fr(j, 1, 4 * m){
                if(b[j]){
                    int r = j;
                    while(b[r]) r++;
                    r--;
                    ans++;
                    fr(k, j, r) comp[k] = ans;
                    j = r;
                }
            }
        }
        else{
            int maxi = 0;
            fr(j, 1, 4 * m){
                comp1[j] = 0;
                dsu[j] = j;
                if(comp[j]) maxi = max(maxi, comp[j]);
            }
            fr(j, 1, 4 * m){
                if(b[j]){
                    int r = j, p = -1;
                    while(b[r]){
                        if(comp[r]){
                            if(p != -1)
                                ans -= uni(p, comp[r]);
                            p = comp[r];
                        }
                        r++;
                    }
                    if(p == -1)
                        comp1[j] = ++maxi, ans++;
                    j = r;
                }
            }
            fr(j, 1, 4 * m){
                if(comp[j] && b[j]) comp1[j] = root(comp[j]);
            }
            fr(j, 1, 4 * m){
                if(comp1[j]){
                    int r = j;
                    while(b[r]){
                        comp1[r] = comp1[j];
                        r--;
                    }
                    r = j;
                    while(b[r]){
                        comp1[r] = comp1[j];
                        r++;
                    }
                    cp.pb(comp1[j]);
                    j = r;
                }
            }
            sort(all(cp));
            unique(all(cp));
            int cc = 0;
            for(int x : cp){
                lol[x] = ++cc;
            }
            fr(j, 1, 4 * m){
                if(comp1[j])
                    comp1[j] = lol[comp1[j]];
                comp[j] = comp1[j];
            }
            cp.clear();
        }
    }
    cout << ans;
}
signed main()
{
    IO;
    #ifdef LOCAL
     freopen("inp.txt", "r", stdin);
     // freopen("out.txt", "w", stdout);
    #endif
    clock_t clk = clock();
    int t;
    // cin >> t;
    t = 1;
    fr(i, 1, t){
        solve();
    }
    cerr << endl << setprecision(10) << fixed << (double)(clock() - clk) / CLOCKS_PER_SEC;
    return 0;
}


#pragma GCC optimize ("Ofast")
#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
// #define int long long int
#define pb push_back
#define fi first
#define se second
#define fr(i, a, b) for(int i = a; i <= b; i++)
#define all(x) x.begin(), x.end()
#define IO ios :: sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define pii pair<int,int>
const int mod = 1e9 + 7;
const int mod1 = 998244353;
typedef long double f80;
#ifndef LOCAL
#define endl '\n'
#endif
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

const int N = 16500;
int comp[N], comp1[N], dsu[N];
bitset<N> b;
int root(int u){
    return (dsu[u] == u) ? u : (dsu[u] = root(dsu[u]));
}
bool uni(int u,int v){
    u = root(u), v = root(v);
    if(u == v) return 0;
    dsu[root(u)] = root(v);
    return 1;
}
vector<int> cp;
void solve(){
    int n, m;
    cin >> n >> m;
    m /= 4;
    int ans = 0;
    fr(i, 1, n){
        b.reset();
        fr(j, 1, m){ // good
            int c = 4 * j, x;
            char ch;
            cin >> ch;
            if(ch >= '0' && ch <= '9') x = ch - '0';
            else x = 10 + ch - 'A';
            while(x){
                b[c--] = (x & 1);
                x >>= 1;
            }
        }
        if(i == 1){
            fr(j, 1, 4 * m){
                if(b[j]){
                    int r = j;
                    while(b[r]) r++;
                    r--;
                    ans++;
                    fr(k, j, r)
                        comp[k] = ans;
                    j = r;
                }
            }
        }
        else{
            int maxi = 1;
            fr(j, 1, 4 * m){
                comp1[j] = 0;
                dsu[j] = j;
                if(comp[j]) maxi = max(maxi, comp[j]);
            }
            fr(j, 1, 4 * m){
                if(b[j]){
                    int r = j, p = -1;
                    while(b[r]){
                        if(comp[r]){
                            if(p != -1)
                                ans -= uni(p, comp[r]);
                            p = comp[r];
                        }
                        r++;
                    }
                    if(p == -1)
                        comp1[j] = ++maxi, ans++;
                    j = r;
                }
            }
            fr(j, 1, 4 * m){
                if(comp[j] && b[j]) comp1[j] = root(comp[j]);
            }
            fr(j, 1, 4 * m){
                if(comp1[j]){
                    int r = j;
                    while(b[r]){
                        comp1[r] = comp1[j];
                        r--;
                    }
                    r = j;
                    while(b[r]){
                        comp1[r] = comp1[j];
                        r++;
                    }
                    j = r;
                }
            }
            sort(all(cp));
            unique(all(cp));
            fr(j, 1, 4 * m){
                if(comp1[i])
                {
                    int val = 1 + lower_bound(all(cp), comp1[i]) - cp.begin();
                    comp1[i] = val;
                }
                comp[j] = comp1[j];
            }
            cp.clear();
        }
    }
    cout << ans;
}
signed main()
{
    IO;
    #ifdef LOCAL
     freopen("inp.txt", "r", stdin);
     // freopen("out.txt", "w", stdout);
    #endif
    clock_t clk = clock();
    int t;
    // cin >> t;
    t = 1;
    fr(i, 1, t){
        solve();
    }
    cerr << endl << setprecision(10) << fixed << (double)(clock() - clk) / CLOCKS_PER_SEC;
    return 0;
}


#pragma GCC optimize ("Ofast")
#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
// #define int long long int
#define pb push_back
#define fi first
#define se second
#define fr(i, a, b) for(int i = a; i <= b; i++)
#define all(x) x.begin(), x.end()
#define IO ios :: sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define pii pair<int,int>
const int mod = 1e9 + 7;
const int mod1 = 998244353;
typedef long double f80;
#ifndef LOCAL
#define endl '\n'
#endif
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

const int N = 16500;
int comp[N], comp1[N], dsu[N];
bitset<N> b;
int n, m;
int root(int u){
    assert(u <= 4 * m);
    return (dsu[u] == u) ? u : (dsu[u] = root(dsu[u]));
}
bool uni(int u,int v){
    assert(u <= 4 * m);
    assert(v <= 4 * m);
    u = root(u), v = root(v);
    if(u == v) return 0;
    dsu[root(u)] = root(v);
    return 1;
}
vector<int> cp;
void solve(){
    cin >> n >> m;
    m /= 4;
    int ans = 0;
    fr(i, 1, n){
        b.reset();
        fr(j, 1, m){ // good
            int c = 4 * j, x;
            char ch;
            cin >> ch;
            if(ch >= '0' && ch <= '9') x = ch - '0';
            else x = 10 + ch - 'A';
            while(x){
                b[c--] = (x & 1);
                x >>= 1;
            }
        }
        if(i == 1){ // good
            fr(j, 1, 4 * m){
                if(b[j]){
                    int r = j;
                    while(b[r]) r++;
                    r--;
                    ans++;
                    fr(k, j, r) comp[k] = ans;
                    j = r;
                }
            }
        }
        else{
            int maxi = 0;
            fr(j, 1, 4 * m){
                comp1[j] = 0;
                dsu[j] = j;
                if(comp[j]) maxi = max(maxi, comp[j]);
            }
            fr(j, 1, 4 * m){
                if(b[j]){
                    int r = j, p = -1;
                    while(b[r]){
                        if(comp[r]){
                            if(p != -1)
                                ans -= uni(p, comp[r]);
                            p = comp[r];
                        }
                        r++;
                    }
                    if(p == -1)
                        comp1[j] = ++maxi, ans++;
                    j = r;
                }
            }
            fr(j, 1, 4 * m){
                if(comp[j] && b[j]) comp1[j] = root(comp[j]);
            }
            fr(j, 1, 4 * m){
                if(comp1[j]){
                    int r = j;
                    while(b[r]){
                        comp1[r] = comp1[j];
                        r--;
                    }
                    r = j;
                    while(b[r]){
                        comp1[r] = comp1[j];
                        r++;
                    }
                    cp.pb(comp1[j]);
                    j = r;
                }
            }
            sort(all(cp));
            unique(all(cp));
            fr(j, 1, 4 * m){
                if(comp1[j])
                {
                    int val = 1 + lower_bound(all(cp), comp1[j]) - cp.begin();
                    comp1[j] = val;
                }
                comp[j] = comp1[j];
            }
            cp.clear();
        }
        fr(j, 1, 4 * m)
            cout << comp[j];
        cout << endl;
    }
    cout << ans;
}
signed main()
{
    IO;
    #ifdef LOCAL
     freopen("inp.txt", "r", stdin);
     // freopen("out.txt", "w", stdout);
    #endif
    clock_t clk = clock();
    int t;
    // cin >> t;
    t = 1;
    fr(i, 1, t){
        solve();
    }
    cerr << endl << setprecision(10) << fixed << (double)(clock() - clk) / CLOCKS_PER_SEC;
    return 0;
}


#pragma GCC optimize ("Ofast")
#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
// #define int long long int
#define pb push_back
#define fi first
#define se second
#define fr(i, a, b) for(int i = a; i <= b; i++)
#define all(x) x.begin(), x.end()
#define IO ios :: sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define pii pair<int,int>
const int mod = 1e9 + 7;
const int mod1 = 998244353;
typedef long double f80;
#ifndef LOCAL
#define endl '\n'
#endif
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

const int N = 16500;
int comp[N], comp1[N], dsu[N];
bitset<N> b;
int n, m;
int root(int u){
    assert(u <= 4 * m);
    return (dsu[u] == u) ? u : (dsu[u] = root(dsu[u]));
}
bool uni(int u,int v){
    assert(u <= 4 * m);
    assert(v <= 4 * m);
    u = root(u), v = root(v);
    if(u == v) return 0;
    dsu[root(u)] = root(v);
    return 1;
}
vector<int> cp;
void solve(){
    cin >> n >> m;
    m /= 4;
    int ans = 0;
    fr(i, 1, n){
        b.reset();
        fr(j, 1, m){ // good
            int c = 4 * j, x;
            char ch;
            cin >> ch;
            if(ch >= '0' && ch <= '9') x = ch - '0';
            else x = 10 + ch - 'A';
            while(x){
                b[c--] = (x & 1);
                x >>= 1;
            }
        }
        if(i == 1){ // good
            fr(j, 1, 4 * m){
                if(b[j]){
                    int r = j;
                    while(b[r]) r++;
                    r--;
                    ans++;
                    fr(k, j, r) comp[k] = ans;
                    j = r;
                }
            }
        }
        else{
            int maxi = 0;
            fr(j, 1, 4 * m){
                comp1[j] = 0;
                dsu[j] = j;
                if(comp[j]) maxi = max(maxi, comp[j]);
            }
            fr(j, 1, 4 * m){
                if(b[j]){
                    int r = j, p = -1;
                    while(b[r]){
                        if(comp[r]){
                            if(p != -1)
                                ans -= uni(p, comp[r]);
                            p = comp[r];
                        }
                        r++;
                    }
                    if(p == -1)
                        comp1[j] = ++maxi, ans++;
                    j = r;
                }
            }
            fr(j, 1, 4 * m){
                if(comp[j] && b[j]) comp1[j] = root(comp[j]);
            }
            fr(j, 1, 4 * m){
                if(comp1[j]){
                    int r = j;
                    while(b[r]){
                        comp1[r] = comp1[j];
                        r--;
                    }
                    r = j;
                    while(b[r]){
                        comp1[r] = comp1[j];
                        r++;
                    }
                    cp.pb(comp1[j]);
                    j = r;
                }
            }
            sort(all(cp));
            unique(all(cp));
            fr(j, 1, 4 * m){
                if(comp1[j])
                {
                    int val = 1 + lower_bound(all(cp), comp1[j]) - cp.begin();
                    comp1[j] = val;
                }
                comp[j] = comp1[j];
            }
            cp.clear();
        }
    }
    cout << ans;
}
signed main()
{
    IO;
    #ifdef LOCAL
     freopen("inp.txt", "r", stdin);
     // freopen("out.txt", "w", stdout);
    #endif
    clock_t clk = clock();
    int t;
    // cin >> t;
    t = 1;
    fr(i, 1, t){
        solve();
    }
    cerr << endl << setprecision(10) << fixed << (double)(clock() - clk) / CLOCKS_PER_SEC;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define eps 1e-7
#define PI acos(-1)
#define de(x) cout<<#x<<'='<<x<<" , "
#define dee(x) cout<<#x<<'='<<x<<endl
#define sz(x) x.size()
#define mp make_pair
#define rep(i,a,b) for(int i=a;i<(b);++i)
#define mset(a,b) memset(a,b,sizeof(a))
#define fi first
#define se second
#define all(x) x.begin(),x.end()
#define pb push_back
typedef long long LL;
const int maxn=50044;

int s[maxn], pres[maxn];
int fa[maxn],prefa[maxn];
int mark[maxn];
int cnt, n, m;
int find_fa(int x,int *fa){ return x==fa[x]?x:fa[x]=find_fa(fa[x],fa); }
void join(int x,int y,int *fa){
    int fx=find_fa(x,fa), fy=find_fa(y,fa);
    if(fx!=fy) { cnt--; fa[fx]=fy; }
}
void toDig(char s[],int num[]){
    rep(i,0,m/4){
        int cur=(s[i]>='0'&&s[i]<='9')?s[i]-'0':s[i]-'A'+10;
        rep(j,0,4) num[i*4+3-j]=(cur>>j)&1;
        rep(j,0,4) cnt+=(num[i*4+j]==1);
    }
}
void Proc1(){
    rep(i,0,m) fa[i]=i, mark[i]=0;
    rep(i,1,m) if(s[i]&&s[i-1]) join(i,i-1,fa);
}
void Proc2(){
    rep(i,0,m) if(s[i]&&pres[i]){
        int fi=find_fa(i,prefa);
        if(fi!=i) { prefa[fi]=i, prefa[i]=i; }
    }
    rep(i,0,m) if(s[i]&&pres[i]){
        int prefi=find_fa(i,prefa);
        if(s[prefi]) join(i,prefi,fa);
        if(!mark[find_fa(i,fa)]) {mark[find_fa(i,fa)]=1; cnt--;}
    }
}
char ss[maxn];
int main(){
    scanf("%d %d",&n,&m);
    scanf("%s",ss);
    toDig(ss,s); Proc1();
    rep(i,1,n){
        scanf("%s",ss);
        swap(fa,prefa);
        swap(s,pres);
        toDig(ss,s);
        Proc1();
        Proc2();
    }
    cout<<cnt<<endl;
}


#include <bits/stdc++.h>
using namespace std;
#define eps 1e-7
#define PI acos(-1)
#define de(x) cout<<#x<<'='<<x<<" , "
#define dee(x) cout<<#x<<'='<<x<<endl
#define sz(x) x.size()
#define mp make_pair
#define rep(i,a,b) for(int i=a;i<(b);++i)
#define mset(a,b) memset(a,b,sizeof(a))
#define fi first
#define se second
#define all(x) x.begin(),x.end()
#define pb push_back
typedef long long LL;
const int maxn=50044;

int s[maxn], pres[maxn];
int fa[maxn],prefa[maxn];
int mark[maxn];
int cnt, n, m;
int find_fa(int x,int *fa){ return x==fa[x]?x:fa[x]=find_fa(fa[x],fa); }
void join(int x,int y,int *fa){
    int fx=find_fa(x,fa), fy=find_fa(y,fa);
    if(fx!=fy) { cnt--; fa[fx]=fy; }
}
void toDig(char s[],int num[]){
    rep(i,0,m/4){
        int cur=(s[i]>='0'&&s[i]<='9')?s[i]-'0':s[i]-'A'+10;
        rep(j,0,4) num[i*4+3-j]=(cur>>j)&1;
        rep(j,0,4) cnt+=(num[i*4+j]==1);
        //rep(j,0,4) cout<<num[i*4+j]<<",";
    }
    //cout<<endl;
}
void Proc1(){
    rep(i,0,m) fa[i]=i, mark[i]=0;
    rep(i,1,m) if(s[i]&&s[i-1]) join(i,i-1,fa);
    //dee(cnt);
}
void Proc2(){
    rep(i,0,m) if(s[i]&&pres[i]){
        int fi=find_fa(i,prefa);
        if(fi!=i) { prefa[fi]=i, prefa[i]=i; }
    }
    rep(i,0,m) if(s[i]&&pres[i]){
        if(!mark[find_fa(i,fa)]) {mark[find_fa(i,fa)]=1; cnt--;}
        int prefi=find_fa(i,prefa);
        //de(i),dee(prefi);
        if(s[prefi]) join(i,prefi,fa);
        //dee(cnt);
    }
}
char ss[maxn];
int main(){
    scanf("%d %d",&n,&m);
    scanf("%s",ss);
    toDig(ss,s); Proc1();
    rep(i,1,n){
        scanf("%s",ss);
        swap(fa,prefa);
        swap(s,pres);
        toDig(ss,s);
        Proc1();
        Proc2();
    }
    cout<<cnt<<endl;
}


#include <bits/stdc++.h>
using namespace std;
#define eps 1e-7
#define PI acos(-1)
#define de(x) cout<<#x<<'='<<x<<" , "
#define dee(x) cout<<#x<<'='<<x<<endl
#define sz(x) x.size()
#define mp make_pair
#define rep(i,a,b) for(int i=a;i<(b);++i)
#define mset(a,b) memset(a,b,sizeof(a))
#define fi first
#define se second
#define all(x) x.begin(),x.end()
#define pb push_back
typedef long long LL;
const int maxn=50044;

int s[maxn], pres[maxn];
int fa[maxn],prefa[maxn];
int mark[maxn];
int cnt, n, m;
int find_fa(int x,int *fa){ return x==fa[x]?x:fa[x]=find_fa(fa[x],fa); }
void join(int x,int y,int *fa){
    int fx=find_fa(x,fa), fy=find_fa(y,fa);
    if(fx!=fy) { cnt--; fa[fx]=fy; }
}
void toDig(char s[],int num[]){
    rep(i,0,m/4){
        int cur=(s[i]>='0'&&s[i]<='9')?s[i]-'0':s[i]-'A'+10;
        rep(j,0,4) num[i*4+3-j]=(cur>>j)&1;
        rep(j,0,4) cnt+=(num[i*4+j]==1);
    }
}
void Proc1(){
    rep(i,0,m) fa[i]=i, mark[i]=0;
    rep(i,1,m) if(s[i]&&s[i-1]) join(i,i-1,fa);
}
void Proc2(){
    rep(i,0,m) if(s[i]&&pres[i]){
        int fi=find_fa(i,prefa);
        if(fi!=i) { prefa[fi]=i, prefa[i]=i; }
    }
    rep(i,0,m) if(s[i]&&pres[i]){

        int prefi=find_fa(i,prefa);
        if(s[prefi]) join(i,prefi,fa);
        if(!mark[prefi]) {mark[prefi]=1; cnt--;}
    }
}
char ss[maxn];
int main(){
    scanf("%d %d",&n,&m);
    scanf("%s",ss);
    toDig(ss,s); Proc1();
    rep(i,1,n){
        scanf("%s",ss);
        swap(fa,prefa);
        swap(s,pres);
        toDig(ss,s);
        Proc1();
        Proc2();
    }
    cout<<cnt<<endl;
}


#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC optimize ("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
#include <unordered_set>
#include <unordered_map>
#include <random>
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define all(a) (a).begin(), (a).end()
#define sz(a) (ll)((a).size())
#define heap priority_queue
#define hash_map unordered_map
#define hash_set unordered_set
#define ft first
#define sd second
#define fast ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
#define endl "\n"
#define y0 y_0
#define y1 y_1
using namespace std;
typedef int ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef pair<ld, ld> pld;
typedef vector<ll> vll;
typedef set<ll> sll;
typedef map<ll, ll> mll;
const ll inf = numeric_limits<ll>::max() / 2;
const ld eps = 1e-9;
const ld pi = acos(-1);
template<typename T> inline bool mineq(T& a, T b) { return (a > b) ? (a = b, 1) : 0; }
template<typename T> inline bool maxeq(T& a, T b) { return (a < b) ? (a = b, 1) : 0; }

inline void solve(), read();
const string file = "";

signed main() {
#ifndef _DEBUG
	if (file != "") {
		freopen((file + ".in").c_str(), "r", stdin);
		freopen((file + ".out").c_str(), "w", stdout);
	}
#endif
	fast;
	read();
	solve();
	return 0;
}

const ll MAXN = 2 * (1ll << 14);

ll n, m;
bitset<MAXN> val;
short t[MAXN];
ll find(ll v) {
	if (v == t[v]) {
		return v;
	}
	return t[v] = find(t[v]);
}
ll join(ll v, ll u) {
	v = find(v), u = find(u);
	if (v == u) {
		return 0;
	}
	t[u] = v;
	return 1;
}
void shift() {
	for (ll i = 0; i < m; i++) {
		t[i] = t[i + m] - m;
		val[i] = val[i + m];
		t[i + m] = i + m;
		val[i + m] = 0;
	}
}
bool checkbit(ll n, ll p) {
	return n & (1ll << p);
}
ll get(char c) {
	if ('0' <= c && c <= '9') {
		return c - '0';
	}
	return 10 + c - 'A';
}

inline void solve() {
	ll cnt1 = 0;
	ll cntm = 0;
	for (ll i = 0; i < n; i++) {
		for (ll j = 0; j < m / 4; j++) {
			char c;
			cin >> c;
			ll v = get(c);
			for (ll k = 0; k < 4; k++) {
				val[m + j * 4 + k] = checkbit(v, 3 - k);
				cnt1 += checkbit(v, 3 - k);
			}
		}
		for (ll i = 0; i < m; i++) {
			if (val[i] && val[i + m]) {
				cntm += join(i, i + m);
			}
			if (i && val[i + m] && val[i - 1 + m]) {
				cntm += join(i - 1 + m, i + m);
			}
		}
		shift();
	}
	ll ans = cnt1 - cntm;
	cout << ans << endl;
}

inline void read() {
	cin >> n >> m;
}


#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC optimize ("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
#include <unordered_set>
#include <unordered_map>
#include <random>
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define all(a) (a).begin(), (a).end()
#define sz(a) (ll)((a).size())
#define heap priority_queue
#define hash_map unordered_map
#define hash_set unordered_set
#define ft first
#define sd second
#define fast ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
#define endl "\n"
#define y0 y_0
#define y1 y_1
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef pair<ld, ld> pld;
typedef vector<ll> vll;
typedef set<ll> sll;
typedef map<ll, ll> mll;
const ll inf = numeric_limits<ll>::max() / 2;
const ld eps = 1e-9;
const ld pi = acos(-1);
template<typename T> inline bool mineq(T& a, T b) { return (a > b) ? (a = b, 1) : 0; }
template<typename T> inline bool maxeq(T& a, T b) { return (a < b) ? (a = b, 1) : 0; }

inline void solve(), read();
const string file = "";

signed main() {
#ifndef _DEBUG
	if (file != "") {
		freopen((file + ".in").c_str(), "r", stdin);
		freopen((file + ".out").c_str(), "w", stdout);
	}
#endif
	fast;
	read();
	solve();
	return 0;
}

const ll MAXN = 2 * (1ll << 14);

struct dsu {
	ll n;
	bitset<MAXN> val;
	short t[MAXN];
	dsu() {}
	dsu(ll n_) {
		n = n_;
		iota(t, t + MAXN, 0);
	}
	ll find(ll v) {
		if (v == t[v]) {
			return v;
		}
		return t[v] = find(t[v]);
	}
	ll join(ll v, ll u) {
		v = find(v), u = find(u);
		if (v == u) {
			return 0;
		}
		t[u] = v;
		return 1;
	}
	void shift() {
		for (ll i = 0; i < n; i++) {
			t[i] = t[i + n] - n;
			val[i] = val[i + n];
			t[i + n] = i + n;
			val[i + n] = 0;
		}
	}
};

const ll MAXM = 1ll << 14;
ll n, m;
dsu d;

bool checkbit(ll n, ll p) {
	return n & (1ll << p);
}

ll get(char c) {
	if ('0' <= c && c <= '9') {
		return c - '0';
	}
	return 10 + c - 'A';
}

inline void solve() {
	ll cnt1 = 0;
	ll cntm = 0;
	d = dsu(m);
	for (ll i = 0; i < n; i++) {
		for (ll j = 0; j < m / 4; j++) {
			char c;
			cin >> c;
			ll v = get(c);
			for (ll k = 0; k < 4; k++) {
				d.val[m + j * 4 + k] = checkbit(v, 3 - k);
				cnt1 += checkbit(v, 3 - k);
			}
		}
		for (ll i = 0; i < m; i++) {
			if (d.val[i] && d.val[i + m]) {
				cntm += d.join(i, i + m);
			}
			if (i && d.val[i + m] && d.val[i - 1 + m]) {
				cntm += d.join(i - 1 + m, i + m);
			}
		}
		d.shift();
	}
	ll ans = cnt1 - cntm;
	cout << ans << endl;
}

inline void read() {
	cin >> n >> m;
}


#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC optimize ("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
#include <unordered_set>
#include <unordered_map>
#include <random>
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define all(a) (a).begin(), (a).end()
#define sz(a) (ll)((a).size())
#define heap priority_queue
#define hash_map unordered_map
#define hash_set unordered_set
#define ft first
#define sd second
#define fast ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
#define endl "\n"
#define y0 y_0
#define y1 y_1
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef pair<ld, ld> pld;
typedef vector<ll> vll;
typedef set<ll> sll;
typedef map<ll, ll> mll;
const ll inf = numeric_limits<ll>::max() / 2;
const ld eps = 1e-9;
const ld pi = acos(-1);
template<typename T> inline bool mineq(T& a, T b) { return (a > b) ? (a = b, 1) : 0; }
template<typename T> inline bool maxeq(T& a, T b) { return (a < b) ? (a = b, 1) : 0; }

inline void solve(), read();
const string file = "";

signed main() {
#ifndef _DEBUG
	if (file != "") {
		freopen((file + ".in").c_str(), "r", stdin);
		freopen((file + ".out").c_str(), "w", stdout);
	}
#endif
	fast;
	read();
	solve();
	return 0;
}

const ll MAXN = 2 * (1ll << 14);

struct dsu {
	ll n;
	ll t[MAXN];
	bitset<MAXN> val;
	dsu() {}
	dsu(ll n_) {
		n = n_;
		iota(t, t + MAXN, 0);
	}
	ll find(ll v) {
		if (v == t[v]) {
			return v;
		}
		return t[v] = find(t[v]);
	}
	ll join(ll v, ll u) {
		v = find(v), u = find(u);
		if (v == u) {
			return 0;
		}
		t[u] = v;
		return 1;
	}
	void shift() {
		for (ll i = 0; i < n; i++) {
			t[i] = t[i + n] - n;
			val[i] = val[i + n];
			t[i + n] = i + n;
			val[i + n] = 0;
		}
	}
};

ll n, m;
dsu d;

bool checkbit(ll n, ll p) {
	return n & (1ll << p);
}

ll get(char c) {
	if ('0' <= c && c <= '9') {
		return c - '0';
	}
	return 10 + c - 'A';
}

inline void solve() {
	ll cnt1 = 0;
	ll cntm = 0;
	d = dsu(m);
	for (ll i = 0; i < n; i++) {
		for (ll j = 0; j < m / 4; j++) {
			char c;
			cin >> c;
			ll v = get(c);
			for (ll k = 0; k < 4; k++) {
				d.val[m + j * 4 + k] = checkbit(v, 3 - k);
				cnt1 += checkbit(v, 3 - k);
			}
		}
		for (ll i = 0; i < m; i++) {
			if (d.val[i] && d.val[i + m]) {
				cntm += d.join(i + m, i);
			}
			if (i && d.val[i + m] && d.val[i - 1 + m]) {
				cntm += d.join(i - 1 + m, i + m);
			}
		}
		d.shift();
	}
	ll ans = cnt1 - cntm;
	cout << ans << endl;
}

inline void read() {
	cin >> n >> m;
}


#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC optimize ("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
#include <unordered_set>
#include <unordered_map>
#include <random>
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define all(a) (a).begin(), (a).end()
#define sz(a) (ll)((a).size())
#define heap priority_queue
#define hash_map unordered_map
#define hash_set unordered_set
#define ft first
#define sd second
#define fast ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
#define endl "\n"
#define y0 y_0
#define y1 y_1
using namespace std;
typedef int ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef pair<ld, ld> pld;
typedef vector<ll> vll;
typedef set<ll> sll;
typedef map<ll, ll> mll;
const ll inf = numeric_limits<ll>::max() / 2;
const ld eps = 1e-9;
const ld pi = acos(-1);
template<typename T> inline bool mineq(T& a, T b) { return (a > b) ? (a = b, 1) : 0; }
template<typename T> inline bool maxeq(T& a, T b) { return (a < b) ? (a = b, 1) : 0; }

inline void solve(), read();
const string file = "";

signed main() {
#ifndef _DEBUG
	if (file != "") {
		freopen((file + ".in").c_str(), "r", stdin);
		freopen((file + ".out").c_str(), "w", stdout);
	}
#endif
	fast;
	read();
	solve();
	return 0;
}

const int MAXN = 16385;

ll n, m;
bitset<MAXN> val;
short t[MAXN];
ll find(ll v) {
	if (v == t[v]) {
		return v;
	}
	return t[v] = find(t[v]);
}
ll join(ll v, ll u) {
	v = find(v), u = find(u);
	if (v == u) {
		return 0;
	}
	t[u] = v;
	return 1;
}
void shift() {
	for (ll i = 0; i < m; i++) {
		t[i] = t[i + m] - m;
		val[i] = val[i + m];
		t[i + m] = i + m;
		val[i + m] = 0;
	}
}
bool checkbit(ll n, ll p) {
	return n & (1ll << p);
}
ll get(char c) {
	if ('0' <= c && c <= '9') {
		return c - '0';
	}
	return 10 + c - 'A';
}

inline void solve() {
	for (ll i = 0; i < 2 * m; i++) {
		t[i] = i;
	}
	ll cnt1 = 0;
	ll cntm = 0;
	for (ll i = 0; i < n; i++) {
		for (ll j = 0; j < m / 4; j++) {
			char c;
			cin >> c;
			ll v = get(c);
			for (ll k = 0; k < 4; k++) {
				val[m + j * 4 + k] = checkbit(v, 3 - k);
				cnt1 += checkbit(v, 3 - k);
			}
		}
		for (ll i = 0; i < m; i++) {
			if (val[i] && val[i + m]) {
				cntm += join(i, i + m);
			}
			if (i && val[i + m] && val[i - 1 + m]) {
				cntm += join(i - 1 + m, i + m);
			}
		}
		shift();
	}
	ll ans = cnt1 - cntm;
	cout << ans << endl;
}

inline void read() {
	cin >> n >> m;
}


#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC optimize ("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
#include <unordered_set>
#include <unordered_map>
#include <random>
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define all(a) (a).begin(), (a).end()
#define sz(a) (ll)((a).size())
#define heap priority_queue
#define hash_map unordered_map
#define hash_set unordered_set
#define ft first
#define sd second
#define fast ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
#define endl "\n"
#define y0 y_0
#define y1 y_1
using namespace std;
typedef int ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef pair<ld, ld> pld;
typedef vector<ll> vll;
typedef set<ll> sll;
typedef map<ll, ll> mll;
const ll inf = numeric_limits<ll>::max() / 2;
const ld eps = 1e-9;
const ld pi = acos(-1);
template<typename T> inline bool mineq(T& a, T b) { return (a > b) ? (a = b, 1) : 0; }
template<typename T> inline bool maxeq(T& a, T b) { return (a < b) ? (a = b, 1) : 0; }

inline void solve(), read();
const string file = "";

signed main() {
#ifndef _DEBUG
	if (file != "") {
		freopen((file + ".in").c_str(), "r", stdin);
		freopen((file + ".out").c_str(), "w", stdout);
	}
#endif
	fast;
	read();
	solve();
	return 0;
}

const int MAXN = 2 * 16385;

ll n, m;
bitset<MAXN> val;
short t[MAXN];
ll find(ll v) {
	if (v == t[v]) {
		return v;
	}
	return t[v] = find(t[v]);
}
ll join(ll v, ll u) {
	v = find(v), u = find(u);
	if (v == u) {
		return 0;
	}
	t[u] = v;
	return 1;
}
void shift() {
	for (ll i = 0; i < m; i++) {
		t[i] = t[i + m] - m;
		val[i] = val[i + m];
		t[i + m] = i + m;
		val[i + m] = 0;
	}
}
bool checkbit(ll n, ll p) {
	return n & (1ll << p);
}
ll get(char c) {
	if ('0' <= c && c <= '9') {
		return c - '0';
	}
	return 10 + c - 'A';
}

inline void solve() {
	for (ll i = 0; i < 2 * m; i++) {
		t[i] = i;
	}
	ll cnt1 = 0;
	ll cntm = 0;
	for (ll i = 0; i < n; i++) {
		for (ll j = 0; j < m / 4; j++) {
			char c;
			cin >> c;
			ll v = get(c);
			for (ll k = 0; k < 4; k++) {
				val[m + j * 4 + k] = checkbit(v, 3 - k);
				cnt1 += checkbit(v, 3 - k);
			}
		}
		for (ll i = 0; i < m; i++) {
			if (val[i] && val[i + m]) {
				cntm += join(i, i + m);
			}
			if (i && val[i + m] && val[i - 1 + m]) {
				cntm += join(i - 1 + m, i + m);
			}
		}
		shift();
	}
	ll ans = cnt1 - cntm;
	cout << ans << endl;
}

inline void read() {
	cin >> n >> m;
}


#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC optimize ("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
#include <unordered_set>
#include <unordered_map>
#include <random>
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define all(a) (a).begin(), (a).end()
#define sz(a) (ll)((a).size())
#define heap priority_queue
#define hash_map unordered_map
#define hash_set unordered_set
#define ft first
#define sd second
#define fast ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
#define endl "\n"
#define y0 y_0
#define y1 y_1
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef pair<ld, ld> pld;
typedef vector<ll> vll;
typedef set<ll> sll;
typedef map<ll, ll> mll;
const ll inf = numeric_limits<ll>::max() / 2;
const ld eps = 1e-9;
const ld pi = acos(-1);
template<typename T> inline bool mineq(T& a, T b) { return (a > b) ? (a = b, 1) : 0; }
template<typename T> inline bool maxeq(T& a, T b) { return (a < b) ? (a = b, 1) : 0; }

inline void solve(), read();
const string file = "";

signed main() {
#ifndef _DEBUG
	if (file != "") {
		freopen((file + ".in").c_str(), "r", stdin);
		freopen((file + ".out").c_str(), "w", stdout);
	}
#endif
	fast;
	read();
	solve();
	return 0;
}

const ll MAXN = 2 * (1ll << 14);

struct dsu {
	ll n;
	bitset<MAXN> val;
	short t[MAXN];
	vll ind;
	dsu() {}
	dsu(ll n_) {
		n = n_;
		iota(t, t + MAXN, 0);
	}
	ll find(ll v) {
		if (v == t[v]) {
			return v;
		}
		return t[v] = find(t[v]);
	}
	ll join(ll v, ll u) {
		v = find(v), u = find(u);
		if (v == u) {
			return 0;
		}
		t[u] = v;
		return 1;
	}
	void shift() {
		for (ll i = 0; i < n; i++) {
			t[i] = t[i + n] - n;
			val[i] = val[i + n];
			t[i + n] = i + n;
			val[i + n] = 0;
		}
	}
};

const ll MAXM = 1ll << 14;
ll n, m;
dsu d;

bool checkbit(ll n, ll p) {
	return n & (1ll << p);
}

ll get(char c) {
	if ('0' <= c && c <= '9') {
		return c - '0';
	}
	return 10 + c - 'A';
}

inline void solve() {
	ll cnt1 = 0;
	ll cntm = 0;
	d = dsu(m);
	for (ll i = 0; i < n; i++) {
		for (ll j = 0; j < m / 4; j++) {
			char c;
			cin >> c;
			ll v = get(c);
			for (ll k = 0; k < 4; k++) {
				d.val[m + j * 4 + k] = checkbit(v, 3 - k);
				cnt1 += checkbit(v, 3 - k);
			}
		}
		for (ll i = 0; i < m; i++) {
			if (d.val[i] && d.val[i + m]) {
				cntm += d.join(i, i + m);
			}
			if (i && d.val[i + m] && d.val[i - 1 + m]) {
				cntm += d.join(i - 1 + m, i + m);
			}
		}
		d.shift();
	}
	ll ans = cnt1 - cntm;
	cout << ans << endl;
}

inline void read() {
	cin >> n >> m;
}


#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC optimize ("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
#include <unordered_set>
#include <unordered_map>
#include <random>
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define all(a) (a).begin(), (a).end()
#define sz(a) (ll)((a).size())
#define heap priority_queue
#define hash_map unordered_map
#define hash_set unordered_set
#define ft first
#define sd second
#define fast ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
#define endl "\n"
#define y0 y_0
#define y1 y_1
using namespace std;
typedef int ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef pair<ld, ld> pld;
typedef vector<ll> vll;
typedef set<ll> sll;
typedef map<ll, ll> mll;
const ll inf = numeric_limits<ll>::max() / 2;
const ld eps = 1e-9;
const ld pi = acos(-1);
template<typename T> inline bool mineq(T& a, T b) { return (a > b) ? (a = b, 1) : 0; }
template<typename T> inline bool maxeq(T& a, T b) { return (a < b) ? (a = b, 1) : 0; }

inline void solve(), read();
const string file = "";

signed main() {
#ifndef _DEBUG
	if (file != "") {
		freopen((file + ".in").c_str(), "r", stdin);
		freopen((file + ".out").c_str(), "w", stdout);
	}
#endif
	fast;
	read();
	solve();
	return 0;
}

const int MAXN = 2 * 16385;

ll n, m;
bool val[MAXN};
short t[MAXN];
ll find(ll v) {
	if (v == t[v]) {
		return v;
	}
	return t[v] = find(t[v]);
}
ll join(ll v, ll u) {
	v = find(v), u = find(u);
	if (v == u) {
		return 0;
	}
	t[u] = v;
	return 1;
}
void shift() {
	for (ll i = 0; i < m; i++) {
		t[i] = t[i + m] - m;
		val[i] = val[i + m];
		t[i + m] = i + m;
		val[i + m] = 0;
	}
}
bool checkbit(ll n, ll p) {
	return n & (1ll << p);
}
ll get(char c) {
	if ('0' <= c && c <= '9') {
		return c - '0';
	}
	return 10 + c - 'A';
}

inline void solve() {
	for (ll i = 0; i < 2 * m; i++) {
		t[i] = i;
	}
	ll cnt1 = 0;
	ll cntm = 0;
	for (ll i = 0; i < n; i++) {
		for (ll j = 0; j < m / 4; j++) {
			char c;
			cin >> c;
			ll v = get(c);
			for (ll k = 0; k < 4; k++) {
				val[m + j * 4 + k] = checkbit(v, 3 - k);
				cnt1 += checkbit(v, 3 - k);
			}
		}
		for (ll i = 0; i < m; i++) {
			if (val[i] && val[i + m]) {
				cntm += join(i, i + m);
			}
			if (i && val[i + m] && val[i - 1 + m]) {
				cntm += join(i - 1 + m, i + m);
			}
		}
		shift();
	}
	ll ans = cnt1 - cntm;
	cout << ans << endl;
}

inline void read() {
	cin >> n >> m;
}


#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC optimize ("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
#include <unordered_set>
#include <unordered_map>
#include <random>
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define all(a) (a).begin(), (a).end()
#define sz(a) (ll)((a).size())
#define heap priority_queue
#define hash_map unordered_map
#define hash_set unordered_set
#define ft first
#define sd second
#define fast ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
#define endl "\n"
#define y0 y_0
#define y1 y_1
using namespace std;
typedef int ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef pair<ld, ld> pld;
typedef vector<ll> vll;
typedef set<ll> sll;
typedef map<ll, ll> mll;
const ll inf = numeric_limits<ll>::max() / 2;
const ld eps = 1e-9;
const ld pi = acos(-1);
template<typename T> inline bool mineq(T& a, T b) { return (a > b) ? (a = b, 1) : 0; }
template<typename T> inline bool maxeq(T& a, T b) { return (a < b) ? (a = b, 1) : 0; }

inline void solve(), read();
const string file = "";

signed main() {
#ifndef _DEBUG
	if (file != "") {
		freopen((file + ".in").c_str(), "r", stdin);
		freopen((file + ".out").c_str(), "w", stdout);
	}
#endif
	fast;
	read();
	solve();
	return 0;
}

const int MAXN = 2 * 16385;

ll n, m;
bool val[MAXN];
short t[MAXN];
ll find(ll v) {
	if (v == t[v]) {
		return v;
	}
	return t[v] = find(t[v]);
}
ll join(ll v, ll u) {
	v = find(v), u = find(u);
	if (v == u) {
		return 0;
	}
	t[u] = v;
	return 1;
}
void shift() {
	for (ll i = 0; i < m; i++) {
		t[i] = t[i + m] - m;
		val[i] = val[i + m];
		t[i + m] = i + m;
		val[i + m] = 0;
	}
}
bool checkbit(ll n, ll p) {
	return n & (1ll << p);
}
ll get(char c) {
	if ('0' <= c && c <= '9') {
		return c - '0';
	}
	return 10 + c - 'A';
}

inline void solve() {
	for (ll i = 0; i < 2 * m; i++) {
		t[i] = i;
	}
	ll cnt1 = 0;
	ll cntm = 0;
	for (ll i = 0; i < n; i++) {
		for (ll j = 0; j < m / 4; j++) {
			char c;
			cin >> c;
			ll v = get(c);
			for (ll k = 0; k < 4; k++) {
				val[m + j * 4 + k] = checkbit(v, 3 - k);
				cnt1 += checkbit(v, 3 - k);
			}
		}
		for (ll j = 0; j < m; j++) {
			if (val[j] && val[j + m]) {
				cntm += join(j, j + m);
			}
			if (j && val[j + m] && val[j - 1 + m]) {
				cntm += join(j - 1 + m, j + m);
			}
		}
		shift();
	}
	ll ans = cnt1 - cntm;
	cout << ans << endl;
}

inline void read() {
	cin >> n >> m;
}


#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC optimize ("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
#include <unordered_set>
#include <unordered_map>
#include <random>
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define all(a) (a).begin(), (a).end()
#define sz(a) (ll)((a).size())
#define heap priority_queue
#define hash_map unordered_map
#define hash_set unordered_set
#define ft first
#define sd second
#define fast ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
#define endl "\n"
#define y0 y_0
#define y1 y_1
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef pair<ld, ld> pld;
typedef vector<ll> vll;
typedef set<ll> sll;
typedef map<ll, ll> mll;
const ll inf = numeric_limits<ll>::max() / 2;
const ld eps = 1e-9;
const ld pi = acos(-1);
template<typename T> inline bool mineq(T& a, T b) { return (a > b) ? (a = b, 1) : 0; }
template<typename T> inline bool maxeq(T& a, T b) { return (a < b) ? (a = b, 1) : 0; }

inline void solve(), read();
const string file = "";

signed main() {
#ifndef _DEBUG
	if (file != "") {
		freopen((file + ".in").c_str(), "r", stdin);
		freopen((file + ".out").c_str(), "w", stdout);
	}
#endif
	fast;
	read();
	solve();
	return 0;
}

struct dsu {
	ll n;
	vll val;
	vll t;
	dsu() {}
	dsu(ll n_) {
		n = n_;
		t.resize(2 * n);
		iota(all(t), 0);
		val.assign(2 * n, 0);
	}
	ll find(ll v) {
		if (v == t[v]) {
			return v;
		}
		return t[v] = find(t[v]);
	}
	ll join(ll v, ll u) {
		v = find(v), u = find(u);
		if (v == u) {
			return 0;
		}
		t[u] = v;
		return 1;
	}
	void shift() {
		for (ll i = 0; i < n; i++) {
			t[i] = t[i + n] - n;
			val[i] = val[i + n];
			t[i + n] = i + n;
			val[i + n] = 0;
		}
	}
};

const ll MAXM = 1ll << 14;
ll n, m;
dsu d;

bool checkbit(ll n, ll p) {
	return n & (1ll << p);
}

ll get(char c) {
	if ('0' <= c && c <= '9') {
		return c - '0';
	}
	return 10 + c - 'A';
}

inline void solve() {
	ll cnt1 = 0;
	ll cntm = 0;
	d = dsu(m);
	for (ll i = 0; i < n; i++) {
		for (ll j = 0; j < m / 4; j++) {
			char c;
			cin >> c;
			ll v = get(c);
			for (ll k = 0; k < 4; k++) {
				d.val[m + j * 4 + k] = checkbit(v, 3 - k);
				cnt1 += checkbit(v, 3 - k);
			}
		}
		for (ll i = 0; i < m; i++) {
			if (d.val[i] && d.val[i + m]) {
				cntm += d.join(i + m, i);
			}
			if (i && d.val[i + m] && d.val[i - 1 + m]) {
				cntm += d.join(i - 1 + m, i + m);
			}
		}
		d.shift();
	}
	ll ans = cnt1 - cntm;
	cout << ans << endl;
}

inline void read() {
	cin >> n >> m;
}


#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC optimize ("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
#include <unordered_set>
#include <unordered_map>
#include <random>
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define all(a) (a).begin(), (a).end()
#define sz(a) (ll)((a).size())
#define heap priority_queue
#define hash_map unordered_map
#define hash_set unordered_set
#define ft first
#define sd second
#define fast ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
#define endl "\n"
#define y0 y_0
#define y1 y_1
using namespace std;
typedef int ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef pair<ld, ld> pld;
typedef vector<ll> vll;
typedef set<ll> sll;
typedef map<ll, ll> mll;
const ll inf = numeric_limits<ll>::max() / 2;
const ld eps = 1e-9;
const ld pi = acos(-1);
template<typename T> inline bool mineq(T& a, T b) { return (a > b) ? (a = b, 1) : 0; }
template<typename T> inline bool maxeq(T& a, T b) { return (a < b) ? (a = b, 1) : 0; }

inline void solve(), read();
const string file = "";

signed main() {
#ifndef _DEBUG
	if (file != "") {
		freopen((file + ".in").c_str(), "r", stdin);
		freopen((file + ".out").c_str(), "w", stdout);
	}
#endif
	fast;
	read();
	solve();
	return 0;
}

const ll MAXN = 2 * (1ll << 14);

struct dsu {
	ll n;
	ll t[MAXN];
	bitset<MAXN> val;
	dsu() {}
	dsu(ll n_) {
		n = n_;
		iota(t, t + MAXN, 0);
	}
	ll find(ll v) {
		if (v == t[v]) {
			return v;
		}
		return t[v] = find(t[v]);
	}
	ll join(ll v, ll u) {
		v = find(v), u = find(u);
		if (v == u) {
			return 0;
		}
		t[u] = v;
		return 1;
	}
	void shift() {
		for (ll i = 0; i < n; i++) {
			t[i] = t[i + n] - n;
			val[i] = val[i + n];
			t[i + n] = i + n;
			val[i + n] = 0;
		}
	}
};

ll n, m;
dsu d;

bool checkbit(ll n, ll p) {
	return n & (1ll << p);
}

ll get(char c) {
	if ('0' <= c && c <= '9') {
		return c - '0';
	}
	return 10 + c - 'A';
}

inline void solve() {
	ll cnt1 = 0;
	ll cntm = 0;
	d = dsu(m);
	for (ll i = 0; i < n; i++) {
		for (ll j = 0; j < m / 4; j++) {
			char c;
			cin >> c;
			ll v = get(c);
			for (ll k = 0; k < 4; k++) {
				d.val[m + j * 4 + k] = checkbit(v, 3 - k);
				cnt1 += checkbit(v, 3 - k);
			}
		}
		for (ll i = 0; i < m; i++) {
			if (d.val[i] && d.val[i + m]) {
				cntm += d.join(i + m, i);
			}
			if (i && d.val[i + m] && d.val[i - 1 + m]) {
				cntm += d.join(i - 1 + m, i + m);
			}
		}
		d.shift();
	}
	ll ans = cnt1 - cntm;
	cout << ans << endl;
}

inline void read() {
	cin >> n >> m;
}


#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC optimize ("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
#include <unordered_set>
#include <unordered_map>
#include <random>
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define all(a) (a).begin(), (a).end()
#define sz(a) (ll)((a).size())
#define heap priority_queue
#define hash_map unordered_map
#define hash_set unordered_set
#define ft first
#define sd second
#define fast ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
#define endl "\n"
#define y0 y_0
#define y1 y_1
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef pair<ld, ld> pld;
typedef vector<ll> vll;
typedef set<ll> sll;
typedef map<ll, ll> mll;
const ll inf = numeric_limits<ll>::max() / 2;
const ld eps = 1e-9;
const ld pi = acos(-1);
template<typename T> inline bool mineq(T& a, T b) { return (a > b) ? (a = b, 1) : 0; }
template<typename T> inline bool maxeq(T& a, T b) { return (a < b) ? (a = b, 1) : 0; }

inline void solve(), read();
const string file = "";

signed main() {
#ifndef _DEBUG
	if (file != "") {
		freopen((file + ".in").c_str(), "r", stdin);
		freopen((file + ".out").c_str(), "w", stdout);
	}
#endif
	fast;
	read();
	solve();
	return 0;
}

struct dsu {
	ll n;
	vll val;
	vll t;
	vll ind;
	dsu() {}
	dsu(ll n_) {
		n = n_;
		t.resize(2 * n);
		iota(all(t), 0);
		val.assign(2 * n, 0);
	}
	ll find(ll v) {
		if (v == t[v]) {
			return v;
		}
		return t[v] = find(t[v]);
	}
	ll join(ll v, ll u) {
		v = find(v), u = find(u);
		if (v == u) {
			return 0;
		}
		t[u] = v;
		return 1;
	}
	void shift() {
		for (ll i = 0; i < n; i++) {
			t[i] = t[i + n] - n;
			val[i] = val[i + n];
			t[i + n] = i + n;
			val[i + n] = 0;
		}
	}
};

const ll MAXM = 1ll << 14;
ll n, m;
dsu d;

bool checkbit(ll n, ll p) {
	return n & (1ll << p);
}

ll get(char c) {
	if ('0' <= c && c <= '9') {
		return c - '0';
	}
	return 10 + c - 'A';
}

inline void solve() {
	ll cnt1 = 0;
	ll cntm = 0;
	d = dsu(m);
	for (ll i = 0; i < n; i++) {
		for (ll j = 0; j < m / 4; j++) {
			char c;
			cin >> c;
			ll v = get(c);
			for (ll k = 0; k < 4; k++) {
				d.val[m + j * 4 + k] = checkbit(v, 3 - k);
				cnt1 += checkbit(v, 3 - k);
			}
		}
		for (ll i = 0; i < m; i++) {
			if (d.val[i] && d.val[i + m]) {
				cntm += d.join(i, i + m);
			}
			if (i && d.val[i + m] && d.val[i - 1 + m]) {
				cntm += d.join(i - 1 + m, i + m);
			}
		}
		d.shift();
	}
	ll ans = cnt1 - cntm;
	cout << ans << endl;
}

inline void read() {
	cin >> n >> m;
}


#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC optimize ("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
#include <unordered_set>
#include <unordered_map>
#include <random>
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define all(a) (a).begin(), (a).end()
#define sz(a) (ll)((a).size())
#define heap priority_queue
#define hash_map unordered_map
#define hash_set unordered_set
#define ft first
#define sd second
#define fast ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
#define endl "\n"
#define y0 y_0
#define y1 y_1
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef pair<ld, ld> pld;
typedef vector<ll> vll;
typedef set<ll> sll;
typedef map<ll, ll> mll;
const ll inf = numeric_limits<ll>::max() / 2;
const ld eps = 1e-9;
const ld pi = acos(-1);
template<typename T> inline bool mineq(T& a, T b) { return (a > b) ? (a = b, 1) : 0; }
template<typename T> inline bool maxeq(T& a, T b) { return (a < b) ? (a = b, 1) : 0; }

inline void solve(), read();
const string file = "";

signed main() {
#ifndef _DEBUG
	if (file != "") {
		freopen((file + ".in").c_str(), "r", stdin);
		freopen((file + ".out").c_str(), "w", stdout);
	}
#endif
	fast;
	read();
	solve();
	return 0;
}

struct dsu {
	ll n;
	vll val;
	vll t, rk;
	vll ind;
	dsu() {}
	dsu(ll n_) {
		n = n_;
		t.resize(2 * n);
		iota(all(t), 0);
		rk.assign(2 * n, 0);
		val.assign(2 * n, 0);
	}
	ll find(ll v) {
		if (v == t[v]) {
			return v;
		}
		return t[v] = find(t[v]);
	}
	ll join(ll v, ll u) {
		v = find(v), u = find(u);
		if (v == u) {
			return 0;
		}
		if (rk[v] > rk[u]) {
			swap(v, u);
		}
		t[u] = v;
		if (rk[v] == rk[u]) {
			++rk[v];
		}
		return 1;
	}
	void shift() {
		for (ll i = 0; i < n; i++) {
			t[i] = t[i + n] - n;
			rk[i] = rk[i + n];
			val[i] = val[i + n];
			t[i + n] = i + n;
			rk[i + n] = 0;
			val[i + n] = 0;
		}
	}
};

const ll MAXM = 1ll << 14;
ll n, m;
dsu d;

bool checkbit(ll n, ll p) {
	return n & (1ll << p);
}

ll get(char c) {
	if ('0' <= c && c <= '9') {
		return c - '0';
	}
	return 10 + c - 'A';
}

inline void solve() {
	ll cnt1 = 0;
	ll cntm = 0;
	d = dsu(m);
	for (ll i = 0; i < n; i++) {
		for (ll j = 0; j < m / 4; j++) {
			char c;
			cin >> c;
			ll v = get(c);
			for (ll k = 0; k < 4; k++) {
				d.val[m + j * 4 + k] = checkbit(v, 3 - k);
				cnt1 += checkbit(v, 3 - k);
			}
		}
		for (ll i = 0; i < m; i++) {
			if (d.val[i] && d.val[i + m]) {
				cntm += d.join(i, i + m);
			}
			if (i && d.val[i + m] && d.val[i - 1 + m]) {
				cntm += d.join(i - 1 + m, i + m);
			}
		}
		d.shift();
	}
	ll ans = cnt1 - cntm;
	cout << ans << endl;
}

inline void read() {
	cin >> n >> m;
}