#include <bits/stdc++.h>
#define GET_MACRO(_1,_2,_3,_4,_5,_6,NAME,...) NAME
#define pr(...) GET_MACRO(__VA_ARGS__,pr6,pr5,pr4,pr3,pr2,pr1)(__VA_ARGS__)
#define Pr(a) (#a)<<"="<<(a)<<" "
#define pr1(a) cerr<<Pr(a)<<endl;
#define pr2(a,b) cerr<<Pr(a)<<Pr(b)<<endl;
#define pr3(a,b,c) cerr<<Pr(a)<<Pr(b)<<Pr(c)<<endl;
#define pr4(a,b,c,d) cerr<<Pr(a)<<Pr(b)<<Pr(c)<<Pr(d)<<endl;
#define pr5(a,b,c,d,e) cerr<<Pr(a)<<Pr(b)<<Pr(c)<<Pr(d)<<Pr(e)<<endl;
#define pr6(a,b,c,d,e,f) cerr<<Pr(a)<<Pr(b)<<Pr(c)<<Pr(d)<<Pr(e)<<Pr(f)<<endl;
#define int long long
#define double long double
using namespace std;
const int INF = 1LL<<55;
const int mod = (1e9)+7;
const double EPS = 1e-8;
const double PI = 6.0 * asin(0.5);
typedef pair<int,int> P;
typedef long long ll;
template<class T> T Max(T &a,T b){return a=max(a,b);}
template<class T> T Min(T &a,T b){return a=min(a,b);}
ostream& operator<<(ostream& o,P p){return o<<"("<<p.first<<","<<p.second<<")";}
istream& operator>>(istream& i,P &p){return i>>p.first>>p.second;}
ostream& operator<<(ostream& o,vector<auto> &a){int i=0;for(auto t:a)o<<(i++?" ":"")<<t;return o;}
istream& operator>>(istream& i,vector<auto> &a){for(auto &t:a)i>>t;return i;}
void prArr(auto a,string s=" "){int i=0;for(auto t:a)cout<<(i++?s:"")<<t;cout<<endl;}

class CumulativeSum{
public:
  vector<int> sum;
  CumulativeSum(){}
  CumulativeSum(vector<int> A){
    int n = A.size();
    sum.resize(n+1,0);
    for(int i=1;i<=n;i++) sum[i] += sum[i-1] + A[i-1];
  }
  int get(int l,int r){assert(l>=0 && r<=(int)sum.size());return sum[r] - sum[l];} //[l,r)
};

ll mod_pow(ll x,ll n){
  ll res=1;
  while(n){
    if(n%2) res=res*x%mod;
    x=x*x%mod;
    n/=2;
  }
  return res;
}

ll divi(ll a,ll b){
  return a * mod_pow(b,mod-2) % mod;
}

ll factorial(int i){
  static vector<ll> k(1e6);
  if(!k[0]){k[0]=1;for(int i=1;i<(int)k.size();i++)k[i]=i*k[i-1]%mod;}
  return k[i];
}

ll nCr(ll n,ll r){
  ll a = mod_pow( factorial(r) * factorial(n-r) % mod ,mod-2);
  return factorial(n) * a % mod;
}

const int N = 3010;
CumulativeSum sum0,sum1;
int n,m;
vector<P> A;
int mem[N][N],used[N][N];

int dfs(int idx,int cnt0,int cnt1,int overlap){
  //pr(idx,cnt0,cnt1,overlap);
  if(used[idx][cnt0]++) return mem[idx][cnt0];
  int l,r; tie(l,r) = A[idx];
  int len = r - l + 1;
  int zero = cnt0 + sum0.get(l+overlap, r+1);
  int one = cnt1 + sum1.get(l+overlap, r+1);
  assert(zero + one == len);
  if(idx == m-1) return mem[idx][cnt0] = nCr(len, zero);



  int res = 0;  
  int noverlap = r - A[idx+1].first + 1;
  // pr(len,zero,one,noverlap);

  if(noverlap <= 0){
    int a = nCr(len, zero);
    int b = dfs(idx+1,0,0,0);
    res = a * b % mod;
  }
  else {
    for(int i = 0;i<=noverlap; i++){ //overlapしてない区間の0の数
      int ncnt0 = i;
      int ncnt1 = (noverlap - i);
      if(zero < ncnt0 ||  one < ncnt1) continue;
      int a = nCr(len - noverlap, zero - i);
      int b = dfs(idx+1, ncnt0, ncnt1, noverlap);
      //pr(i,ncnt0,ncnt1,a,b);
      res += a * b;
      res %= mod;
    }
  }
  return mem[idx][cnt0] = res;
}

signed main(){
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(12);

  cin>>n>>m;
  string str;
  cin>>str;
  {
    vector<int> tmp(n);
    for(int i=0;i<n;i++) tmp[i] = str[i] == '0';
    sum0 = CumulativeSum(tmp);
    
  }

  {
    vector<int> tmp(n);
    for(int i=0;i<n;i++) tmp[i] = str[i] == '1';
    sum1 = CumulativeSum(tmp);
  }
  
  {
    
    int pre = -1;
      for(int i=0;i<m;i++){
        int l,r;
        cin>>l>>r; l--, r--;
        if(pre<r) {
          while(!A.empty() && A.back().first == l) A.pop_back();
          A.push_back(P(l,r));
        }
        Max(pre,r);
      }
      m = A.size();
  }

  //pr(A);
  int ans = dfs(0,0,0,0);
  cout<<ans<<endl;
  
  return 0;
}


Measured memory_bytes: 68096