#include<bits/stdc++.h>
using namespace std;using ll=long long;const int maxN=1e7+5;
using ll = long long;
const int MOD = 1e9 + 7;
template<ll M>
struct modint {
static ll _pow(ll n, ll k) {
ll r = 1;
for (; k > 0; k >>= 1, n = (n*n)%M)
if (k&1) r = (r*n)%M;
return r;
}
ll v; modint(ll n = 0) : v(n%M) { v += (M&(0-(v<0))); }
friend string to_string(const modint n) { return to_string(n.v); }
friend istream& operator>>(istream& i, modint& n) { return i >> n.v; }
friend ostream& operator<<(ostream& o, const modint n) { return o << n.v; }
template<typename T> explicit operator T() { return T(v); }
friend bool operator==(const modint n, const modint m) { return n.v == m.v; }
friend bool operator!=(const modint n, const modint m) { return n.v != m.v; }
friend bool operator<(const modint n, const modint m) { return n.v < m.v; }
friend bool operator<=(const modint n, const modint m) { return n.v <= m.v; }
friend bool operator>(const modint n, const modint m) { return n.v > m.v; }
friend bool operator>=(const modint n, const modint m) { return n.v >= m.v; }
modint& operator+=(const modint n) { v += n.v; v -= (M&(0-(v>=M))); return *this; }
modint& operator-=(const modint n) { v -= n.v; v += (M&(0-(v<0))); return *this; }
modint& operator*=(const modint n) { v = (v*n.v)%M; return *this; }
modint& operator/=(const modint n) { v = (v*_pow(n.v, M-2))%M; return *this; }
friend modint operator+(const modint n, const modint m) { return modint(n) += m; }
friend modint operator-(const modint n, const modint m) { return modint(n) -= m; }
friend modint operator*(const modint n, const modint m) { return modint(n) *= m; }
friend modint operator/(const modint n, const modint m) { return modint(n) /= m; }
modint& operator++() { return *this += 1; }
modint& operator--() { return *this -= 1; }
modint operator++(int) { modint t = *this; return *this += 1, t; }
modint operator--(int) { modint t = *this; return *this -= 1, t; }
modint operator+() { return *this; }
modint operator-() { return modint(0) -= *this; }
modint pow(const ll k) const {
return k < 0 ? _pow(v, M-1-(-k%(M-1))) : _pow(v, k);
}
modint inv() const { return _pow(v, M-2); }
};
using mint = modint<int(MOD)>;
// check add
class segtree {
public:
struct node {
mint mul = 1;
mint add = 1;
void apply(int l, int r, mint x) {
mul = mul*(x.pow(r-l+1));
add = add*x;
}
};
node unite(const node &a, const node &b) const {
node res;
res.mul = a.mul*b.mul;
return res;
}
inline void push(int x, int l, int r) {
int y = (l + r) >> 1;
int z = x + ((y - l + 1) << 1);
if (tree[x].add != 1) { // it's wrong because of me
tree[x + 1].apply(l, y, tree[x].add);
tree[z].apply(y + 1, r, tree[x].add);
tree[x].add = 1;
}
}
inline void pull(int x, int z) {
tree[x] = unite(tree[x + 1], tree[z]);
}
int n;
vector<node> tree;
template <typename M>
void build(int x, int l, int r, const vector<M> &v) {
if (l == r) {
tree[x].apply(l, r, v[l]);
return;
}
int y = (l + r) >> 1;
int z = x + ((y - l + 1) << 1);
build(x + 1, l, y, v);
build(z, y + 1, r, v);
pull(x, z);
}
node query(int x, int l, int r, int LL, int rr) {
if (LL <= l && r <= rr) {
return tree[x];
}
int y = (l + r) >> 1;
int z = x + ((y - l + 1) << 1);
push(x, l, r);
node res{};
if (rr <= y) {
res = query(x + 1, l, y, LL, rr);
}
else{
if (LL > y) {
res = query(z, y + 1, r, LL, rr);
}
else{
res = unite(query(x + 1, l, y, LL, rr), query(z, y + 1, r, LL, rr));
}
}
pull(x, z);
return res;
}
template <typename... M>
void update(int x, int l, int r, int LL, int rr, const M&... v) {
if (LL <= l && r <= rr) {
tree[x].apply(l, r, v...);
return;
}
int y = (l + r) >> 1;
int z = x + ((y - l + 1) << 1);
push(x, l, r);
if (LL <= y) {
update(x + 1, l, y, LL, rr, v...);
}
if (rr > y) {
update(z, y + 1, r, LL, rr, v...);
}
pull(x, z);
}
template <typename M>
segtree(const vector<M> &v) {
n = v.size();
assert(n > 0);
tree.resize(2 * n - 1);
build(0, 0, n - 1, v);
}
node query(int LL, int rr) {
if(LL > rr)
return {};
assert(0 <= LL && LL <= rr && rr <= n - 1);
return query(0, 0, n - 1, LL, rr);
}
template <typename... M>
void update(int LL, int rr, const M&... v) {
assert(0 <= LL && LL <= rr && rr <= n - 1);
update(0, 0, n - 1, LL, rr, v...);
}
};
class segtree2 {
public:
struct node {
int mn = 1e9;
int add = 1e9;
void apply(int l, int r, int x) {
mn = min(mn,x);
add = min(add,x);
}
};
node unite(const node &a, const node &b) const {
node res;
res.mn=min(a.mn,b.mn);
return res;
}
inline void push(int x, int l, int r) {
int y = (l + r) >> 1;
int z = x + ((y - l + 1) << 1);
if (tree[x].add != 1e9) { // it's wrong because of me
tree[x + 1].apply(l, y, tree[x].add);
tree[z].apply(y + 1, r, tree[x].add);
tree[x].add = 1e9;
}
}
inline void pull(int x, int z) {
tree[x] = unite(tree[x + 1], tree[z]);
}
int n;
vector<node> tree;
template <typename M>
void build(int x, int l, int r, const vector<M> &v) {
if (l == r) {
tree[x].apply(l, r, v[l]);
return;
}
int y = (l + r) >> 1;
int z = x + ((y - l + 1) << 1);
build(x + 1, l, y, v);
build(z, y + 1, r, v);
pull(x, z);
}
node query(int x, int l, int r, int LL, int rr) {
if (LL <= l && r <= rr) {
return tree[x];
}
int y = (l + r) >> 1;
int z = x + ((y - l + 1) << 1);
push(x, l, r);
node res{};
if (rr <= y) {
res = query(x + 1, l, y, LL, rr);
}
else{
if (LL > y) {
res = query(z, y + 1, r, LL, rr);
}
else{
res = unite(query(x + 1, l, y, LL, rr), query(z, y + 1, r, LL, rr));
}
}
pull(x, z);
return res;
}
template <typename... M>
void update(int x, int l, int r, int LL, int rr, int val) {
// if(tree[x].mn<=val){
// }
if (LL <= l && r <= rr) {
tree[x].apply(l, r, val);
return;
}
int y = (l + r) >> 1;
int z = x + ((y - l + 1) << 1);
push(x, l, r);
if (LL <= y) {
update(x + 1, l, y, LL, rr, val);
}
if (rr > y) {
update(z, y + 1, r, LL, rr, val);
}
pull(x, z);
}
template <typename M>
segtree2(const vector<M> &v) {
n = v.size();
assert(n > 0);
tree.resize(2 * n - 1);
build(0, 0, n - 1, v);
}
node query(int LL, int rr) {
if(LL > rr)
return {};
assert(0 <= LL && LL <= rr && rr <= n - 1);
return query(0, 0, n - 1, LL, rr);
}
template <typename... M>
void update(int LL, int rr, int x) {
assert(0 <= LL && LL <= rr && rr <= n - 1);
update(0, 0, n - 1, LL, rr, x);
}
};
int spf[maxN],lst[maxN];
vector<int> prms;
void pre(){
for(int i = 2;i<maxN;++i){
if(spf[i]==0){
spf[i] = i;
prms.push_back(i);
}
for(auto&p:prms){
if(p*i>=maxN||p>spf[i]) break;
spf[p*i]=p;
}
}
for(int i=1;i<maxN;++i){
if(spf[i]==i) lst[i] = i;
else lst[i] = lst[i-1];
}
}
void solve(){
int n;cin>>n;
int q;cin>>q;
vector<int> a(n+1), b(n+1);
for(int i=1;i<=n;++i){
cin>>a[i];
b[i]=spf[a[i]];
}
segtree st1(a);
segtree2 st2(b);
while(q--){
ll type, l,r;cin>>type>>l>>r;
if(type==1){
mint mul = st1.query(l,r).mul;
mint mn = st2.query(l,r).mn;
mul/=mn;
// cout << mul << " " << mn << '\n';
cout<<mul<<'\n';
}
else{
int x;cin>>x;
st1.update(l,r,x);
st2.update(l,r,spf[x]);
}
}
}
int32_t main(){ios_base::sync_with_stdio(0); cin.tie(0);
pre();
int tt=1;cin>>tt;while(tt--)
solve();return 0;}
I2luY2x1ZGU8Yml0cy9zdGRjKysuaD4KdXNpbmcgbmFtZXNwYWNlIHN0ZDt1c2luZyBsbD1sb25nIGxvbmc7Y29uc3QgaW50IG1heE49MWU3KzU7CnVzaW5nIGxsID0gbG9uZyBsb25nOwpjb25zdCBpbnQgTU9EID0gMWU5ICsgNzsKIAp0ZW1wbGF0ZTxsbCBNPgpzdHJ1Y3QgbW9kaW50IHsKIAogICAgc3RhdGljIGxsIF9wb3cobGwgbiwgbGwgaykgewogICAgICAgIGxsIHIgPSAxOwogICAgICAgIGZvciAoOyBrID4gMDsgayA+Pj0gMSwgbiA9IChuKm4pJU0pCiAgICAgICAgICAgIGlmIChrJjEpIHIgPSAocipuKSVNOwogICAgICAgIHJldHVybiByOwogICAgfQogCiAgICBsbCB2OyBtb2RpbnQobGwgbiA9IDApIDogdihuJU0pIHsgdiArPSAoTSYoMC0odjwwKSkpOyB9CiAgICAKICAgIGZyaWVuZCBzdHJpbmcgdG9fc3RyaW5nKGNvbnN0IG1vZGludCBuKSB7IHJldHVybiB0b19zdHJpbmcobi52KTsgfQogICAgZnJpZW5kIGlzdHJlYW0mIG9wZXJhdG9yPj4oaXN0cmVhbSYgaSwgbW9kaW50JiBuKSB7IHJldHVybiBpID4+IG4udjsgfQogICAgZnJpZW5kIG9zdHJlYW0mIG9wZXJhdG9yPDwob3N0cmVhbSYgbywgY29uc3QgbW9kaW50IG4pIHsgcmV0dXJuIG8gPDwgbi52OyB9CiAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBUPiBleHBsaWNpdCBvcGVyYXRvciBUKCkgeyByZXR1cm4gVCh2KTsgfQogCiAgICBmcmllbmQgYm9vbCBvcGVyYXRvcj09KGNvbnN0IG1vZGludCBuLCBjb25zdCBtb2RpbnQgbSkgeyByZXR1cm4gbi52ID09IG0udjsgfQogICAgZnJpZW5kIGJvb2wgb3BlcmF0b3IhPShjb25zdCBtb2RpbnQgbiwgY29uc3QgbW9kaW50IG0pIHsgcmV0dXJuIG4udiAhPSBtLnY7IH0KICAgIGZyaWVuZCBib29sIG9wZXJhdG9yPChjb25zdCBtb2RpbnQgbiwgY29uc3QgbW9kaW50IG0pIHsgcmV0dXJuIG4udiA8IG0udjsgfQogICAgZnJpZW5kIGJvb2wgb3BlcmF0b3I8PShjb25zdCBtb2RpbnQgbiwgY29uc3QgbW9kaW50IG0pIHsgcmV0dXJuIG4udiA8PSBtLnY7IH0KICAgIGZyaWVuZCBib29sIG9wZXJhdG9yPihjb25zdCBtb2RpbnQgbiwgY29uc3QgbW9kaW50IG0pIHsgcmV0dXJuIG4udiA+IG0udjsgfQogICAgZnJpZW5kIGJvb2wgb3BlcmF0b3I+PShjb25zdCBtb2RpbnQgbiwgY29uc3QgbW9kaW50IG0pIHsgcmV0dXJuIG4udiA+PSBtLnY7IH0KIAogICAgbW9kaW50JiBvcGVyYXRvcis9KGNvbnN0IG1vZGludCBuKSB7IHYgKz0gbi52OyB2IC09IChNJigwLSh2Pj1NKSkpOyByZXR1cm4gKnRoaXM7IH0KICAgIG1vZGludCYgb3BlcmF0b3ItPShjb25zdCBtb2RpbnQgbikgeyB2IC09IG4udjsgdiArPSAoTSYoMC0odjwwKSkpOyByZXR1cm4gKnRoaXM7IH0KICAgIG1vZGludCYgb3BlcmF0b3IqPShjb25zdCBtb2RpbnQgbikgeyB2ID0gKHYqbi52KSVNOyByZXR1cm4gKnRoaXM7IH0KICAgIG1vZGludCYgb3BlcmF0b3IvPShjb25zdCBtb2RpbnQgbikgeyB2ID0gKHYqX3BvdyhuLnYsIE0tMikpJU07IHJldHVybiAqdGhpczsgfQogICAgZnJpZW5kIG1vZGludCBvcGVyYXRvcisoY29uc3QgbW9kaW50IG4sIGNvbnN0IG1vZGludCBtKSB7IHJldHVybiBtb2RpbnQobikgKz0gbTsgfQogICAgZnJpZW5kIG1vZGludCBvcGVyYXRvci0oY29uc3QgbW9kaW50IG4sIGNvbnN0IG1vZGludCBtKSB7IHJldHVybiBtb2RpbnQobikgLT0gbTsgfQogICAgZnJpZW5kIG1vZGludCBvcGVyYXRvciooY29uc3QgbW9kaW50IG4sIGNvbnN0IG1vZGludCBtKSB7IHJldHVybiBtb2RpbnQobikgKj0gbTsgfQogICAgZnJpZW5kIG1vZGludCBvcGVyYXRvci8oY29uc3QgbW9kaW50IG4sIGNvbnN0IG1vZGludCBtKSB7IHJldHVybiBtb2RpbnQobikgLz0gbTsgfQogICAgbW9kaW50JiBvcGVyYXRvcisrKCkgeyByZXR1cm4gKnRoaXMgKz0gMTsgfQogICAgbW9kaW50JiBvcGVyYXRvci0tKCkgeyByZXR1cm4gKnRoaXMgLT0gMTsgfQogICAgbW9kaW50IG9wZXJhdG9yKysoaW50KSB7IG1vZGludCB0ID0gKnRoaXM7IHJldHVybiAqdGhpcyArPSAxLCB0OyB9CiAgICBtb2RpbnQgb3BlcmF0b3ItLShpbnQpIHsgbW9kaW50IHQgPSAqdGhpczsgcmV0dXJuICp0aGlzIC09IDEsIHQ7IH0KICAgIG1vZGludCBvcGVyYXRvcisoKSB7IHJldHVybiAqdGhpczsgfQogICAgbW9kaW50IG9wZXJhdG9yLSgpIHsgcmV0dXJuIG1vZGludCgwKSAtPSAqdGhpczsgfQogCiAgICBtb2RpbnQgcG93KGNvbnN0IGxsIGspIGNvbnN0IHsKICAgICAgICByZXR1cm4gayA8IDAgPyBfcG93KHYsIE0tMS0oLWslKE0tMSkpKSA6IF9wb3codiwgayk7CiAgICB9CiAgICBtb2RpbnQgaW52KCkgY29uc3QgeyByZXR1cm4gX3Bvdyh2LCBNLTIpOyB9Cn07CiAKdXNpbmcgbWludCA9IG1vZGludDxpbnQoTU9EKT47Ci8vIGNoZWNrIGFkZApjbGFzcyBzZWd0cmVlIHsKICAgIHB1YmxpYzoKICAgIHN0cnVjdCBub2RlIHsKICAgICAgICBtaW50IG11bCA9IDE7CiAgICAgICAgbWludCBhZGQgPSAxOwoKICAgICAgICB2b2lkIGFwcGx5KGludCBsLCBpbnQgciwgbWludCB4KSB7CiAgICAgICAgICAgIG11bCA9IG11bCooeC5wb3coci1sKzEpKTsKICAgICAgICAgICAgYWRkID0gYWRkKng7CiAgICAgICAgfQogICAgfTsKIAogICAgbm9kZSB1bml0ZShjb25zdCBub2RlICZhLCBjb25zdCBub2RlICZiKSBjb25zdCB7CiAgICAgICAgbm9kZSByZXM7CiAgICAgICAgcmVzLm11bCA9IGEubXVsKmIubXVsOwogICAgICAgIHJldHVybiByZXM7CiAgICB9CiAKICAgIGlubGluZSB2b2lkIHB1c2goaW50IHgsIGludCBsLCBpbnQgcikgewogICAgICAgIGludCB5ID0gKGwgKyByKSA+PiAxOwogICAgICAgIGludCB6ID0geCArICgoeSAtIGwgKyAxKSA8PCAxKTsKICAgICAgICBpZiAodHJlZVt4XS5hZGQgIT0gMSkgeyAvLyBpdCdzIHdyb25nIGJlY2F1c2Ugb2YgbWUKICAgICAgICAgICAgdHJlZVt4ICsgMV0uYXBwbHkobCwgeSwgdHJlZVt4XS5hZGQpOwogICAgICAgICAgICB0cmVlW3pdLmFwcGx5KHkgKyAxLCByLCB0cmVlW3hdLmFkZCk7CiAgICAgICAgICAgIHRyZWVbeF0uYWRkID0gMTsKICAgICAgICB9CiAgICB9CiAKICAgIGlubGluZSB2b2lkIHB1bGwoaW50IHgsIGludCB6KSB7CiAgICAgICAgdHJlZVt4XSA9IHVuaXRlKHRyZWVbeCArIDFdLCB0cmVlW3pdKTsKICAgIH0KIAogICAgaW50IG47CiAgICB2ZWN0b3I8bm9kZT4gdHJlZTsKIAogICAgdGVtcGxhdGUgPHR5cGVuYW1lIE0+CiAgICB2b2lkIGJ1aWxkKGludCB4LCBpbnQgbCwgaW50IHIsIGNvbnN0IHZlY3RvcjxNPiAmdikgewogICAgICAgIGlmIChsID09IHIpIHsKICAgICAgICAgICAgdHJlZVt4XS5hcHBseShsLCByLCB2W2xdKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBpbnQgeSA9IChsICsgcikgPj4gMTsKICAgICAgICBpbnQgeiA9IHggKyAoKHkgLSBsICsgMSkgPDwgMSk7CiAgICAgICAgYnVpbGQoeCArIDEsIGwsIHksIHYpOwogICAgICAgIGJ1aWxkKHosIHkgKyAxLCByLCB2KTsKICAgICAgICBwdWxsKHgsIHopOwogICAgfQogCiAgICBub2RlIHF1ZXJ5KGludCB4LCBpbnQgbCwgaW50IHIsIGludCBMTCwgaW50IHJyKSB7CiAgICAgICAgaWYgKExMIDw9IGwgJiYgciA8PSBycikgewogICAgICAgICAgICByZXR1cm4gdHJlZVt4XTsKICAgICAgICB9CiAgICAgICAgaW50IHkgPSAobCArIHIpID4+IDE7CiAgICAgICAgaW50IHogPSB4ICsgKCh5IC0gbCArIDEpIDw8IDEpOwogICAgICAgIHB1c2goeCwgbCwgcik7CiAgICAgICAgbm9kZSByZXN7fTsKICAgICAgICBpZiAocnIgPD0geSkgewogICAgICAgICAgICByZXMgPSBxdWVyeSh4ICsgMSwgbCwgeSwgTEwsIHJyKTsKICAgICAgICB9IAogICAgICAgIGVsc2V7CiAgICAgICAgICAgIGlmIChMTCA+IHkpIHsKICAgICAgICAgICAgICAgIHJlcyA9IHF1ZXJ5KHosIHkgKyAxLCByLCBMTCwgcnIpOwogICAgICAgICAgICB9IAogICAgICAgICAgICBlbHNlewogICAgICAgICAgICAgICAgcmVzID0gdW5pdGUocXVlcnkoeCArIDEsIGwsIHksIExMLCByciksIHF1ZXJ5KHosIHkgKyAxLCByLCBMTCwgcnIpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBwdWxsKHgsIHopOwogICAgICAgIHJldHVybiByZXM7CiAgICB9CiAKICAgIHRlbXBsYXRlIDx0eXBlbmFtZS4uLiBNPgogICAgdm9pZCB1cGRhdGUoaW50IHgsIGludCBsLCBpbnQgciwgaW50IExMLCBpbnQgcnIsIGNvbnN0IE0mLi4uIHYpIHsKICAgICAgICBpZiAoTEwgPD0gbCAmJiByIDw9IHJyKSB7CiAgICAgICAgICAgIHRyZWVbeF0uYXBwbHkobCwgciwgdi4uLik7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgaW50IHkgPSAobCArIHIpID4+IDE7CiAgICAgICAgaW50IHogPSB4ICsgKCh5IC0gbCArIDEpIDw8IDEpOwogICAgICAgIHB1c2goeCwgbCwgcik7CiAgICAgICAgaWYgKExMIDw9IHkpIHsKICAgICAgICAgICAgdXBkYXRlKHggKyAxLCBsLCB5LCBMTCwgcnIsIHYuLi4pOwogICAgICAgIH0KICAgICAgICBpZiAocnIgPiB5KSB7CiAgICAgICAgICAgIHVwZGF0ZSh6LCB5ICsgMSwgciwgTEwsIHJyLCB2Li4uKTsKICAgICAgICB9CiAgICAgICAgcHVsbCh4LCB6KTsKICAgIH0KICAgIAogICAgdGVtcGxhdGUgPHR5cGVuYW1lIE0+CiAgICBzZWd0cmVlKGNvbnN0IHZlY3RvcjxNPiAmdikgewogICAgICAgIG4gPSB2LnNpemUoKTsKICAgICAgICBhc3NlcnQobiA+IDApOwogICAgICAgIHRyZWUucmVzaXplKDIgKiBuIC0gMSk7CiAgICAgICAgYnVpbGQoMCwgMCwgbiAtIDEsIHYpOwogICAgfQogCiAgICBub2RlIHF1ZXJ5KGludCBMTCwgaW50IHJyKSB7CiAgICAgICAgaWYoTEwgPiBycikKICAgICAgICAgICAgcmV0dXJuIHt9OwogICAgICAgIGFzc2VydCgwIDw9IExMICYmIExMIDw9IHJyICYmIHJyIDw9IG4gLSAxKTsKICAgICAgICByZXR1cm4gcXVlcnkoMCwgMCwgbiAtIDEsIExMLCBycik7CiAgICB9CiAKICAgIHRlbXBsYXRlIDx0eXBlbmFtZS4uLiBNPgogICAgdm9pZCB1cGRhdGUoaW50IExMLCBpbnQgcnIsIGNvbnN0IE0mLi4uIHYpIHsKICAgICAgICBhc3NlcnQoMCA8PSBMTCAmJiBMTCA8PSByciAmJiByciA8PSBuIC0gMSk7CiAgICAgICAgdXBkYXRlKDAsIDAsIG4gLSAxLCBMTCwgcnIsIHYuLi4pOwogICAgfQp9OwpjbGFzcyBzZWd0cmVlMiB7CiAgICBwdWJsaWM6CiAgICBzdHJ1Y3Qgbm9kZSB7CiAgICAgICAgaW50IG1uID0gMWU5OwogICAgICAgIGludCBhZGQgPSAxZTk7CiAgICAgICAgdm9pZCBhcHBseShpbnQgbCwgaW50IHIsIGludCB4KSB7CiAgICAgICAgICAgIG1uID0gbWluKG1uLHgpOwogICAgICAgICAgICBhZGQgPSBtaW4oYWRkLHgpOwogICAgICAgIH0KICAgIH07CiAKICAgIG5vZGUgdW5pdGUoY29uc3Qgbm9kZSAmYSwgY29uc3Qgbm9kZSAmYikgY29uc3QgewogICAgICAgIG5vZGUgcmVzOwogICAgICAgIHJlcy5tbj1taW4oYS5tbixiLm1uKTsKICAgICAgICByZXR1cm4gcmVzOwogICAgfQogCiAgICBpbmxpbmUgdm9pZCBwdXNoKGludCB4LCBpbnQgbCwgaW50IHIpIHsKICAgICAgICBpbnQgeSA9IChsICsgcikgPj4gMTsKICAgICAgICBpbnQgeiA9IHggKyAoKHkgLSBsICsgMSkgPDwgMSk7CiAgICAgICAgaWYgKHRyZWVbeF0uYWRkICE9IDFlOSkgeyAvLyBpdCdzIHdyb25nIGJlY2F1c2Ugb2YgbWUKICAgICAgICAgICAgdHJlZVt4ICsgMV0uYXBwbHkobCwgeSwgdHJlZVt4XS5hZGQpOwogICAgICAgICAgICB0cmVlW3pdLmFwcGx5KHkgKyAxLCByLCB0cmVlW3hdLmFkZCk7CiAgICAgICAgICAgIHRyZWVbeF0uYWRkID0gMWU5OwogICAgICAgIH0KICAgIH0KIAogICAgaW5saW5lIHZvaWQgcHVsbChpbnQgeCwgaW50IHopIHsKICAgICAgICB0cmVlW3hdID0gdW5pdGUodHJlZVt4ICsgMV0sIHRyZWVbel0pOwogICAgfQogCiAgICBpbnQgbjsKICAgIHZlY3Rvcjxub2RlPiB0cmVlOwogCiAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUgTT4KICAgIHZvaWQgYnVpbGQoaW50IHgsIGludCBsLCBpbnQgciwgY29uc3QgdmVjdG9yPE0+ICZ2KSB7CiAgICAgICAgaWYgKGwgPT0gcikgewogICAgICAgICAgICB0cmVlW3hdLmFwcGx5KGwsIHIsIHZbbF0pOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIGludCB5ID0gKGwgKyByKSA+PiAxOwogICAgICAgIGludCB6ID0geCArICgoeSAtIGwgKyAxKSA8PCAxKTsKICAgICAgICBidWlsZCh4ICsgMSwgbCwgeSwgdik7CiAgICAgICAgYnVpbGQoeiwgeSArIDEsIHIsIHYpOwogICAgICAgIHB1bGwoeCwgeik7CiAgICB9CiAKICAgIG5vZGUgcXVlcnkoaW50IHgsIGludCBsLCBpbnQgciwgaW50IExMLCBpbnQgcnIpIHsKICAgICAgICBpZiAoTEwgPD0gbCAmJiByIDw9IHJyKSB7CiAgICAgICAgICAgIHJldHVybiB0cmVlW3hdOwogICAgICAgIH0KICAgICAgICBpbnQgeSA9IChsICsgcikgPj4gMTsKICAgICAgICBpbnQgeiA9IHggKyAoKHkgLSBsICsgMSkgPDwgMSk7CiAgICAgICAgcHVzaCh4LCBsLCByKTsKICAgICAgICBub2RlIHJlc3t9OwogICAgICAgIGlmIChyciA8PSB5KSB7CiAgICAgICAgICAgIHJlcyA9IHF1ZXJ5KHggKyAxLCBsLCB5LCBMTCwgcnIpOwogICAgICAgIH0gCiAgICAgICAgZWxzZXsKICAgICAgICAgICAgaWYgKExMID4geSkgewogICAgICAgICAgICAgICAgcmVzID0gcXVlcnkoeiwgeSArIDEsIHIsIExMLCBycik7CiAgICAgICAgICAgIH0gCiAgICAgICAgICAgIGVsc2V7CiAgICAgICAgICAgICAgICByZXMgPSB1bml0ZShxdWVyeSh4ICsgMSwgbCwgeSwgTEwsIHJyKSwgcXVlcnkoeiwgeSArIDEsIHIsIExMLCBycikpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHB1bGwoeCwgeik7CiAgICAgICAgcmV0dXJuIHJlczsKICAgIH0KIAogICAgdGVtcGxhdGUgPHR5cGVuYW1lLi4uIE0+CiAgICB2b2lkIHVwZGF0ZShpbnQgeCwgaW50IGwsIGludCByLCBpbnQgTEwsIGludCByciwgaW50IHZhbCkgewogICAgICAgIC8vIGlmKHRyZWVbeF0ubW48PXZhbCl7CiAgICAgICAgLy8gfQogICAgICAgIGlmIChMTCA8PSBsICYmIHIgPD0gcnIpIHsKICAgICAgICAgICAgdHJlZVt4XS5hcHBseShsLCByLCB2YWwpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIGludCB5ID0gKGwgKyByKSA+PiAxOwogICAgICAgIGludCB6ID0geCArICgoeSAtIGwgKyAxKSA8PCAxKTsKICAgICAgICBwdXNoKHgsIGwsIHIpOwogICAgICAgIGlmIChMTCA8PSB5KSB7CiAgICAgICAgICAgIHVwZGF0ZSh4ICsgMSwgbCwgeSwgTEwsIHJyLCB2YWwpOwogICAgICAgIH0KICAgICAgICBpZiAocnIgPiB5KSB7CiAgICAgICAgICAgIHVwZGF0ZSh6LCB5ICsgMSwgciwgTEwsIHJyLCB2YWwpOwogICAgICAgIH0KICAgICAgICBwdWxsKHgsIHopOwogICAgfQogICAgCiAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUgTT4KICAgIHNlZ3RyZWUyKGNvbnN0IHZlY3RvcjxNPiAmdikgewogICAgICAgIG4gPSB2LnNpemUoKTsKICAgICAgICBhc3NlcnQobiA+IDApOwogICAgICAgIHRyZWUucmVzaXplKDIgKiBuIC0gMSk7CiAgICAgICAgYnVpbGQoMCwgMCwgbiAtIDEsIHYpOwogICAgfQogCiAgICBub2RlIHF1ZXJ5KGludCBMTCwgaW50IHJyKSB7CiAgICAgICAgaWYoTEwgPiBycikKICAgICAgICAgICAgcmV0dXJuIHt9OwogICAgICAgIGFzc2VydCgwIDw9IExMICYmIExMIDw9IHJyICYmIHJyIDw9IG4gLSAxKTsKICAgICAgICByZXR1cm4gcXVlcnkoMCwgMCwgbiAtIDEsIExMLCBycik7CiAgICB9CiAKICAgIHRlbXBsYXRlIDx0eXBlbmFtZS4uLiBNPgogICAgdm9pZCB1cGRhdGUoaW50IExMLCBpbnQgcnIsIGludCB4KSB7CiAgICAgICAgYXNzZXJ0KDAgPD0gTEwgJiYgTEwgPD0gcnIgJiYgcnIgPD0gbiAtIDEpOwogICAgICAgIHVwZGF0ZSgwLCAwLCBuIC0gMSwgTEwsIHJyLCB4KTsKICAgIH0KfTsKaW50IHNwZlttYXhOXSxsc3RbbWF4Tl07CnZlY3RvcjxpbnQ+IHBybXM7CnZvaWQgcHJlKCl7CiAgICBmb3IoaW50IGkgPSAyO2k8bWF4TjsrK2kpewogICAgICAgIGlmKHNwZltpXT09MCl7CiAgICAgICAgICAgIHNwZltpXSA9IGk7CiAgICAgICAgICAgIHBybXMucHVzaF9iYWNrKGkpOwogICAgICAgIH0KICAgICAgICBmb3IoYXV0byZwOnBybXMpewogICAgICAgICAgICBpZihwKmk+PW1heE58fHA+c3BmW2ldKSBicmVhazsKICAgICAgICAgICAgc3BmW3AqaV09cDsKICAgICAgICB9CiAgICB9CiAgICBmb3IoaW50IGk9MTtpPG1heE47KytpKXsKICAgICAgICBpZihzcGZbaV09PWkpIGxzdFtpXSA9IGk7CiAgICAgICAgZWxzZSBsc3RbaV0gPSBsc3RbaS0xXTsKICAgIH0KfQp2b2lkIHNvbHZlKCl7CiAgICBpbnQgbjtjaW4+Pm47CiAgICBpbnQgcTtjaW4+PnE7CiAgICB2ZWN0b3I8aW50PiBhKG4rMSksIGIobisxKTsKICAgIGZvcihpbnQgaT0xO2k8PW47KytpKXsKICAgICAgICBjaW4+PmFbaV07CiAgICAgICAgYltpXT1zcGZbYVtpXV07CiAgICB9CiAgICBzZWd0cmVlIHN0MShhKTsKICAgIHNlZ3RyZWUyIHN0MihiKTsKCiAgICB3aGlsZShxLS0pewogICAgICAgIGxsIHR5cGUsIGwscjtjaW4+PnR5cGU+Pmw+PnI7CiAgICAgICAgaWYodHlwZT09MSl7CiAgICAgICAgICAgIG1pbnQgbXVsID0gc3QxLnF1ZXJ5KGwscikubXVsOwogICAgICAgICAgICBtaW50IG1uID0gc3QyLnF1ZXJ5KGwscikubW47CiAgICAgICAgICAgIG11bC89bW47CiAgICAgICAgICAgIC8vIGNvdXQgPDwgbXVsIDw8ICIgIiA8PCBtbiA8PCAnXG4nOwogICAgICAgICAgICBjb3V0PDxtdWw8PCdcbic7CiAgICAgICAgfQogICAgICAgIGVsc2V7CiAgICAgICAgICAgIGludCB4O2Npbj4+eDsKICAgICAgICAgICAgc3QxLnVwZGF0ZShsLHIseCk7CiAgICAgICAgICAgIHN0Mi51cGRhdGUobCxyLHNwZlt4XSk7CiAgICAgICAgfQogICAgfQp9CmludDMyX3QgbWFpbigpe2lvc19iYXNlOjpzeW5jX3dpdGhfc3RkaW8oMCk7IGNpbi50aWUoMCk7CnByZSgpOwppbnQgdHQ9MTtjaW4+PnR0O3doaWxlKHR0LS0pCnNvbHZlKCk7cmV0dXJuIDA7fQ==