/**
 * Author: Sergey Kopeliovich (Burunduk30@gmail.com)
 * Persistent 1D segment tree
 */

#include <bits/stdc++.h>

using namespace std;

#define forn(i, n) for (int i = 0; i < (int)(n); i++)

struct node {
  node *l, *r;
  int sum;
  node( node *l, node *r ) : l(l), r(r) { sum = l->sum + r->sum; } 
  node( node *l, node *r, int sum ) : l(l), r(r), sum(sum) { }  
};

inline node *buildEmpty( int vl, int vr ) {
  if (vl == vr)
    return new node(0, 0, 0);
  int vm = (vl + vr) / 2;
  return new node(buildEmpty(vl, vm), buildEmpty(vm + 1, vr), 0);
}

inline node *change( node *v, int vl, int vr, int i, int x ) {
  if (vr < i || i < vl)
    return v;
  if (vl == vr) 
    return new node(0, 0, x);
  int vm = (vl + vr) / 2;
  return new node(change(v->l, vl, vm, i, x), change(v->r, vm + 1, vr, i, x));
}

inline int get( node *v, int vl, int vr, int l, int r ) {
  if (vr < l || r < vl)
    return 0;
  if (l <= vl && vr <= r)
    return v->sum;
  int vm = (vl + vr) / 2;
  return get(v->l, vl, vm, l, r) + get(v->r, vm + 1, vr, l, r);
}

inline int readChar();
template <class T = int> inline T readInt(); // skip spaces, read signed int
template <class T> inline void writeInt( T x );
inline void writeChar( int x ); // you may use putchar() instead of it
inline void flush();

int main() {
  #define NAME "permutation"
  assert(freopen(NAME ".in", "r", stdin));
  assert(freopen(NAME ".out", "w", stdout));

  int n = readInt();
  int k = readInt();
  node *root[n + 1];
  root[0] = buildEmpty(0, n - 1);
  forn(i, n) 
    root[i + 1] = change(root[i], 1, n, readInt(), 1);
  while (k--) {
    int L = readInt();
    int R = readInt();
    int X = readInt();
    int Y = readInt();
    writeInt(get(root[R], 1, n, X, Y) - get(root[L - 1], 1, n, X, Y));
    writeChar('\n');
  }
  flush();
  return 0;
}

/** Read */

static const int buf_size = 4096;

inline int getchar_fast() { // you may use getchar() instead of it
  static char buf[buf_size];
  static int len = 0, pos = 0;
  if (pos == len)
    pos = 0, len = fread(buf, 1, buf_size, stdin);
  if (pos == len)
    return -1;
  return buf[pos++];
}

inline int readChar() {
  int c = getchar_fast();
  while (c <= 32)
    c = getchar_fast();
  return c;
}

template <class T>
inline T readInt() {
  int s = 1, c = readChar();
  T x = 0;
  if (c == '-')
    s = -1, c = getchar_fast();
  while ('0' <= c && c <= '9')
    x = x * 10 + c - '0', c = getchar_fast();
  return s == 1 ? x : -x;
}

/** Write */

static int write_pos = 0;
static char write_buf[buf_size];

inline void writeChar( int x ) {
  if (write_pos == buf_size)
    fwrite(write_buf, 1, buf_size, stdout), write_pos = 0;
  write_buf[write_pos++] = x;
}

inline void flush() {
  if (write_pos)
    fwrite(write_buf, 1, write_pos, stdout), write_pos = 0;
}

template <class T> 
inline void writeInt( T x ) {
  if (x < 0)
    writeChar('-'), x = -x;

  char s[24];
  int n = 0;
  while (x || !n)
    s[n++] = '0' + x % 10, x /= 10;
  while (n--)
    writeChar(s[n]);
}