#include <bits/stdc++.h>
using namespace std;
const long long MOD = 1e9 + 7;
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  long long n, m;
  cin >> n >> m;
  vector<long long> s(n + 1);
  for (long long i = 1; i <= n; i++) cin >> s[i];
  vector<vector<long long>> cows(n + 1);
  for (long long i = 1; i <= m; i++) {
    long long f, h;
    cin >> f >> h;
    cows[f].push_back(h);
  }
  for (long long i = 1; i <= n; i++) sort(cows[i].begin(), cows[i].end());
  vector<vector<long long>> grass(n + 2, vector<long long>(n + 2));
  for (long long i = 1; i <= n; i++) {
    grass[i] = grass[i - 1];
    grass[i][s[i]]++;
  }
  vector<bool> can(n + 1);
  vector<long long> answer(n + 1);
  long long kekw = -1, lulw = -1;
  for (long long border = 0; border <= n; border++) {
    long long sum = 0, mus = 0;
    long long variations = 1, cnt = 0;
    vector<long long> left(n + 1), right(n + 1);
    for (long long i = 1; i <= n; i++) left[i] = grass[border][i];
    for (long long i = 1; i <= n; i++) right[i] = grass[n][i] - left[i];
    bool tf = false;
    long long x;
    for (long long i = 0; i <= n; i++) {
      if (cows[i].size() == 0) continue;
      long long left_pos, right_pos;
      long long l = 0, r = cows[i].size() - 1;
      while (l != r) {
        long long m = (l + r + 1) / 2;
        if (cows[i][m] <= left[i])
          l = m;
        else
          r = m - 1;
      }
      left_pos = l;
      l = 0, r = cows[i].size() - 1;
      while (l != r) {
        long long m = (l + r + 1) / 2;
        if (cows[i][m] <= right[i])
          l = m;
        else
          r = m - 1;
      }
      right_pos = r;
      long long a = min(left_pos, right_pos);
      long long b = max(left_pos, right_pos);
      if ((cows[i][left_pos] == left[i] &&
           grass[border][i] - grass[border - 1][i] == 1) ||
          border == 0) {
        tf = true;
        if (cows[i][0] > right[i]) {
          if (cows[i][0] <= left[i]) cnt++;
          continue;
        }
        if (cows[i][0] <= right[i] && cows[i][0] > left[i]) {
          cnt++;
          variations = (variations * (right_pos + 1)) % MOD;
          continue;
        }
        if (a == b && a == 0) {
          cnt++;
          continue;
        }
        cnt += 2;
        variations =
            (variations * (right_pos + 1 - (left_pos <= right_pos))) % MOD;
        continue;
      }
      if (cows[i][0] > max(left[i], right[i])) continue;
      if (cows[i][0] > min(left[i], right[i])) {
        cnt++;
        variations = variations * (b + 1) % MOD;
        continue;
      }
      if (a == b && a == 0) {
        cnt++;
        variations = 2 * variations % MOD;
        continue;
      }
      cnt += 2;
      variations = variations * (a + 1) * b % MOD;
    }
    if (!tf) continue;
    can[cnt] = true;
    answer[cnt] = (answer[cnt] + variations) % MOD;
  }
  pair<long long, long long> ans = {0, 0};
  for (long long i = 0; i <= n; i++)
    if (can[i]) ans = {i, answer[i]};
  cout << ans.first << " " << ans.second;
  return 0;
}
