#include<bits/stdc++.h>
using namespace std;
using Int = long long;
 
struct UnionFind{
  Int n;
  vector<Int> r,p;
  UnionFind(){}
  UnionFind(Int sz):n(sz),r(sz,1),p(sz,0){iota(p.begin(),p.end(),0);}
  Int find(Int x){
    return (x==p[x]?x:p[x]=find(p[x]));
  }
  bool same(Int x,Int y){
    return find(x)==find(y);
  }
  void unite(Int x,Int y){
    x=find(x);y=find(y);
    if(x==y) return;
    if(r[x]<r[y]) swap(x,y);
    r[x]+=r[y];
    p[y]=x;
  }
};

template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;} 

template<typename F>
struct FixPoint : F{
  FixPoint(F&& f):F(forward<F>(f)){}
  template<typename... Args>
  decltype(auto) operator()(Args&&... args) const{
    return F::operator()(*this,forward<Args>(args)...);
  }  
};
template<typename F>
inline decltype(auto) MFP(F&& f){
  return FixPoint<F>{forward<F>(f)};
}

//INSERT ABOVE HERE 
signed main(){  
  cin.tie(0);
  ios::sync_with_stdio(0);
 
  Int n,m;
  string s;
  cin>>n>>m>>s;
  vector<char> c(m);
  vector<Int> u(m);
  for(Int i=0;i<m;i++) cin>>c[i]>>u[i];

  vector<int> idx(256);
  for(Int i=0;i<m;i++) idx[c[i]]=i;
  for(Int i=0;i<m;i++) idx[toupper(c[i])]=i;
 
  Int ans=0;
  constexpr Int MOD = 1e9+7;

  vector<Int> v(m);
  auto calc=
    [&](){     
      string t;
      for(Int i=0;i<n;i++){
        if(!isdigit(s[i])&&v[idx[s[i]]]) t+=toupper(s[i]);
        t+=s[i];
      }
      
      Int len=t.size();
      vector<Int> lb(len), ub(len);
      // [lb, ub]
      for(Int i=0;i<len;i++){
        if(isdigit(t[i])){
          lb[i]=ub[i]=t[i]-'0';   
        }else{
          if(isupper(t[i])){
            if(v[idx[t[i]]]==2){
              lb[i]=ub[i]=u[idx[t[i]]]/10;
              if(!ub[i]) return;      
            }else{
              assert(v[idx[t[i]]]==1);
              lb[i]=1;
              ub[i]=u[idx[t[i]]]/10-1;
            }
          }else{    
            if(v[idx[t[i]]]==2){
              lb[i]=0;
              ub[i]=u[idx[t[i]]]%10;      
            }else{
              lb[i]=0;
              ub[i]=min(u[idx[t[i]]],9LL);
            }
          }
        }      
      }
      
      UnionFind uf(m*2);
      vector<Int> x(m*2,-2), y(m*2, 10);
      for(Int i=0;i<len;i++){
        if(isdigit(t[i])) continue;
        Int k=idx[t[i]]+m*!!isupper(t[i]);
        chmax(x[k],lb[i]); 
        chmin(y[k],ub[i]);
      }
     
      for(Int i=0;i<len;i++){
        Int j=len-(i+1);
        if(isdigit(t[i])&&isdigit(t[j])){
          if(t[i]!=t[j]) return;
          continue;
        }
        Int p=idx[t[i]]+m*!!isupper(t[i]);
        Int q=idx[t[j]]+m*!!isupper(t[j]);
        p=uf.find(p);
        q=uf.find(q);
       
        if(!isdigit(t[i])&&isdigit(t[j])){
          chmax(x[p],lb[j]);
          chmin(y[p],ub[j]);
          continue;
        }
       
        if(isdigit(t[i])&&!isdigit(t[j])){
          chmax(x[q],lb[i]);
          chmin(y[q],ub[i]);
          continue;
        }
 
        uf.unite(p,q);
        Int r=uf.find(p);
        chmax(x[r],x[p]);
        chmin(y[r],y[p]);
        chmax(x[r],x[q]);
        chmin(y[r],y[q]);
      }
     
      Int res=1;
      for(Int i=0;i<m*2;i++){
        if(uf.find(i)!=i) continue;
        if(x[i]<0) assert(i>=m);
        if(x[i]<-1) continue;
        res*=max(0LL,y[i]-x[i]+1);     
        res%=MOD;
      }
     
      ans+=res;
      ans%=MOD;
    };
   
   
  MFP([&](auto dfs,Int x){
        if(x==m){
          calc();
          return;
        }
        for(Int i=0;i<3;i++){
          v[x]=i;
          dfs(x+1);
        }
      })(0);
  
  cout<<ans<<endl;
  return 0;
}



Measured memory_bytes: 3268