#include <bits/stdc++.h>
using namespace std;
int num[100050], head[355][100050], fa[100050], last[100050], cnt[355][100050];
int mem, n;
priority_queue<int> que[355];
void read(int &rem) {
  rem = 0;
  char c = getchar();
  while (c < '0' || c > '9') c = getchar();
  while (c >= '0' && c <= '9') rem = rem * 10 + c - 48, c = getchar();
}
int getfa(int x) {
  if (x == fa[x]) {
    return num[x];
  }
  return num[x] = getfa(fa[x]);
}
void query(int l, int r, int val) {
  int ans = 0;
  int sg = (l - 1) / mem + 1, eg = (r - 1) / mem + 1;
  if (sg == eg) {
    for (int i = l; i <= r; i++)
      if (getfa(i) == val) ans++;
  } else {
    for (int i = l; i <= sg * mem; i++)
      if (getfa(i) == val) ans++;
    for (int i = r; i > (eg - 1) * mem; i--)
      if (getfa(i) == val) ans++;
    sg++;
    while (sg < eg) {
      ans += cnt[sg][val];
      sg++;
    }
  }
  printf("%d\n", ans);
}
void cf(int group, int x) {
  int st = (group - 1) * mem;
  if (fa[x] != x)
    for (int i = x % group + 1; i <= min(n - x + 1, mem); i++)
      if (fa[i + st] == x) {
        fa[i + st] = fa[x];
        break;
      } else {
        int setw;
        for (int i = x % group + 1; i <= min(n - x + 1, mem); i++)
          if (fa[i + st] == x) {
            setw = i;
            break;
          }
        head[group][num[setw]] = setw;
        fa[setw] = setw;
      }
}
void findf(int group, int x, int val) {
  num[x] = val;
  if (!head[group][val]) {
    head[group][val] = x;
    fa[x] = x;
    num[x] = val;
  }
  int st = (group - 1) * mem;
  for (int i = x - 1; i > st; i--)
    if (num[i] == val) {
      fa[x] = i;
      return;
    }
}
void del(int group, int val) {
  int tot = 0, note[335];
  int now = que[group].top();
  while (now > val) {
    note[++tot] = now;
    que[group].pop();
    now = que[group].top();
  }
  if (now == val) que[group].pop();
  for (int i = 1; i <= tot; i++) que[group].push(note[i]);
}
void change(int l, int r, int val) {
  int sg = (l - 1) / mem + 1, eg = (r - 1) / mem + 1;
  int tot = 0, note[355];
  if (sg == eg) {
    for (int i = l; i <= r; i++)
      if (num[i] > val) {
        int tag = num[i];
        cnt[sg][tag]--;
        if (!cnt[sg][tag]) del(sg, tag);
        if (!cnt[sg][tag - val]) que[sg].push(tag - val);
        cf(sg, i);
        findf(sg, i, tag - val);
        cnt[sg][tag - val]++;
      }
  } else {
    for (int i = l; i <= sg * mem; i++)
      if (num[i] > val) {
        int tag = num[i];
        cnt[sg][tag]--;
        if (!cnt[sg][tag]) del(sg, tag);
        if (!cnt[sg][tag - val]) que[sg].push(tag - val);
        cf(sg, i);
        findf(sg, i, tag - val);
        cnt[sg][tag - val]++;
      }
    for (int i = r; i > (eg - 1) * mem; i--)
      if (num[i] > val) {
        int tag = num[i];
        cnt[eg][tag]--;
        if (!cnt[eg][tag]) del(eg, tag);
        if (!cnt[eg][tag - val]) que[sg].push(tag - val);
        cf(eg, i);
        findf(eg, i, tag - val);
        cnt[eg][tag - val]++;
      }
    sg++;
    while (sg < eg) {
      tot = 0;
      int now = que[sg].top();
      if (now > val) {
        note[++tot] = now - val;
        que[sg].pop();
      } else
        continue;
      bool flag = 0;
      while (now > val) {
        cnt[sg][now - val] += cnt[sg][now];
        cnt[sg][now] = 0;
        if (!head[sg][now - val]) note[++tot] = now - val;
        findf(sg, head[sg][now], now - val);
        head[sg][now] = 0;
        if (que[sg].empty()) break;
        now = que[sg].top();
        if (now > val) {
          que[sg].pop();
        } else
          break;
      }
      for (int i = 1; i <= tot; i++) que[sg].push(note[i]);
      sg++;
    }
  }
}
int main() {
  int m;
  read(n);
  read(m);
  mem = sqrt(n);
  int group = 0, now = 1;
  while (now <= n) {
    group++;
    for (int i = 1; i <= mem; i++) {
      int w = i + now - 1;
      if (w > n) {
        now = n + 1;
        break;
      }
      read(num[w]);
      if (!head[group][num[w]]) {
        head[group][num[w]] = w;
        fa[w] = w;
        que[group].push(num[w]);
      } else {
        fa[w] = last[num[w]];
      }
      last[num[w]] = w;
      cnt[group][num[w]]++;
    }
    now += mem;
  }
  while (m--) {
    int type, l, r, val;
    read(type), read(l), read(r), read(val);
    if (type == 1)
      change(l, r, val);
    else if (type == 2)
      query(l, r, val);
    for (int i = 1; i <= 4; i++)
      while (!que[i].empty())
        printf("%d ", que[i].top()), que[i].pop(), puts("");
    break;
  }
  return 0;
}
