#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;}


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];
  map<char, Int> idx;
  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;
  const 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];
    }
    //cout<<t<<endl;
    
    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);
	  }
	}
      }      
    }

    //for(int i=0;i<len;i++) cout<<i<<":"<<lb[i]<<" "<<ub[i]<<endl;
    
    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;
      //cout<<t[i]<<":"<<lb[i]<<" "<<ub[i]<<endl;
      Int k=idx[t[i]]+m*!!isupper(t[i]);
      //cout<<k<<endl;
      chmax(x[k],lb[i]); 
      chmin(y[k],ub[i]);
    }

    //for(int i=0;i<m*2;i++) cout<<i<<":"<<x[i]<<" "<<y[i]<<endl;
    
    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++){
      //cout<<i<<":"<<x[i]<<" "<<y[i]<<endl;
      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;
    }
    
    //cout<<t<<":"<<res<<endl;
    ans+=res;
    ans%=MOD;
  };
  
  
  function<void(Int)> dfs=[&](Int x){
    if(x==m){
      calc();
      return;
    }
    for(Int i=0;i<3;i++){
      v[x]=i;
      dfs(x+1);
    }
  };
  dfs(0);
  
  cout<<ans<<endl;
  return 0;
}



Measured memory_bytes: 3224