#include <bits/stdc++.h>

using namespace std;
using int64 = long long;

constexpr int DEBUG = 0;

struct Range {
  int l, r;
  Range(int l, int r) : l(l), r(r) {}
};

template<class T> inline bool UpdateMin(T& a, T b) {
  if (a > b) { a = b; return 1; } return 0;
}

template<class T> inline bool UpdateMax(T& a, T b) {
  if (a < b) { a = b; return 1; } return 0;
}

template<typename T>
vector<vector<T>> Make2DVector(int d1, int d2, T default_value) {
  return vector<vector<T>>(d1, vector<T>(d2, default_value));
}

constexpr int64 P = 1000000007;

struct FiniteField {
 private:
  int64 x;
  static inline int64 Normalize(int64 x) {
    if (0 <= x && x < P) return x; x %= P; if (x < 0) x += P; return x;
  }
 public:
  FiniteField(int64 x) : x(Normalize(x)) {}
  FiniteField() : x(0) {}
  int64 Value() const { return x; }
  inline FiniteField operator+(FiniteField o) const {
    FiniteField r(*this); r += o; return r;
  }
  inline FiniteField operator-(FiniteField o) const {
    FiniteField r(*this); r -= o; return r;
  }
  inline FiniteField operator* (FiniteField o) const {
    FiniteField r(*this); r *= o; return r;
  }
  inline FiniteField operator/ (FiniteField o) const {
    FiniteField r(*this); r /= o; return r;
  }
  inline void operator+= (FiniteField o) { x = (x + o.x) % P; }
  inline void operator-= (FiniteField o) { x = (x + P - o.x) % P; }
  inline void operator*= (FiniteField o) { x = (x * o.x) % P; }
  void operator/=(FiniteField o) {
    int64 p = P - 2; while (p) { if (p % 2) { *this *= o; } o *= o; p /= 2; }
  }
};

ostream& operator<<(ostream& s, const FiniteField& v) { s << v.Value(); return s; }

tuple<vector<FiniteField>, vector<FiniteField>> MakeFactorialTables(int n) {
  vector<FiniteField> factorials(n + 1);
  vector<FiniteField> inverse_factorials(n + 1);
  factorials[0] = 1;
  for (int i = 1; i <= n; i++) {
    factorials[i] = factorials[i - 1] * i;
  }
  inverse_factorials[n] = FiniteField(1) / factorials[n];
  for (int i = n; i >= 1; i--) {
    inverse_factorials[i - 1] = inverse_factorials[i] * i;
  }
  return make_tuple(factorials, inverse_factorials);
}

// Vector
template<typename T> ostream& operator<<(ostream& s, const vector<T>& v) {
  int len = v.size();
  s << "[";
	for (int i = 0; i < len; i++) {
    if (i > 0) s << ", ";
		s << v[i];
  }
  s << "]";
  return s;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);

  int n, m;
  cin >> n >> m;
  string s;
  cin >> s;

  vector<Range> ranges;
  int r_max = -1;
  for (int i = 0; i < m; i++) {
    int l, r;
    cin >> l >> r;
    l--;
    if (r < r_max) continue;
    UpdateMax(r_max, r);
    ranges.push_back(Range(l, r));
  }

  ranges.push_back(Range(n, n));

  m = ranges.size();

  vector<FiniteField> fs, ifs;
  tie(fs, ifs) = MakeFactorialTables(n + 1);
  auto c_fn = [&](int a, int b) -> FiniteField {
    if (a < b) return 0;
    return fs[a] * ifs[b] * ifs[a - b];
  };

  auto dp = Make2DVector(m, n + 1, FiniteField(0));

  int c0 = 0;
  for (int i = ranges[0].l; i < ranges[0].r; i++) {
    if (s[i] == '1') c0++;
  }
  dp[0][c0] = 1;

  for (int k = 1; k < m; k++) {
    if (DEBUG) cout << k << " " << ranges[k].l << " " << ranges[k].r << endl;
    if (ranges[k].l < ranges[k - 1].r) {
      if (DEBUG) cout << "A" << endl;
      int c = 0;
      for (int i = ranges[k - 1].r; i < ranges[k].r; i++) {
        if (s[i] == '1') c++;
      }

      int d = ranges[k].l - ranges[k - 1].l;

      for (int l = 0; l <= n; l++) {
        if (dp[k - 1][l].Value() == 0) continue;

        for (int x = 0; x <= d; x++) {
          int nl = ranges[k - 1].r - ranges[k - 1].l - l;
          if (x > l) continue;
          if (d - x > nl) continue;
          // if (l + c - x > ranges[k].r - ranges[k].l) continue;
          dp[k][l + c - x] += c_fn(d, x) * dp[k - 1][l];
        }
      }
    } else {
      if (DEBUG) cout << "B" << endl;
      int c = 0;
      for (int i = ranges[k].l; i < ranges[k].r; i++) {
        if (s[i] == '1') c++;
      }

      int d = ranges[k - 1].r - ranges[k - 1].l;

      for (int l = 0; l <= n; l++) {
        if (dp[k - 1][l].Value() == 0) continue;
        dp[k][c] += c_fn(d, l) * dp[k - 1][l];
      }
    }
  }

  if (DEBUG) {
    for (int i = 0; i < m; i++) {
      cout << "dp[" << i << "]: " << dp[i] << endl;
    }
  }

  FiniteField ans = 0;
  for (int i = 0; i <= n; i++) {
    ans += dp[m - 1][i];
  }
  cout << ans << endl;
}

Measured memory_bytes: 46976