/**
* 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]);
}