#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline T SQR(T x) {
  return x * x;
}
template <typename T>
inline T MIN(T x, T y) {
  return (x < y) ? x : y;
}
template <typename T>
inline T MAX(T x, T y) {
  return (x > y) ? x : y;
}
template <typename T>
inline T ABS(T x) {
  return (x > 0) ? x : -x;
}
template <typename T>
inline void UPDATE_MIN(T &x, T y) {
  if (y < x) {
    x = y;
  }
}
template <typename T>
inline void UPDATE_MAX(T &x, T y) {
  if (x < y) {
    x = y;
  }
}
template <typename T>
inline int ARGMAX(T cont) {
  return max_element(cont.begin(), cont.end()) - cont.begin();
}
template <typename T>
inline int ARGMIN(T cont) {
  return min_element(cont.begin(), cont.end()) - cont.begin();
}
vector<string> split(const string &s, char c) {
  vector<string> v;
  stringstream ss(s);
  string x;
  while (getline(ss, x, c)) v.emplace_back(x);
  return move(v);
}
template <typename T, typename... Args>
inline string arrStr(T arr, int n) {
  stringstream s;
  s << "[";
  for (__typeof(n - 1) i = (0), __tmpvar__end87 = (n - 1); i < __tmpvar__end87;
       i++)
    s << arr[i] << ",";
  s << arr[n - 1] << "]";
  return s.str();
}
template <class T>
inline string TOSTR(const T &x) {
  stringstream ss;
  ss << x;
  return ss.str();
}
inline int gcd(int a, int b) { return a ? gcd(b % a, a) : b; }
inline long long gcd(long long a, long long b) { return a ? gcd(b % a, a) : b; }
inline long long powmod(long long a, long long p, long long m) {
  long long r = 1;
  while (p) {
    if (p & 1) r = r * a % m;
    p >>= 1;
    a = a * a % m;
  }
  return r;
}
struct pairhash {
  template <typename T, typename U>
  std::size_t operator()(const std::pair<T, U> &x) const {
    return std::hash<T>()(x.first) ^ std::hash<U>()(x.second);
  }
};
template <typename K, typename V>
V GetWithDef(const std::unordered_map<K, V> &m, const K &key, const V &defval) {
  auto it = m.find(key);
  return (it == m.end()) ? defval : it->second;
}
template <typename K, typename V>
void SetDef(std::unordered_map<K, V> &m, const K &key, const V &defval) {
  auto it = m.find(key);
  if (it == m.end()) m[key] = defval;
}
const int MOD = 1000 * 1000 * 1000 + 7;
const double PI = 3.1415926535897932384626433832795l;
inline void addto(int &a, int b) {
  a += b;
  if (a >= MOD) a -= MOD;
}
inline int add(int a, int b) {
  a += b;
  if (a >= MOD) a -= MOD;
  return a;
}
inline void subto(int &a, int b) {
  a -= b;
  if (a < 0) a += MOD;
  if (a >= MOD) a -= MOD;
}
inline int sub(int a, int b) {
  a -= b;
  if (a < 0) a += MOD;
  if (a >= MOD) a -= MOD;
  return a;
}
inline void multo(int &a, int b) { a = (long long)a * b % MOD; }
inline int mul(int a, int b) { return (long long)a * b % MOD; }
inline int mulmod(int a, int b, int mod) { return (long long)a * b % mod; }
inline int powmod(int a, int e, int mod) {
  int x;
  for (x = 1; e > 0; e >>= 1) {
    if (e & 1) x = mulmod(x, a, mod);
    a = mulmod(a, a, mod);
  }
  return x;
}
inline int invmod(int a, int mod) { return powmod(a, mod - 2, mod); }
inline long long invmodLL(long long p) {
  long long q = p;
  for (long long a = p * p; a != 1; a *= a) q *= a;
  return q;
}
template <typename T>
struct Zfunc {
  vector<int> z;
  void init(vector<T> &s) {
    int n = s.size();
    z.assign(n, 0);
    for (int i = 1, l = 0, r = 0; i < n; ++i) {
      if (i <= r) z[i] = min(r - i + 1, z[i - l]);
      while (i + z[i] < n && s[z[i]] == s[i + z[i]]) ++z[i];
      if (i + z[i] - 1 > r) l = i, r = i + z[i] - 1;
    }
  }
};
template <typename T>
struct Zpattern {
  Zfunc<T> zf;
  int sn, tn;
  void init(vector<T> &s, vector<T> &t, T delim) {
    sn = s.size();
    tn = t.size();
    vector<T> buf(tn + 1 + sn);
    for (__typeof(tn) i = (0), __tmpvar__end232 = (tn); i < __tmpvar__end232;
         i++)
      buf[i] = t[i];
    buf[tn] = delim;
    for (__typeof(sn) i = (0), __tmpvar__end234 = (sn); i < __tmpvar__end234;
         i++)
      buf[tn + 1 + i] = s[i];
    zf.init(buf);
  }
  int get(int pos) { return zf.z[tn + 1 + pos]; }
};
int N, M, K, L, E;
vector<pair<char, long long> > t;
vector<pair<char, long long> > s;
vector<pair<char, long long> > s2;
void readm(vector<pair<char, long long> > &res, int ln) {
  for (__typeof(ln) i = (0), __tmpvar__end245 = (ln); i < __tmpvar__end245;
       i++) {
    long long l = 0;
    char c = 0;
    scanf("%lld-%c", &l, &c);
    if (res.size() && res.back().first == c) {
      res.back().second += l;
    } else {
      res.push_back({c, l});
    }
  }
}
int main() {
  ios_base::sync_with_stdio(0);
  scanf("%d%d", &N, &M);
  readm(t, N);
  readm(s, M);
  if (s.size() == 1) {
    pair<char, long long> sc = s.back();
    long long ans = 0;
    for (auto &tc : t) {
      if (tc.first == sc.first && tc.second >= sc.second) {
        ans += tc.second - sc.second + 1;
      }
    }
    cout << (ans) << endl;
    return 0;
  }
  s2 = s;
  s2.erase(s2.begin());
  s2.pop_back();
  Zpattern<pair<char, long long> > zpat;
  zpat.init(t, s2, {-1, -1});
  pair<char, long long> c1 = s.front();
  pair<char, long long> c2 = s.back();
  int len = s2.size();
  long long ans = 0;
  1;
  for (__typeof((int)t.size() - len - 1) i = (0), __tmpvar__end296 =
                                                      ((int)t.size() - len - 1);
       i < __tmpvar__end296; i++) {
    1;
    if (zpat.get(i + 1) < len) continue;
    pair<char, long long> x1 = t[i];
    pair<char, long long> x2 = t[i + len + 1];
    if (x1.first != c1.first) continue;
    if (x2.first != c2.first) continue;
    if (x1.second < c1.second) continue;
    if (x2.second < c2.second) continue;
    1;
    ans++;
  }
  cout << (ans) << endl;
  return 0;
}
