#include <bits/stdc++.h>
using i64 = long long;
#ifdef DEBUG
#include "debug.h"
#else
#define debug(...) void(23)
#endif
constexpr i64 inf = i64(1E18);
#define def int mid = (l + r) >> 1, lv = v + 1, rv = v + ((mid - l + 1) << 1)
// c = -1 [l, r] goes in [l, r]
// othws: [s, p] goes from p with c+max(0,x-s)
struct node {
int l;
int r;
i64 c;
node() {}
node(int l_, int r_, i64 c_ = -1) : l(l_), r(r_), c(c_) {}
};
node unite(const node& lhs, const node& rhs) {
if (lhs.c == -1 && rhs.c == -1) {
if (lhs.l >= rhs.r) {
return node(lhs.l, rhs.r, lhs.l - rhs.r);
} else if (lhs.r <= rhs.l) {
return node(lhs.r, rhs.l, 0);
} else {
assert(std::max(lhs.l, rhs.l) <= std::min(lhs.r, rhs.r));
return node(std::max(lhs.l, rhs.l), std::min(lhs.r, rhs.r));
}
} else if (lhs.c == -1) {
if (rhs.l <= lhs.l) {
return node(lhs.l, rhs.r, rhs.c + lhs.l - rhs.l);
} else if (rhs.l >= lhs.r) {
return node(lhs.r, rhs.r, rhs.c);
} else {
return rhs;
}
} else if (rhs.c == -1) {
if (lhs.r <= rhs.l) {
return node(lhs.l, rhs.l, lhs.c);
} else if (lhs.r >= rhs.r) {
return node(lhs.l, rhs.r, lhs.c + lhs.r - rhs.r);
} else {
return lhs;
}
} else {
return node(lhs.l, rhs.r, lhs.c + rhs.c + std::max(0, lhs.r - rhs.l));
}
}
int N;
std::vector<node> tree;
std::vector<node> eert;
void build(int v, int l, int r, std::vector<std::array<int, 2>>& G) {
if (l == r) {
tree[v] = node(G[l][0] - l, G[l][1] - l - 1);
eert[v] = node(G[l][0] + l + 1, G[l][1] + l);
return;
}
def;
build(lv, l, mid, G);
build(rv, mid + 1, r, G);
tree[v] = unite(tree[lv], tree[rv]);
eert[v] = unite(eert[rv], eert[lv]);
}
void modify(int v, int l, int r, int p, std::array<int, 2> gx) {
if (l == r) {
tree[v] = node(gx[0] - l, gx[1] - l - 1);
eert[v] = node(gx[0] + l + 1, gx[1] + l);
return;
}
def;
if (p <= mid) {
modify(lv, l, mid, p, gx);
} else {
modify(rv, mid + 1, r, p, gx);
}
tree[v] = unite(tree[lv], tree[rv]);
eert[v] = unite(eert[rv], eert[lv]);
}
node get(int v, int l, int r, int ql, int qr) {
if (ql == l && r == qr) {
return tree[v];
}
def;
if (qr <= mid) {
return get(lv, l, mid, ql, qr);
} else if (mid + 1 <= ql) {
return get(rv, mid + 1, r, ql, qr);
} else {
return unite(get(lv, l, mid, ql, mid),
get(rv, mid + 1, r, mid + 1, qr));
}
}
node teg(int v, int l, int r, int ql, int qr) {
if (ql == l && r == qr) {
return eert[v];
}
def;
if (qr <= mid) {
return teg(lv, l, mid, ql, qr);
} else if (mid + 1 <= ql) {
return teg(rv, mid + 1, r, ql, qr);
} else {
return unite(teg(rv, mid + 1, r, mid + 1, qr),
teg(lv, l, mid, ql, mid));
}
}
int main() {
std::ios_base::sync_with_stdio(false);
std::cin.tie(nullptr);
int Q;
std::cin >> N >> Q;
std::vector<std::array<int, 2>> G(N - 1);
for (int i = 0; i < N - 1; ++i) {
std::cin >> G[i][0] >> G[i][1];
}
if (N != 1) {
tree.resize((N - 1) << 1);
eert.resize((N - 1) << 1);
build(0, 0, N - 2, G);
}
for (int i = 0; i < Q; ++i) {
int TP;
std::cin >> TP;
if (TP == 1) {
int P, S, T;
std::cin >> P >> S >> T;
--P;
modify(0, 0, N - 2, P, {S, T});
} else {
int A, B, C, D;
std::cin >> A >> B >> C >> D;
--A, --C;
if (A == C) {
std::cout << std::max(0, B - D) << '\n';
} else if (A < C) {
B -= A;
D -= C;
node nd = unite(unite(node(B, B), get(0, 0, N - 2, A, C - 1)), node(D, D));
std::cout << nd.c << '\n';
} else {
B += A;
D += C;
node nd = unite(unite(node(B, B), teg(0, 0, N - 2, C, A - 1)), node(D, D));
std::cout << nd.c << '\n';
}
}
}
return 0;
}