#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
const int N = 2e5, oo = 2e18, MOD = 1e9+7;
int modpow(int b, int p) {
int res = 1;
while (p) {
if (p & 1) res = (b * res) % MOD;
b = (b * b) % MOD;
p >>= 1;
}
return res;
}
int inv(int a) {
return modpow(a, MOD - 2);
}
vector<int> spf;
void sieve(int n) { // O (n . log(n))
spf.assign(n + 1,0 );
vector<bool> is_prime(n+1, true);
is_prime[0] = is_prime[1] = false;
for (int i = 2; i <= n; i++) {
if (is_prime[i]) {
spf[i] = i;
for (int j = 2 * i; j <= n; j+=i) {
is_prime[j] = false;
if (spf[j] == 0) {
spf[j] = i;
}
}
}
}
}
struct Node2 {
int sum, lazy = 0;
bool isLazy = false;
Node2(){
sum=oo;
}
Node2(int x) : sum(x) {}
void updateNode(int x, int lx, int rx) {
sum=min(sum,x);
lazy=x;
isLazy=true;
}
};
struct SagaraWithLazy2 {
#define leftChild (node * 2 + 1)
#define rightChild (node * 2 + 2)
#define mid ((lx + rx >> 1))
int treeSize;
vector<Node2> segData;
void build(int node, int lx, int rx, vector<int>& arr) {
if (rx - lx == 1) {
if (lx < (int)arr.size())
segData[node] = Node2(arr[lx]);
return;
}
build(leftChild, lx, mid, arr);
build(rightChild, mid, rx, arr);
segData[node] = merge(segData[leftChild], segData[rightChild]);
}
Node2 merge(Node2& L, Node2& R) {
Node2 res = Node2();
res.sum=min(L.sum,R.sum);
return res;
}
void propagate(int node, int lx, int rx) {
if (rx - lx == 1 or !segData[node].isLazy) return;
segData[leftChild].updateNode(segData[node].lazy, lx, mid);
segData[rightChild].updateNode(segData[node].lazy, mid, rx);
segData[node].isLazy = segData[node].lazy = 0;
}
void update(int l, int r, int x, int node, int lx, int rx) {
propagate(node, lx, rx);
if (l >= rx or lx >= r) return;
if (l <= lx and rx <= r) {
segData[node].updateNode(x, lx, rx);
return;
}
update(l, r, x, leftChild, lx, mid);
update(l, r, x, rightChild, mid, rx);
segData[node] = merge(segData[leftChild], segData[rightChild]);
}
Node2 query(int l, int r, int node, int lx, int rx) {
propagate(node, lx, rx);
if (l >= rx or lx >= r) return Node2();
if (l <= lx and rx <= r) {
return segData[node];
}
Node2 left = query(l, r, leftChild, lx, mid);
Node2 right = query(l, r, rightChild, mid, rx);
return merge(left, right);
}
public:
SagaraWithLazy2(int n, vector<int>& arr) {
treeSize = 1;
while (treeSize < n) treeSize <<= 1;
segData = vector<Node2>(treeSize << 1);
build(0, 0, treeSize, arr);
}
void update(int l, int r, int x) {
update(l, r, x, 0, 0, treeSize);
}
int query(int l, int r) {
Node2 a = query(l, r, 0, 0, treeSize);
return (a.sum);
}
#undef LeftChild
#undef RightChild
#undef mid
};
struct Node {
int prod;
int sum, lazy = 0;
bool isLazy = false;
Node() :prod(1) { }
Node(int x) : prod(x) {}
void updateNode(int x, int lx, int rx) {
prod *= modpow(x,rx-lx);
prod %= MOD;
if(lazy==0)lazy=1;
lazy *= x;
lazy%=MOD;
isLazy = true;
}
};
struct SagaraWithLazy {
#define leftChild (node * 2 + 1)
#define rightChild (node * 2 + 2)
#define mid ((lx + rx >> 1))
int treeSize;
vector<Node> segData;
void build(int node, int lx, int rx, vector<int>& arr) {
if (rx - lx == 1) {
if (lx < (int)arr.size())
segData[node] = Node(arr[lx]);
return;
}
build(leftChild, lx, mid, arr);
build(rightChild, mid, rx, arr);
segData[node] = merge(segData[leftChild], segData[rightChild]);
}
Node merge(Node& L, Node& R) {
Node res = Node();
res.prod = (L.prod * R.prod) % MOD;
return res;
}
void propagate(int node, int lx, int rx) {
if (rx - lx == 1 or !segData[node].isLazy) return;
segData[leftChild].updateNode(segData[node].lazy, lx, mid);
segData[rightChild].updateNode(segData[node].lazy, mid, rx);
segData[node].isLazy = segData[node].lazy = 0;
}
void update(int l, int r, int x, int node, int lx, int rx) {
propagate(node, lx, rx);
if (l >= rx or lx >= r) return;
if (l <= lx and rx <= r) {
segData[node].updateNode(x, lx, rx);
return;
}
update(l, r, x, leftChild, lx, mid);
update(l, r, x, rightChild, mid, rx);
segData[node] = merge(segData[leftChild], segData[rightChild]);
}
Node query(int l, int r, int node, int lx, int rx) {
propagate(node, lx, rx);
if (l >= rx or lx >= r) return Node();
if (l <= lx and rx <= r) {
return segData[node];
}
Node left = query(l, r, leftChild, lx, mid);
Node right = query(l, r, rightChild, mid, rx);
return merge(left, right);
}
public:
SagaraWithLazy(int n, vector<int>& arr) {
treeSize = 1;
while (treeSize < n) treeSize <<= 1;
segData = vector<Node>(treeSize << 1);
build(0, 0, treeSize, arr);
}
void update(int l, int r, int x) {
update(l, r, x, 0, 0, treeSize);
}
int query(int l, int r) {
Node a = query(l, r, 0, 0, treeSize);
return (a.prod ) % MOD;
}
#undef LeftChild
#undef RightChild
#undef mid
};
void solve() {
int n, q; cin >> n >> q;
vector<int> a(n),b(n);
for (int i = 0; i < n; i++) cin >> a[i],b[i]=spf[a[i]];
SagaraWithLazy st(n, a);
SagaraWithLazy2 st2(n,b);
while (q--) {
int t; cin >> t;
if (t == 1) {
int l, r; cin >> l >> r;
l--, r--;
int prod = st.query(l, r + 1);
int sp = st2.query(l, r + 1);
cout << (prod * inv(sp)) % MOD << endl;
} else {
int l, r, x; cin >> l >> r >> x;
st.update(l-1, r, x);
st2.update(l-1, r, spf[x]);
}
}
}
signed main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
// #ifndef ONLINE_JUDGE
// freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
// #endif
int t; t = 1;
sieve(1e7);
cin >> t;
while (t--) solve();
return 0;
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CgojZGVmaW5lIGVuZGwgICAgICdcbicKI2RlZmluZSBpbnQgICAgICBsb25nIGxvbmcKCmNvbnN0IGludCBOID0gMmU1LCBvbyA9IDJlMTgsIE1PRCA9IDFlOSs3OwoKCmludCBtb2Rwb3coaW50IGIsIGludCBwKSB7CiAgICBpbnQgcmVzID0gMTsKICAgIHdoaWxlIChwKSB7CiAgICAgICAgaWYgKHAgJiAxKSByZXMgPSAoYiAqIHJlcykgJSBNT0Q7CiAgICAgICAgYiA9IChiICogYikgICUgTU9EOwogICAgICAgIHAgPj49IDE7CiAgICB9CiAgICByZXR1cm4gcmVzOwp9CgppbnQgaW52KGludCBhKSB7CiAgICByZXR1cm4gbW9kcG93KGEsIE1PRCAtIDIpOwp9Cgp2ZWN0b3I8aW50PiBzcGY7CnZvaWQgc2lldmUoaW50IG4pIHsgLy8gTyAobiAuIGxvZyhuKSkKICAgIHNwZi5hc3NpZ24obiArIDEsMCApOwogICB2ZWN0b3I8Ym9vbD4gaXNfcHJpbWUobisxLCB0cnVlKTsKICAgaXNfcHJpbWVbMF0gPSBpc19wcmltZVsxXSA9IGZhbHNlOwogICBmb3IgKGludCBpID0gMjsgaSA8PSBuOyBpKyspIHsKICAgICAgaWYgKGlzX3ByaW1lW2ldKSB7CiAgICAgICAgIHNwZltpXSA9IGk7CiAgICAgICAgIGZvciAoaW50IGogPSAyICogaTsgaiA8PSBuOyBqKz1pKSB7CiAgICAgICAgICAgIGlzX3ByaW1lW2pdID0gZmFsc2U7CiAgICAgICAgICAgIGlmIChzcGZbal0gPT0gMCkgewogICAgICAgICAgICAgICAgc3BmW2pdID0gaTsKICAgICAgICAgICAgfQogICAgICAgICB9CiAgICAgIH0KICAgfQp9CgoKCnN0cnVjdCBOb2RlMiB7CiAgICBpbnQgc3VtLCBsYXp5ID0gMDsKICAgIGJvb2wgaXNMYXp5ID0gZmFsc2U7CiAgICBOb2RlMigpewogICAgICAgIHN1bT1vbzsKICAgIH0KICAgIE5vZGUyKGludCB4KSA6IHN1bSh4KSB7fQogICAgdm9pZCB1cGRhdGVOb2RlKGludCB4LCBpbnQgbHgsIGludCByeCkgewogICAgICAgIHN1bT1taW4oc3VtLHgpOwogICAgICAgIGxhenk9eDsKICAgICAgICBpc0xhenk9dHJ1ZTsKICAgIH0KfTsKCgpzdHJ1Y3QgU2FnYXJhV2l0aExhenkyIHsKI2RlZmluZSBsZWZ0Q2hpbGQgIChub2RlICogMiArIDEpCiNkZWZpbmUgcmlnaHRDaGlsZCAobm9kZSAqIDIgKyAyKQojZGVmaW5lIG1pZCAgICAgICAgKChseCArIHJ4ID4+IDEpKQoKICAgIGludCB0cmVlU2l6ZTsKICAgIHZlY3RvcjxOb2RlMj4gc2VnRGF0YTsKCiAgICB2b2lkIGJ1aWxkKGludCBub2RlLCBpbnQgbHgsIGludCByeCwgdmVjdG9yPGludD4mIGFycikgewogICAgICAgIGlmIChyeCAtIGx4ID09IDEpIHsKICAgICAgICAgICAgaWYgKGx4IDwgKGludClhcnIuc2l6ZSgpKQogICAgICAgICAgICAgICAgc2VnRGF0YVtub2RlXSA9IE5vZGUyKGFycltseF0pOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBidWlsZChsZWZ0Q2hpbGQsIGx4LCBtaWQsIGFycik7CiAgICAgICAgYnVpbGQocmlnaHRDaGlsZCwgbWlkLCByeCwgYXJyKTsKCiAgICAgICAgc2VnRGF0YVtub2RlXSA9IG1lcmdlKHNlZ0RhdGFbbGVmdENoaWxkXSwgc2VnRGF0YVtyaWdodENoaWxkXSk7CiAgICB9CgogICAgTm9kZTIgbWVyZ2UoTm9kZTImIEwsIE5vZGUyJiBSKSB7CiAgICAgICAgTm9kZTIgcmVzID0gTm9kZTIoKTsKICAgICAgICByZXMuc3VtPW1pbihMLnN1bSxSLnN1bSk7CiAgICAgICAgcmV0dXJuIHJlczsKICAgIH0KCgogICAgdm9pZCBwcm9wYWdhdGUoaW50IG5vZGUsIGludCBseCwgaW50IHJ4KSB7CiAgICAgICAgaWYgKHJ4IC0gbHggPT0gMSBvciAhc2VnRGF0YVtub2RlXS5pc0xhenkpIHJldHVybjsKCiAgICAgICAgc2VnRGF0YVtsZWZ0Q2hpbGRdLnVwZGF0ZU5vZGUoc2VnRGF0YVtub2RlXS5sYXp5LCBseCwgbWlkKTsKICAgICAgICBzZWdEYXRhW3JpZ2h0Q2hpbGRdLnVwZGF0ZU5vZGUoc2VnRGF0YVtub2RlXS5sYXp5LCBtaWQsIHJ4KTsKCiAgICAgICAgc2VnRGF0YVtub2RlXS5pc0xhenkgPSBzZWdEYXRhW25vZGVdLmxhenkgPSAwOwogICAgfQoKICAgIHZvaWQgdXBkYXRlKGludCBsLCBpbnQgciwgaW50IHgsIGludCBub2RlLCBpbnQgbHgsIGludCByeCkgewogICAgICAgIHByb3BhZ2F0ZShub2RlLCBseCwgcngpOwoKICAgICAgICBpZiAobCA+PSByeCBvciBseCA+PSByKSByZXR1cm47CiAgICAgICAgaWYgKGwgPD0gbHggYW5kIHJ4IDw9IHIpIHsKICAgICAgICAgICAgc2VnRGF0YVtub2RlXS51cGRhdGVOb2RlKHgsIGx4LCByeCk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIHVwZGF0ZShsLCByLCB4LCBsZWZ0Q2hpbGQsIGx4LCBtaWQpOwogICAgICAgIHVwZGF0ZShsLCByLCB4LCByaWdodENoaWxkLCBtaWQsIHJ4KTsKCiAgICAgICAgc2VnRGF0YVtub2RlXSA9IG1lcmdlKHNlZ0RhdGFbbGVmdENoaWxkXSwgc2VnRGF0YVtyaWdodENoaWxkXSk7CiAgICB9CgoKICAgIE5vZGUyIHF1ZXJ5KGludCBsLCBpbnQgciwgaW50IG5vZGUsIGludCBseCwgaW50IHJ4KSB7CiAgICAgICAgcHJvcGFnYXRlKG5vZGUsIGx4LCByeCk7CgogICAgICAgIGlmIChsID49IHJ4IG9yIGx4ID49IHIpIHJldHVybiBOb2RlMigpOwogICAgICAgIGlmIChsIDw9IGx4IGFuZCByeCA8PSByKSB7CiAgICAgICAgICAgIHJldHVybiBzZWdEYXRhW25vZGVdOwogICAgICAgIH0KCiAgICAgICAgTm9kZTIgbGVmdCA9IHF1ZXJ5KGwsIHIsIGxlZnRDaGlsZCwgbHgsIG1pZCk7CiAgICAgICAgTm9kZTIgcmlnaHQgPSBxdWVyeShsLCByLCByaWdodENoaWxkLCBtaWQsIHJ4KTsKCiAgICAgICAgcmV0dXJuIG1lcmdlKGxlZnQsIHJpZ2h0KTsKICAgIH0KCnB1YmxpYzoKICAgIFNhZ2FyYVdpdGhMYXp5MihpbnQgbiwgdmVjdG9yPGludD4mIGFycikgewogICAgICAgIHRyZWVTaXplID0gMTsKICAgICAgICB3aGlsZSAodHJlZVNpemUgPCBuKSB0cmVlU2l6ZSA8PD0gMTsKICAgICAgICBzZWdEYXRhID0gdmVjdG9yPE5vZGUyPih0cmVlU2l6ZSA8PCAxKTsKICAgICAgICBidWlsZCgwLCAwLCB0cmVlU2l6ZSwgYXJyKTsKICAgIH0KCiAgICB2b2lkIHVwZGF0ZShpbnQgbCwgaW50IHIsIGludCB4KSB7CiAgICAgICAgdXBkYXRlKGwsIHIsIHgsIDAsIDAsIHRyZWVTaXplKTsKICAgIH0KCiAgICBpbnQgcXVlcnkoaW50IGwsIGludCByKSB7CiAgICAgICAgTm9kZTIgYSA9IHF1ZXJ5KGwsIHIsIDAsIDAsIHRyZWVTaXplKTsKICAgICAgICByZXR1cm4gKGEuc3VtKTsKICAgIH0KI3VuZGVmIExlZnRDaGlsZAojdW5kZWYgUmlnaHRDaGlsZAojdW5kZWYgbWlkCn07CgpzdHJ1Y3QgTm9kZSB7CiAgICBpbnQgcHJvZDsKICAgIGludCBzdW0sIGxhenkgPSAwOwogICAgYm9vbCBpc0xhenkgPSBmYWxzZTsKCiAgICBOb2RlKCkgOnByb2QoMSkgeyB9CiAgICBOb2RlKGludCB4KSA6ICBwcm9kKHgpIHt9CiAgICB2b2lkIHVwZGF0ZU5vZGUoaW50IHgsIGludCBseCwgaW50IHJ4KSB7CiAgICAgICAgcHJvZCAqPSBtb2Rwb3coeCxyeC1seCk7CiAgICAgICAgcHJvZCAlPSBNT0Q7CiAgICAgICAgaWYobGF6eT09MClsYXp5PTE7CiAgICAgICAgbGF6eSAqPSB4OwogICAgICAgIGxhenklPU1PRDsKICAgICAgICBpc0xhenkgPSB0cnVlOwogICAgfQp9OwoKCnN0cnVjdCBTYWdhcmFXaXRoTGF6eSB7CiNkZWZpbmUgbGVmdENoaWxkICAobm9kZSAqIDIgKyAxKQojZGVmaW5lIHJpZ2h0Q2hpbGQgKG5vZGUgKiAyICsgMikKI2RlZmluZSBtaWQgICAgICAgICgobHggKyByeCA+PiAxKSkKCiAgICBpbnQgdHJlZVNpemU7CiAgICB2ZWN0b3I8Tm9kZT4gc2VnRGF0YTsKCiAgICB2b2lkIGJ1aWxkKGludCBub2RlLCBpbnQgbHgsIGludCByeCwgdmVjdG9yPGludD4mIGFycikgewogICAgICAgIGlmIChyeCAtIGx4ID09IDEpIHsKICAgICAgICAgICAgaWYgKGx4IDwgKGludClhcnIuc2l6ZSgpKQogICAgICAgICAgICAgICAgc2VnRGF0YVtub2RlXSA9IE5vZGUoYXJyW2x4XSk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGJ1aWxkKGxlZnRDaGlsZCwgbHgsIG1pZCwgYXJyKTsKICAgICAgICBidWlsZChyaWdodENoaWxkLCBtaWQsIHJ4LCBhcnIpOwoKICAgICAgICBzZWdEYXRhW25vZGVdID0gbWVyZ2Uoc2VnRGF0YVtsZWZ0Q2hpbGRdLCBzZWdEYXRhW3JpZ2h0Q2hpbGRdKTsKICAgIH0KCiAgICBOb2RlIG1lcmdlKE5vZGUmIEwsIE5vZGUmIFIpIHsKICAgICAgICBOb2RlIHJlcyA9IE5vZGUoKTsKICAgICAgICByZXMucHJvZCA9IChMLnByb2QgKiBSLnByb2QpICUgTU9EOwogICAgICAgIHJldHVybiByZXM7CiAgICB9CgoKICAgIHZvaWQgcHJvcGFnYXRlKGludCBub2RlLCBpbnQgbHgsIGludCByeCkgewogICAgICAgIGlmIChyeCAtIGx4ID09IDEgb3IgIXNlZ0RhdGFbbm9kZV0uaXNMYXp5KSByZXR1cm47CgogICAgICAgIHNlZ0RhdGFbbGVmdENoaWxkXS51cGRhdGVOb2RlKHNlZ0RhdGFbbm9kZV0ubGF6eSwgbHgsIG1pZCk7CiAgICAgICAgc2VnRGF0YVtyaWdodENoaWxkXS51cGRhdGVOb2RlKHNlZ0RhdGFbbm9kZV0ubGF6eSwgbWlkLCByeCk7CgogICAgICAgIHNlZ0RhdGFbbm9kZV0uaXNMYXp5ID0gc2VnRGF0YVtub2RlXS5sYXp5ID0gMDsKICAgIH0KCiAgICB2b2lkIHVwZGF0ZShpbnQgbCwgaW50IHIsIGludCB4LCBpbnQgbm9kZSwgaW50IGx4LCBpbnQgcngpIHsKICAgICAgICBwcm9wYWdhdGUobm9kZSwgbHgsIHJ4KTsKCiAgICAgICAgaWYgKGwgPj0gcnggb3IgbHggPj0gcikgcmV0dXJuOwogICAgICAgIGlmIChsIDw9IGx4IGFuZCByeCA8PSByKSB7CiAgICAgICAgICAgIHNlZ0RhdGFbbm9kZV0udXBkYXRlTm9kZSh4LCBseCwgcngpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICB1cGRhdGUobCwgciwgeCwgbGVmdENoaWxkLCBseCwgbWlkKTsKICAgICAgICB1cGRhdGUobCwgciwgeCwgcmlnaHRDaGlsZCwgbWlkLCByeCk7CgogICAgICAgIHNlZ0RhdGFbbm9kZV0gPSBtZXJnZShzZWdEYXRhW2xlZnRDaGlsZF0sIHNlZ0RhdGFbcmlnaHRDaGlsZF0pOwogICAgfQoKCiAgICBOb2RlIHF1ZXJ5KGludCBsLCBpbnQgciwgaW50IG5vZGUsIGludCBseCwgaW50IHJ4KSB7CiAgICAgICAgcHJvcGFnYXRlKG5vZGUsIGx4LCByeCk7CgogICAgICAgIGlmIChsID49IHJ4IG9yIGx4ID49IHIpIHJldHVybiBOb2RlKCk7CiAgICAgICAgaWYgKGwgPD0gbHggYW5kIHJ4IDw9IHIpIHsKICAgICAgICAgICAgcmV0dXJuIHNlZ0RhdGFbbm9kZV07CiAgICAgICAgfQoKICAgICAgICBOb2RlIGxlZnQgPSBxdWVyeShsLCByLCBsZWZ0Q2hpbGQsIGx4LCBtaWQpOwogICAgICAgIE5vZGUgcmlnaHQgPSBxdWVyeShsLCByLCByaWdodENoaWxkLCBtaWQsIHJ4KTsKCiAgICAgICAgcmV0dXJuIG1lcmdlKGxlZnQsIHJpZ2h0KTsKICAgIH0KCnB1YmxpYzoKICAgIFNhZ2FyYVdpdGhMYXp5KGludCBuLCB2ZWN0b3I8aW50PiYgYXJyKSB7CiAgICAgICAgdHJlZVNpemUgPSAxOwogICAgICAgIHdoaWxlICh0cmVlU2l6ZSA8IG4pIHRyZWVTaXplIDw8PSAxOwogICAgICAgIHNlZ0RhdGEgPSB2ZWN0b3I8Tm9kZT4odHJlZVNpemUgPDwgMSk7CiAgICAgICAgYnVpbGQoMCwgMCwgdHJlZVNpemUsIGFycik7CiAgICB9CgogICAgdm9pZCB1cGRhdGUoaW50IGwsIGludCByLCBpbnQgeCkgewogICAgICAgIHVwZGF0ZShsLCByLCB4LCAwLCAwLCB0cmVlU2l6ZSk7CiAgICB9CgogICAgaW50IHF1ZXJ5KGludCBsLCBpbnQgcikgewogICAgICAgIE5vZGUgYSA9IHF1ZXJ5KGwsIHIsIDAsIDAsIHRyZWVTaXplKTsKICAgICAgICByZXR1cm4gKGEucHJvZCApICUgTU9EOwogICAgfQojdW5kZWYgTGVmdENoaWxkCiN1bmRlZiBSaWdodENoaWxkCiN1bmRlZiBtaWQKfTsKCgoKdm9pZCBzb2x2ZSgpIHsKICAgIGludCBuLCBxOyBjaW4gPj4gbiA+PiBxOwogICAgdmVjdG9yPGludD4gYShuKSxiKG4pOwogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIGNpbiA+PiBhW2ldLGJbaV09c3BmW2FbaV1dOwoKICAgIFNhZ2FyYVdpdGhMYXp5IHN0KG4sIGEpOwoKICAgIFNhZ2FyYVdpdGhMYXp5MiBzdDIobixiKTsKICAgIHdoaWxlIChxLS0pIHsKICAgICAgICBpbnQgdDsgY2luID4+IHQ7CiAgICAgICAgaWYgKHQgPT0gMSkgewogICAgICAgICAgICBpbnQgbCwgcjsgY2luID4+IGwgPj4gcjsKICAgICAgICAgICAgbC0tLCByLS07CiAgICAgICAgICAgIGludCBwcm9kID0gc3QucXVlcnkobCwgciArIDEpOwogICAgICAgICAgICBpbnQgc3AgPSBzdDIucXVlcnkobCwgciArIDEpOwogICAgICAgICAgICBjb3V0IDw8IChwcm9kICogaW52KHNwKSkgJSBNT0QgPDwgZW5kbDsKCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaW50IGwsIHIsIHg7IGNpbiA+PiBsID4+IHIgPj4geDsKICAgICAgICAgICAgc3QudXBkYXRlKGwtMSwgciwgeCk7CiAgICAgICAgICAgIHN0Mi51cGRhdGUobC0xLCByLCBzcGZbeF0pOwoKICAgICAgICB9CiAgICB9Cn0KCgpzaWduZWQgbWFpbigpIHsKICAgIGlvc19iYXNlOjpzeW5jX3dpdGhfc3RkaW8oZmFsc2UpOyAKICAgIGNpbi50aWUoTlVMTCk7IGNvdXQudGllKE5VTEwpOwogICAgLy8gI2lmbmRlZiBPTkxJTkVfSlVER0UgCiAgICAvLyAgICBmcmVvcGVuKCJpbnB1dC50eHQiLCAiciIsIHN0ZGluKTsgCiAgICAvLyAgICBmcmVvcGVuKCJvdXRwdXQudHh0IiwgInciLCBzdGRvdXQpOyAKICAgIC8vICNlbmRpZiAKICAgIGludCB0OyB0ID0gMTsKICAgIHNpZXZlKDFlNyk7CiAgICBjaW4gPj4gdDsKICAgIHdoaWxlICh0LS0pIHNvbHZlKCk7CiAgICByZXR1cm4gMDsKfQ==