#include using namespace std; #define rep(i, n) for(int i = 0; i < n; i++) #define rep2(i, x, n) for(int i = x; i <= n; i++) #define rep3(i, x, n) for(int i = x; i >= n; i--) #define each(e, v) for(auto &e: v) #define pb push_back #define eb emplace_back #define all(x) x.begin(), x.end() #define rall(x) x.rbegin(), x.rend() #define sz(x) (int)x.size() using ll = long long; using pii = pair; using pil = pair; using pli = pair; using pll = pair; const int MOD = 1000000007; //const int MOD = 998244353; const int inf = (1<<30)-1; const ll INF = (1LL<<60)-1; template bool chmax(T &x, const T &y) {return (x < y)? (x = y, true) : false;}; template bool chmin(T &x, const T &y) {return (x > y)? (x = y, true) : false;}; struct io_setup{ io_setup(){ ios_base::sync_with_stdio(false); cin.tie(NULL); cout << fixed << setprecision(15); } } io_setup; template struct Segment_Tree{ using F = function; int n; vector seg; const F f; const Monoid e1; Segment_Tree(const vector &v, const F &f, const Monoid &e1) : f(f), e1(e1){ int m = v.size(); n = 1; while(n < m) n <<= 1; seg.assign(2*n, e1); copy(begin(v), end(v), begin(seg)+n); for(int i = n-1; i > 0; i--) seg[i] = f(seg[2*i], seg[2*i+1]); } Segment_Tree(int m, const Monoid &x, const F &f, const Monoid &e1) : f(f), e1(e1){ n = 1; while(n < m) n <<= 1; seg.assign(2*n, e1); vector v(m, x); copy(begin(v), end(v), begin(seg)+n); for(int i = n-1; i > 0; i--) seg[i] = f(seg[2*i], seg[2*i+1]); } void change(int i, const Monoid &x, bool update = true){ if(update) seg[i+n] = x; else seg[i+n] = f(seg[i+n], x); i += n; while(i >>= 1){ seg[i] = f(seg[2*i], seg[2*i+1]); } } Monoid query(int l, int r) const{ Monoid L = e1, R = e1; l += n, r += n; while(l < r){ if(l&1) L = f(L, seg[l++]); if(r&1) R = f(seg[--r], R); l >>= 1, r >>= 1; } return f(L, R); } Monoid operator [] (int i) const {return seg[n+i];} template int find_subtree(int i, const C &check, const Monoid &x, Monoid &M, bool type) const{ while(i < n){ Monoid nxt = type? f(seg[2*i+type], M) : f(M, seg[2*i+type]); if(check(nxt, x)) i = 2*i+type; else M = nxt, i = 2*i+(type^1); } return i-n; } template int find_first(int l, const C &check, const Monoid &x) const{ Monoid L = e1; int a = l+n, b = n+n; while(a < b){ if(a&1){ Monoid nxt = f(L, seg[a]); if(check(nxt, x)) return find_subtree(a, check, x, L, false); L = nxt, a++; } a >>= 1, b >>= 1; } return n; } template int find_last(int r, const C &check, const Monoid &x) const{ Monoid R = e1; int a = n, b = r+n; while(a < b){ if(b&1 || a == 1){ Monoid nxt = f(seg[--b], R); if(check(nxt, x)) return find_subtree(b, check, x, R, true); R = nxt; } a >>= 1, b >>= 1; } return -1; } }; template struct Segment_Tree_2D{ using F = function; int n; vector> ids; vector> segs; const F f; const T e; Segment_Tree_2D(int m, const F &f, const T &e) : f(f), e(e){ n = 1; while(n < m) n <<= 1; ids.resize(2*n); } void insert(int x, int y){ x += n; while(x){ ids[x].push_back(y); x >>= 1; } } void build(){ for(int i = 0; i < 2*n; i++){ sort(begin(ids[i]), end(ids[i])); ids[i].erase(unique(begin(ids[i]), end(ids[i])), end(ids[i])); segs.emplace_back((int)ids[i].size(), e, f, e); } } void change(int x, int y, const T &a, bool update = true){ x += n; while(x){ segs[x].change(lower_bound(begin(ids[x]), end(ids[x]), y)-begin(ids[x]), a, update); x >>= 1; } } T query(int lx, int rx, int ly, int ry) const{ T L = e, R = e; lx += n, rx += n; while(lx < rx){ if(lx&1){ int l = lower_bound(begin(ids[lx]), end(ids[lx]), ly)-begin(ids[lx]); int r = lower_bound(begin(ids[lx]), end(ids[lx]), ry)-begin(ids[lx]); L = f(L, segs[lx].query(l, r)); lx++; } if(rx&1){ rx--; int l = lower_bound(begin(ids[rx]), end(ids[rx]), ly)-begin(ids[rx]); int r = lower_bound(begin(ids[rx]), end(ids[rx]), ry)-begin(ids[rx]); R = f(segs[rx].query(l, r), R); } lx >>= 1, rx >>= 1; } return f(L, R); } }; template void print(const vector &v, T x = 0){ int n = v.size(); for(int i = 0; i < n; i++) cout << v[i]+x << (i == n-1? '\n' : ' '); } template void printn(const vector &v, T x = 0){ int n = v.size(); for(int i = 0; i < n; i++) cout << v[i]+x << '\n'; } template void unique(vector &v){ sort(begin(v), end(v)); v.erase(unique(begin(v), end(v)), end(v)); } template vector iota(const vector&v, bool greater = false){ int n = v.size(); vector ret(n); iota(begin(ret), end(ret), 0); sort(begin(ret), end(ret), [&](int i, int j){ return greater? v[i] > v[j] : v[i] < v[j]; }); return ret; } int main(){ int N, Q; cin >> N >> Q; vector l1(N), r1(N), t(Q), l2(Q), r2(Q); vector s1(N), s2(Q); vector ls, rs; rep(i, N){ vector x(3), y(3); rep(j, 3) cin >> x[j] >> y[j]; l1[i] = *min_element(all(x)), r1[i] = *max_element(all(x)); ls.eb(l1[i]), rs.eb(r1[i]); s1[i] = abs((x[1]-x[0])*(y[2]-y[0])-(x[2]-x[0])*(y[1]-y[0])); } rep(i, Q){ cin >> t[i]; if(t[i] == 1){ vector x(3), y(3); rep(j, 3) cin >> x[j] >> y[j]; l2[i] = *min_element(all(x)), r2[i] = *max_element(all(x)); ls.eb(l2[i]), rs.eb(r2[i]); s2[i] = abs((x[1]-x[0])*(y[2]-y[0])-(x[2]-x[0])*(y[1]-y[0])); } else{ cin >> l2[i] >> r2[i]; r2[i]++; } } unique(ls), unique(rs); int K = sz(ls); auto f = [](ll a, ll b) {return max(a, b);}; Segment_Tree_2D seg(K, f, -1); rep(i, N){ l1[i] = lower_bound(all(ls), l1[i])-begin(ls); r1[i] = lower_bound(all(rs), r1[i])-begin(rs); seg.insert(l1[i], r1[i]); } rep(i, Q){ l2[i] = lower_bound(all(ls), l2[i])-begin(ls); r2[i] = lower_bound(all(rs), r2[i])-begin(rs); if(t[i] == 1){ seg.insert(l2[i], r2[i]); } } seg.build(); rep(i, N){ seg.change(l1[i], r1[i], s1[i], false); } rep(i, Q){ if(t[i] == 1){ seg.change(l2[i], r2[i], s2[i], false); } else{ cout << seg.query(l2[i], K, 0, r2[i]) << '\n'; } } }