Problem:
Score : 900 points

Problem Statement

There is a string S of length N consisting of characters 0 and 1. You will perform the following operation for each i = 1, 2, ..., m:

Arbitrarily permute the characters within the substring of S starting at the l_i-th character from the left and extending through the r_i-th character.

Here, the sequence l_i is non-decreasing.

How many values are possible for S after the M operations, modulo 1000000007(= 10^9+7)?

Constraints

2≦N≦3000

1≦M≦3000

S consists of characters 0 and 1.

The length of S equals N.

1≦l_i < r_i≦N

l_i ≦ l_{i+1}

Input

The input is given from Standard Input in the following format:

N M
S
l_1 r_1
:
l_M r_M

Output

Print the number of the possible values for S after the M operations, modulo 1000000007.

Sample Input 1

5 2
01001
2 4
3 5

Sample Output 1

6

After the first operation, S can be one of the following three: 01001, 00101 and 00011.

After the second operation, S can be one of the following six: 01100, 01010, 01001, 00011, 00101 and 00110.

Sample Input 2

9 3
110111110
1 4
4 6
6 9

Sample Output 2

26

Sample Input 3

11 6
00101000110
2 4
2 3
4 7
5 6
6 10
10 11

Sample Output 3

143

Solution in C++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

#include<iostream>
#include<vector>
#include<algorithm>

int const MOD=1000000007;
int main(){
	std::ios::sync_with_stdio(0);std::cin.tie(0);
	int n,n_operation;std::cin>>n>>n_operation;

	std::vector<int> acm;acm.reserve(n+1);acm.resize(n); // suffix sum accumulation
	for(int& x:acm){
		char c;std::cin>>c;
		x=c-'0';
	}
	for(int i=n-1;i--;)
		acm[i]+=acm[i+1];
	acm.push_back(0);

	auto const sum=[&](int l,int r){return acm[l]-acm[r];};


	std::vector<std::pair<int,int>> ops;ops.reserve(n_operation+1);
	for(int _=n_operation;_--;){
		int l,r;std::cin>>l>>r;--l;
		if(!ops.empty()){
			if(ops.back().first==l){
				ops.back().second=std::max(ops.back().second,r);
				continue;
			}
			else if(ops.back().second>=r)
				continue;
		}
		ops.push_back({l,r});
	}

	ops.push_back({n,n});

	n_operation=-1;

	auto const l=[&](int x){return ops[x].first;};
	auto const r=[&](int x){return ops[x].second;};

	std::vector<std::vector<int>> dp(ops.size());
	// dp[i][n] = number of states of the sequence [0,l(i)] after i steps with sum n

	dp[0].resize(n+1);
	dp[0][sum(0,l(0))]=1;


	std::vector<std::vector<int>> binom(n+1);
	binom[0].assign(1,1);
	for(unsigned i=1;i<binom.size();++i){
		binom[i].resize(i+1);
		std::copy(begin(binom[i-1]),end(binom[i-1]),begin(binom[i]));
		std::transform(begin(binom[i-1]),end(binom[i-1]),++begin(binom[i]),++begin(binom[i]),[](int a,int b){
				a+=b;
				if(a>=MOD)a-=b;
				return a;
				});
	}


	for(int i=1;i<(int)ops.size();++i){
		dp[i].resize(n+1);
		for(int x=0;x<=n;++x){
			// x = sum [0,l(i)] after i steps

			int ans=0;
			for(int y=0;y<=x;++y){
				// y = sum [0,l(i-1)] after >= i-1 steps
				// then perform permutation of l(i-1) .. r(i-1) (after i-1 steps there are
				// sum(0,r(i-1))-y   ones in the range and  y  ones before)
				// such that there are x ones before l(i) <-> x-y ones int  l(i-1) .. l(i)

				int const cntrange=sum(0,r(i-1))-y; // range l..r (i-1)

				int mid=l(i);
				int midcnt=x-y; // desired cnt int l(i-1) .. mid
				if(mid>r(i-1)){
					midcnt-=sum(r(i-1),mid);
					mid=r(i-1);
				}

				// need to count number of seq [l(i-1) .. mid] with midcnt ones
				if(midcnt<=cntrange&& midcnt<=mid-l(i-1) && cntrange-midcnt<=r(i-1)-mid)
					ans=(ans+(int64_t)dp[i-1][y]*binom[mid-l(i-1)][midcnt])%MOD;
			}
			dp[i][x]=ans;
		}
	}

	std::cout<<dp[ops.size()-1][sum(0,n)]<<'\n';
}