#include <bits/stdc++.h>
using namespace std;
const int maxn = 100020;
const int maxx = 10000;
const int MOd = 1e9 + 7;
struct node {
  int min, left, count;
  node(int a = 0, int b = 0, int c = 0) {
    min = a;
    left = b;
    count = c;
  }
} segment[maxn * 3];
int a, b, ust[maxn], ar[maxn], lazy[maxn * 3];
int n;
vector<int> w;
node operator+(const node &a, const int &b) {
  return node(a.min + b, a.left, a.count);
}
node merge(const node a, const node b) {
  node t;
  t.min = min(a.min, b.min);
  if (a.min <= b.min)
    t.left = a.left;
  else
    t.left = b.left;
  t.count = 0;
  if (a.min == t.min) t.count += a.count;
  if (b.min == t.min) t.count += b.count;
  return t;
}
void ind(int k) {
  if (k < n) {
    lazy[2 * k] += lazy[k];
    lazy[2 * k + 1] += lazy[k];
  }
  segment[k].min += lazy[k];
  lazy[k] = 0;
}
node find(int k, int b, int s, int x, int y) {
  if (b > y || x > s) return node(1e9, 0, 0);
  if (x <= b && s <= y) return segment[k] + lazy[k];
  ind(k);
  return merge(find(2 * k, b, (b + s) / 2, x, y),
               find(2 * k + 1, (b + s) / 2 + 1, s, x, y)) +
         lazy[k];
}
node update(int k, int b, int s, int x, int y, int m) {
  if (b > y || x > s) return segment[k] + lazy[k];
  if (x <= b && s <= y) {
    lazy[k] += m;
    return segment[k] + lazy[k];
  }
  ind(k);
  segment[k] = merge(update(2 * k, b, (b + s) / 2, x, y, m),
                     update(2 * k + 1, (b + s) / 2 + 1, s, x, y, m));
  return segment[k] + lazy[k];
}
node update(int k, int b, int s, int x, int m) {
  if (b > x || x > s) return segment[k] + lazy[k];
  if (s == b) {
    ind(k);
    return segment[k] = node(m, b, 1);
  }
  ind(k);
  segment[k] = merge(update(2 * k, b, (b + s) / 2, x, m),
                     update(2 * k + 1, (b + s) / 2 + 1, s, x, m));
  return segment[k] + lazy[k];
}
int main() {
  scanf("%d %d", &a, &b);
  n = 1;
  while (n < a) n *= 2;
  w.push_back(0);
  for (int i = 1; i <= maxx; i++)
    if ((i % 10 == 4 || i % 10 == 7) &&
        *lower_bound(w.begin(), w.end(), i / 10) == i / 10)
      w.push_back(i);
  w.push_back(1e9);
  for (int i = 1, j; i <= a; i++) {
    scanf("%d", &j);
    int t = *lower_bound(w.begin(), w.end(), j) - j;
    segment[i + n - 1] = node(t, i, 1);
    for (int k = (i + n - 1) / 2; k; k >>= 1)
      segment[k] = merge(segment[2 * k], segment[2 * k + 1]);
    ar[i] = lower_bound(w.begin(), w.end(), j) - w.begin();
  }
  for (int i = 1; i <= b; i++) {
    char ch[10];
    int x, y;
    scanf("%s %d %d", ch + 1, &x, &y);
    if (ch[1] == 'c') {
      node t = find(1, 1, n, x, y);
      if (t.min > 0)
        printf("0\n");
      else
        printf("%d\n", t.count);
    } else {
      int d;
      scanf("%d", &d);
      update(1, 1, n, x, y, -d);
      node t = find(1, 1, n, x, y);
      while (t.min < 0) {
        int j = w[ar[t.left]] - t.min;
        while (w[ar[t.left]] < j) ar[t.left]++;
        update(1, 1, n, t.left, w[ar[t.left]] - j);
        t = segment[1];
      }
    }
  }
  return 0;
}
