#include <bits/stdc++.h>   using namespace std;   inline int read() {     char c = getchar();     int x = 0, f = 1;     for (; !isdigit(c); c = getchar())       if (c ==  - ) f = -1;     for (; isdigit(c); c = getchar()) x = x * 10 + c -  0 ;     return x * f;   }   const int MAXN = 1e6 + 5;   struct Node {     long long cnt;     char c;     inline bool operator==(Node &b) { return cnt == b.cnt && c == b.c; }     inline bool operator!=(Node &b) { return cnt != b.cnt || c != b.c; }   } p1[MAXN], p2[MAXN], up1[MAXN], up2[MAXN], cpy[MAXN];   int nxt[MAXN];   int N, M, l1, l2;   char s[MAXN];   bool pos[MAXN];   inline void Unique1() {     l1 = 0;     long long now = 0;     for (int i = 1; i <= N; i++)       if (p1[i].c != p1[i - 1].c) {         up1[l1].cnt = now;         up1[++l1].c = p1[i].c;         now = p1[i].cnt;       } else         now += p1[i].cnt;     up1[l1].cnt = now;     N = l1;     memcpy(p1, up1, sizeof(p1));   }   inline void Unique2() {     l2 = 0;     long long now = 0;     for (int i = 1; i <= M; i++)       if (p2[i].c != p2[i - 1].c) {         up2[l2].cnt = now;         up2[++l2].c = p2[i].c;         now = p2[i].cnt;       } else         now += p2[i].cnt;     up2[l2].cnt = now;     M = l2;     memcpy(p2, up2, sizeof(p2));   }   namespace Subtask1 {   inline void Main() {     long long ans = 0;     for (int i = 1; i <= N; i++)       if (p1[i].c == p2[1].c) {         if (p1[i].cnt >= p2[1].cnt) ans += p1[i].cnt - p2[1].cnt + 1;       }     printf( %I64d n , ans);   }   }  // namespace Subtask1   namespace Subtask2 {   inline void Main() {     long long ans = 0;     for (int i = 1; i < N; i++)       if (p1[i].c == p2[1].c && p1[i + 1].c == p2[2].c) {         if (p1[i].cnt >= p2[i].cnt && p1[i + 1].cnt >= p2[2].cnt) ans++;       }     printf( %I64d n , ans);   }   }  // namespace Subtask2   int main() {     N = read();     M = read();     for (int i = 1; i <= N; i++) {       scanf( %s , s);       int len = strlen(s), ret = 0;       bool flg = false;       char c;       for (int j = 0; j < len; j++) {         if (s[j] ==  - ) {           flg = true;           continue;         }         if (!flg)           ret = ret * 10 + s[j] -  0 ;         else           c = s[j];       }       p1[i] = {ret, c};     }     Unique1();     for (int i = 1; i <= M; i++) {       scanf( %s , s);       int len = strlen(s), ret = 0;       bool flg = false;       char c;       for (int j = 0; j < len; j++) {         if (s[j] ==  - ) {           flg = true;           continue;         }         if (!flg)           ret = ret * 10 + s[j] -  0 ;         else           c = s[j];       }       p2[i] = {ret, c};     }     Unique2();     if (M == 1) return Subtask1::Main(), 0;     if (M == 2) return Subtask2::Main(), 0;     int p = 0;     for (int i = 2; i < M; i++) cpy[++p] = p2[i];     int j = 0;     for (int i = 2; i <= p; i++) {       while (j && cpy[i] != cpy[j + 1]) j = nxt[j];       if (cpy[i] == cpy[j + 1]) j++;       nxt[i] = j;     }     for (int i = 1; i <= N; i++) {       while (j && p1[i] != cpy[j + 1]) j = nxt[j];       if (p1[i] == cpy[j + 1]) j++;       if (j == p) pos[i] = true, j = nxt[j];     }     long long ans = 0;     for (int i = p + 1; i < N; i++)       if (pos[i]) {         if (p1[i + 1].c == p2[M].c && p1[i + 1].cnt >= p2[M].cnt &&             p1[i - p].c == p2[1].c && p1[i - p].cnt >= p2[1].cnt)           ans++;       }     printf( %I64d n , ans);     return 0;   }