import java.io.*;
/**
* Created by Sony on 27-12-2017.
*/
class CSUBQ {
public static String FILE
= "CSUBQIn.txt"; // TestGenerator.testGenerator();
if (str.startsWith("C:")) {
} else {
}
StringBuilder sb = new StringBuilder();
int i = 0, N, Q, x, l, r;
long y, L, R;
N = reader.nextInt();
Q = reader.nextInt();
L = reader.nextInt();
R = reader.nextInt();
Segtree t1 = new Segtree(N, R);
Segtree t2 = new Segtree(N, L - 1);
while (i < Q) {
i++;
int option = reader.nextInt();
int a = reader.nextInt();
int b = reader.nextInt();
if (option == 1) {
x = a;
y = b;
if( t1.shouldUpdate(y, x-1) ) {
t1.update(1, x - 1, y);
}
if( t2.shouldUpdate(y, x-1) ) {
t2.update(1, x - 1, y);
}
} else {
l = a;
r = b;
long answer = t1.query(1, l - 1, r - 1).total - t2.query(1, l - 1, r - 1).total;
sb.append(answer).append("\n");
}
}
}
}
class Segtree {
public long M;
public long[] array;
private Node[] heap;
private int sz;
//The Node class represents a partition range of the array.
static class Node {
int pre, suf, inter, l, r, len;
long total;
boolean isLeaf() {
return l == r;
}
public Node() {
}
public Node(Node node) {
this.pre = node.pre;
this.suf = node.suf;
this.inter = node.inter;
this.l = node.l;
this.r = node.r;
this.len = node.len;
this.total = node.total;
}
}
public Segtree(int n, long m) {
this.M = m;
this.array = new long[n];
//The max size of this array is about 2 * 2 ^ log2(n) + 1
sz
= (int) (2 * Math.
pow(2.0,
Math.
floor((Math.
log((double) n
) / Math.
log(2.0)) + 1))); heap = new Node[sz];
build(1, 0, n);
}
public boolean isElementWithinRange(long val) {
return val <= M;
}
private void build(int n, int l, int sz) {
heap[n] = new Node();
heap[n].l = l;
heap[n].r = l + sz - 1;
heap[n].len = sz;
if (sz == 1) {
initLeaf(n, this.array[l]);
return;
} else {
build(2 * n, l, sz / 2);
build(2 * n + 1, l + sz / 2, sz - sz / 2);
balance(n);
}
}
private Node balance(int n) {
Node node = heap[n];
if (node.isLeaf()) {
return node;
}
//get refs to child nodes
//TODO: left and right can be null, or is it.. ??. NO the tree is built in such way the you never get children as null
Node left = heap[2 * n];
Node right = heap[2 * n + 1];
return balance(node, left, right);
}
private Node balance(Node node, Node left, Node right) {
//set prefix for node
if (left.pre < left.len) {
node.pre = left.pre;
} else {
node.pre = left.pre + right.pre;
}
//set suffix for node
if (right.suf < right.len) {
node.suf = right.suf;
} else {
node.suf = left.suf + right.suf;
}
//set intersection for node
node.inter = left.suf + right.pre;
node.total = left.total + right.total + f(left.suf + right.pre) - f(left.suf) - f(right.pre);
node.len = left.len + right.len;
return node;
}
private long f(long n) {
return ((n + 1) * (n)) / 2;
}
private void initLeaf(int n, long y) {
if (isElementWithinRange(y)) {
heap[n].pre = 1;
heap[n].suf = 1;
heap[n].total = 1;
} else {
heap[n].pre = 0;
heap[n].suf = 0;
heap[n].total = 0;
}
}
private void heapify(int n) {
while (n > 0) {
balance(n);
n = n >> 1;
}
}
public void update(int n, int x, long y) {
if (heap[n].isLeaf()) {
array[x] = y;
initLeaf(n, y);
// heapify(n);
return;
}
Node left = heap[2 * n];
if (x <= left.r) {
update(2 * n, x, y);
} else {
update(2 * n + 1, x, y);
}
balance(n);
}
public Node query(int n, int l, int r) {
Node node = new Node(heap[n]);
if (l == node.l && r == node.r) {
return node;
}
Node lc = heap[2 * n];
Node rc = heap[2 * n + 1];
if (r <= lc.r) {
return query(2 * n, l, r);
}
if (l >= rc.l) {
return query(2 * n + 1, l, r);
}
//TODO: is it necessary to create nodes at runtime to answer queries?
Node ln = query(2 * n, l, lc.r);
Node rn = query(2 * n + 1, lc.r + 1, r);
return balance(node, ln, rn);
}
public boolean shouldUpdate(long y, int x) {
return ( (y <= M && array[x] > M ) || (y > M && array[x] <= M) );
}
}
final private int BUFFER_SIZE = 1 << 16;
private byte[] buffer;
private int bufferPointer, bytesRead;
buffer = new byte[BUFFER_SIZE];
bufferPointer = bytesRead = 0;
}
buffer = new byte[BUFFER_SIZE];
bufferPointer = bytesRead = 0;
}
byte[] buf = new byte[64]; // line length
int cnt = 0, c;
while ((c = read()) != -1) {
if (c == '\n')
break;
buf[cnt++] = (byte) c;
}
return new String(buf,
0, cnt
); }
int ret = 0;
byte c = read();
while (c <= ' ')
c = read();
boolean neg = (c == '-');
if (neg)
c = read();
do {
ret = ret * 10 + c - '0';
} while ((c = read()) >= '0' && c <= '9');
if (neg)
return -ret;
return ret;
}
long ret = 0;
byte c = read();
while (c <= ' ')
c = read();
boolean neg = (c == '-');
if (neg)
c = read();
do {
ret = ret * 10 + c - '0';
}
while ((c = read()) >= '0' && c <= '9');
if (neg)
return -ret;
return ret;
}
double ret = 0, div = 1;
byte c = read();
while (c <= ' ')
c = read();
boolean neg = (c == '-');
if (neg)
c = read();
do {
ret = ret * 10 + c - '0';
}
while ((c = read()) >= '0' && c <= '9');
if (c == '.') {
while ((c = read()) >= '0' && c <= '9') {
ret += (c - '0') / (div *= 10);
}
}
if (neg)
return -ret;
return ret;
}
bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);
if (bytesRead == -1)
buffer[0] = -1;
}
if (bufferPointer == bytesRead)
fillBuffer();
return buffer[bufferPointer++];
}
if (din == null)
return;
din.close();
}
}
//5 6 1 10
//1 1 2
//2 1 5
//1 3 11
//1 4 3
//2 3 5
//2 1 5
//#2
//7 7 1 6
//2 1 7
//1 1 4
//2 1 7
//2 1 2
//1 4 6
//1 2 1
//2 1 7
//#3
//7 7 1 6
//2 1 7
//1 2 4
//2 1 7
//2 1 2
//1 5 6
//1 3 1
//2 1 7
//#4
//5 9 1 5
//2 1 5
//1 2 1
//2 1 5
//1 2 0
//2 1 5
//1 1 1
//2 1 5
//1 2 1
//2 1 5
//#5
//10 7 1 500
//1 5 45
//2 3 6
//1 8 600
//2 2 7
//1 10 10
//1 2 800
//2 1 10
//#6
//100 7 100 100000000
//1 50 45
//2 30 60
//1 80 600
//2 20 70
//1 100 99
//1 20 800
//2 10 100
//#7
//100 5 100 100000000
//1 80 600
//2 20 70
//1 100 100
//1 20 800
//2 10 100
//class TestGenerator {
// public static void testGenerator() throws IOException {
// BufferedWriter writer = new BufferedWriter(new FileWriter(Mainy.FILE, true));
// int n = 1;
//
// writer.append(100000 + " ");
// writer.append(100000 + " ");
// writer.append(2 + " ");
// writer.append(100000000 + "\n");
//
// writer.append("1 " + 1 + " " + 100000 + "\n");
//
// for (int i = 1; i < 100000; i++) {
// writer.append("2 " + i + " " + i + "\n");
// }
//// writer.append("\n");
//// for (int i = 0; i < n; i++) {
//// writer.append(0 + " ");
//// }
//// writer.append("\n");
//// for (int i = n - 1; i >= 0; i--) {
//// writer.append(i + " ");
//// }
//
// writer.close();
// }
//}