#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#define sf scanf
#define pf printf
#define pb push_back
#define mp make_pair
#define PI ( acos(-1.0) )
#define mod 1000000007LL
#define IN freopen("C.in","r",stdin)
#define OUT freopen("output.txt","w",stdout)
#define FOR(i,a,b) for(i=a ; i<=b ; i++)
#define DBG pf("Hi\n")
#define INF 1000000000
#define i64 long long int
#define eps (1e-8)
#define xx first
#define yy second
#define ln 17
#define off 100

using namespace __gnu_pbds;
using namespace std ;

typedef tree< i64, null_type, less<i64>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;
typedef pair<int, int> pii;

#define maxn 500005

class numberTheory{

public:
    numberTheory(){}

    pii extendedEuclid(i64 a, i64 b) { // returns x, y | ax + by = gcd(a,b)

        if(b == 0) return pii( a >= 0 ? 1 : -1 , 0LL);
        else {
            pii d = extendedEuclid(b, a % b);
            return pii(d.yy, d.xx - d.yy * (a / b));
        }

    }

    i64 modularInverse(i64 a, i64 n) {
        pair<i64,i64> ret = extendedEuclid(a, n);
        return ((ret.xx % n) + n) % n;
    }


    i64 bigMod(i64 a, i64 n , i64 m)
    {
        if(n==0) return 1 ;
        i64 ret = bigMod(a,n/2,m) ;
        ret = (ret*ret)%m ;
        if(n%2) ret = (ret*a)%m ;
        return ret ;
    }
};

const i64 N = 200000 ;

i64 fact[N+5] , invFact[N+5] ;

i64 C(i64 n, i64 r)
{
    if( n<0 || r<0 || r>n ) return 0 ;
    i64 ret = (fact[n]*invFact[r])%mod ;
    return (ret*invFact[n-r])%mod ;
}

void preprocess()
{
    numberTheory nt ;

    fact[0] = 1 ;
    for(i64 x=1 ; x<=N ; x++) fact[x] = (fact[x-1]*x)%mod ;

    invFact[N] = nt.modularInverse(fact[N],mod) ;

    for(i64 x=N-1 ; x>=0 ; x--) invFact[x] = (invFact[x+1]*(x+1) )%mod ;
}


vector < pair<int,int> > vp ;

char str[maxn] ;
int s[maxn] ;

int dp[3005][3005] ;

int n , m ;

int f(int i , int ones)
{
    if( i==m ) return 1 ;
    if( dp[i][ones] != -1  ) return dp[i][ones] ;

    int la = vp[i].xx , ra = vp[i].yy ;

    int totones = ones ;
    int lb = la , rb =  ra ;
    if( i > 0 && vp[i-1].yy >= vp[i].xx ) lb = vp[i-1].yy+1 ;

    totones += (s[rb]-s[lb-1]) ;

    int totzeroes = (ra-la+1) - totones ;

    int ans = 0 ;
    int rc = ra ;
    if( i+1 < m && vp[i+1].xx <= rc ) rc = vp[i+1].xx-1 ;

 //   printf("--- %d %d la:%d ra:%d lb:%d rb:%d rc:%d\n",i,ones,la,ra,lb,rb,rc) ;

    for(int j=0 ; j<=(rc-la+1) ; j++ )
    {
        int cone = j , czero = (rc-la+1) - cone ;
        if( cone > totones || czero > totzeroes ) continue ;

        int ret = C(cone+czero,cone) ;
        if( i+1 < m ) ret = (1LL*ret*f(i+1, totones-cone) )%mod ;
//        DBG ;
        ans = (ans+ ret)%mod ;
    }

    return dp[i][ones] = ans ;
}

int main()
{
    preprocess() ;

    scanf("%d %d",&n,&m) ;

    scanf("%s",str) ;
    for(int i=1 ; i<=n ; i++)
    {
        s[i]  = s[i-1] ;
        if( str[i-1]=='1' ) s[i]++ ;
    }

    for(int i=1 ; i<=m ; i++)
    {
        int l , r ;
        scanf("%d %d",&l,&r) ;

        if( vp.size() != 0 )
        {
            int sz = (int)vp.size() ;

            if( vp[sz-1].xx == l ) vp[sz-1].yy = max(vp[sz-1].yy,r) ;
            else if( vp[sz-1].yy < r ) vp.pb( mp(l,r) ) ;
        }
        else vp.pb( mp(l,r) ) ;
    }

    m = vp.size() ;

 //   for( auto p: vp ) printf("%d %d\n",p.xx,p.yy ) ;

    memset(dp,-1,sizeof(dp)) ;

    int ans = f(0,0) ;

    printf("%d\n",ans) ;

    return 0 ;
}


Measured memory_bytes: 41216