#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#pragma GCC optimize("-ffloat-store")
using namespace std;
clock_t time_p = clock();
void aryanc403() {}
const int INF = 0xFFFFFFFFFFFFFFFL;
int seed;
mt19937 rng(seed = chrono::steady_clock::now().time_since_epoch().count());
inline int rnd(int l = 0, int r = INF) {
  return uniform_int_distribution<int>(l, r)(rng);
}
class CMP {
 public:
  bool operator()(pair<int, int> a, pair<int, int> b) {
    return !(a.first < b.first || (a.first == b.first && a.second <= b.second));
  }
};
void add(map<int, int> &m, int x, int cnt = 1) {
  auto jt = m.find(x);
  if (jt == m.end())
    m.insert({x, cnt});
  else
    jt->second += cnt;
}
void del(map<int, int> &m, int x, int cnt = 1) {
  auto jt = m.find(x);
  if (jt->second <= cnt)
    m.erase(jt);
  else
    jt->second -= cnt;
}
bool cmp(const pair<int, int> &a, const pair<int, int> &b) {
  return a.first < b.first || (a.first == b.first && a.second < b.second);
}
const int mod = 1000000007L;
const int N = 1LL << 12;
int T, n, i, j, k, in, cnt, l, r, u, v, x, y;
int m;
vector<int> a;
bitset<N> vis[4 * N];
bool isOn(const string &s, int y) {
  char c = s[y / 4];
  int v = 0;
  if ('0' <= c && c <= '9')
    v = c - '0';
  else
    v = c - 'A' + 10;
  y %= 4;
  y = 3 - y;
  return v & (1 << y);
}
struct UF {
  vector<int> e;
  UF(int n) : e(n) {
    for (int i = 0; i < n; ++i) e[i] = i;
  }
  bool same_set(int a, int b) { return find(a) == find(b); }
  int find(int x) { return (e[x] == x) ? x : e[x] = find(e[x]); }
  bool join(int a, int b) {
    a = find(a), b = find(b);
    if (a == b) return false;
    e[b] = a;
    return true;
  }
  void reinit() {
    const int n = (int)(e).size();
    vector<int> m(n);
    for (int i = n / 2; i < n; ++i) m[find(i)] = i - n / 2;
    ;
    for (int i = n / 2; i < n; ++i) {
      e[i - n / 2] = m[e[i]];
      e[i] = i;
    };
  }
};
int main(void) {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  {
    cin >> n >> m;
    ;
    int ans = 0;
    for (i = 0; i < (n); ++i) {
      string s;
      cin >> s;
      for (j = 0; j < (m); ++j) {
        vis[j][i] = isOn(s, j);
        ans += vis[j][i];
      }
    }
    swap(n, m);
    UF b(2 * m);
    for (i = 0; i < (n); ++i) {
      for (j = 0; j < (m - 1); ++j) {
        if (vis[i][j] && vis[i][j + 1]) {
          ans -= b.join(j + m, j + m + 1);
        }
      }
      if (i == 0) {
        b.reinit();
        continue;
      }
      for (j = 0; j < (m); ++j) {
        if (vis[i][j] && vis[i - 1][j]) {
          ans -= b.join(j, j + m);
        }
      }
      b.reinit();
    }
    cout << ans << "\n";
  }
  aryanc403();
  return 0;
}
