#include <bits/stdc++.h>
using namespace std;
const int MAXM = (1 << 14);
int parent[MAXM + MAXM + 1];
bool currRow[MAXM + 1];
int N, M;
char str[MAXM];
int result = 0;
int getNum(char c) {
  if (isdigit(c)) {
    return c - '0';
  } else {
    return c - 'A' + 10;
  }
}
int getGroup(int n) {
  if (parent[n] == n) {
    return n;
  }
  return parent[n] = getGroup(parent[n]);
}
void joinGroup(int group1, int group2) {
  int g1 = getGroup(group1), g2 = getGroup(group2);
  if (g1 != g2) {
    result--;
    if (g1 > g2) {
      swap(g1, g2);
    }
    parent[g2] = g1;
  }
}
int main() {
  scanf("%d%d", &N, &M);
  char c = getchar();
  memset(parent, 0xff, sizeof(parent));
  while (N--) {
    scanf("%s", str);
    for (int i = 0; str[i]; i++) {
      int n = getNum(str[i]);
      for (int j = 0; j < 4; j++) {
        currRow[i * 4 + 4 - j] = n & (1 << j);
      }
    }
    for (int i = 1; i <= M; i++) {
      if (currRow[i]) {
        if (currRow[i - 1]) {
          parent[i] = parent[i - 1];
        } else {
          parent[i] = i;
          result++;
        }
        if (parent[i + M] != -1) {
          joinGroup(parent[i + M], parent[i]);
        }
      }
    }
    for (int i = 1; i <= M; i++) {
      if (parent[i] != -1) {
        parent[i] = getGroup(parent[i]);
        parent[i + M] = parent[i] + M;
      } else {
        parent[i + M] = -1;
      }
    }
    memset(parent + 1, 0xff, sizeof(int) * M);
  }
  cout << result << endl;
  return 0;
}
