#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <string.h>
#include <fstream>
#include <cassert>
using namespace std;
typedef long long ll;
const int M = 1e6;
const ll mod = 1e9 + 7;
ll cr[M], cl[M], c[M];
struct node {/*{{{*/
public:
ll m, ml, mr, mm;
int li, ri;
void merge(node& l, node& r) {
li = l.li;
ri = r.ri;
ll s = (cr[l.ri] * cl[r.li]) % mod;
m = (l.m*r.m) % mod;
m = (m + ((l.ml*r.mr) % mod)*s) % mod;
ml = (l.m*r.ml) % mod;
ml = (ml + ((l.ml*r.mm) % mod)*s) % mod;
mr = (r.m*l.mr) % mod;
mr = (mr + ((r.mr*l.mm) % mod)*s) % mod;
mm = (l.mr*r.ml) % mod;
mm = (mm + ((l.mm*r.mm) % mod)*s) % mod;
}
node() {
li = 0, ri = 0, ml = 1, mr = 1, mm = 0, m = 1;
}
void init() {
li = 0, ri = 0, ml = 1, mr = 1, mm = 0, m = 1;
}
};/*}}}*/
template<class node>
class segtree {/*{{{*/
template<bool b>class param {};
inline void spltdwn(int idx, param<true>) { splt(idx); }
inline void splt(int idx) {/*{{{*/
idx >>= 1;
if (idx>0)splt(idx);
tree[idx].split(tree[idx << 1], tree[(idx << 1) | 1]);
}/*}}}*/
inline void spltdwn(int, param<false>) {};
inline void split(node& a, node& b, node& c, param<true>) { return a.split(b, c); }
inline void split(node&, node&, node&, param<false>) {}
template<typename t, void (t::*)(t&, t&)> class T {};
template<typename t> static char test(T<t, &t::split>*) { return 0; }
template<typename t> static long double test(...) { return 0; }
int u, v;
node query(int root, int left_range, int right_range) {/*{{{*/
if (u <= left_range && right_range <= v)
return tree[root];
int mid = (left_range + right_range) >> 1,
l = root << 1,
r = l | 1;
if (has_split)split(tree[root], tree[l], tree[r], param<has_split>());
node res;
if (u >= mid)res = query(r, mid, right_range);
else if (v <= mid)res = query(l, left_range, mid);
else {
node n1 = query(l, left_range, mid),
n2 = query(r, mid, right_range);
res.merge(n1, n2);
}
if (has_split) tree[root].merge(tree[l], tree[r]);
return res;
}/*}}}*/
template<void(*fn)(node&)>
void local_update(int root, int left_range, int right_range) {/*{{{*/
if (u <= left_range && right_range <= v) {
return fn(tree[root]);
}
int mid = (left_range + right_range) >> 1,
l = root << 1,
r = l | 1;
if (has_split)split(tree[root], tree[l], tree[r], param<has_split>());
if (v>mid)local_update<fn>(r, mid, right_range);
if (u<mid)local_update<fn>(l, left_range, mid);
tree[root].merge(tree[l], tree[r]);
}/*}}}*/
void mrgup(int idx) {/*{{{*/
idx >>= 1;
while (idx>0)
tree[idx].merge(tree[idx << 1], tree[(idx << 1) | 1]),
idx >>= 1;
}/*}}}*/
public:
static bool const has_split = (sizeof(test<node>(0)) == sizeof(char));
int N;
int leftmost_leaf, rightmost_leaf;
node* tree;
node identity;
segtree() { tree = 0; }
~segtree() {
if (tree) delete[] tree;
}
void init(int n, const node a[], const node& identity) {/*{{{*/
if (tree) delete[] tree;
this->identity = identity;
N = 0;
while ((1 << N)<n)N++;
leftmost_leaf = 1 << N;
rightmost_leaf = leftmost_leaf << 1;
tree = new node[rightmost_leaf];
for (int i = 0; i<n; i++)
tree[i + leftmost_leaf] = a[i];
for (int i = n + leftmost_leaf; i<rightmost_leaf; i++)
tree[i] = identity;
for (int i = leftmost_leaf - 1; i; i--)
tree[i].merge(tree[i << 1], tree[(i << 1) | 1]);
}/*}}}*/
node query(int u, int v) {//[u,v]/*{{{*/
this->u = u + leftmost_leaf;
this->v = v + leftmost_leaf + 1;
return query(1, leftmost_leaf, rightmost_leaf);
}/*}}}*/
node query(int u) {//faster version of query(u,u)/*{{{*/
//indexing starts from 0
u += leftmost_leaf;
spltdwn(u, param<has_split>());
return tree[u];
}/*}}}*/
template<void(*fn)(node&)>
void update(int u, int v) {/*{{{*/
//0-indexed
this->u = u + leftmost_leaf;
this->v = v + leftmost_leaf + 1;
return local_update<fn>(1, leftmost_leaf, rightmost_leaf);
}/*}}}*/
template<void(*fn)(node&)>
void update(int u) {//faster version of update(u,u)/*{{{*/
//indexing starts from 0
u += leftmost_leaf;
spltdwn(u, param<has_split>());
fn(tree[u]);
mrgup(u);
}/*}}}*/
void split_down(int leaf_idx) {/*{{{*/
spltdwn(leaf_idx + leftmost_leaf, param<has_split>());
}/*}}}*/
void merge_up(int leaf_idx) {/*{{{*/
mrgup(leaf_idx + leftmost_leaf);
}/*}}}*/
bool is_leaf(int tree_idx) { return tree_idx >= leftmost_leaf; }
int binary_search(node k) {/*{{{*/
//search the last place i, such that merge( everyting to the left of i(including i) ) compares less than k
int root = 1;
node n = identity;
//identity satisfies merge(identity,y) = merge(y,identity) = y for all y.
assert(!(k<identity));
while (!is_leaf(root)) {
int left_child = root << 1,
right_child = left_child | 1;
if (has_split)
split(tree[root], tree[left_child], tree[right_child], param<has_split>());
node m;
m.merge(n, tree[left_child]);
if (m<k) {//go to right side
n = m;
root = right_child;
}
else root = left_child;
}
node m;
m.merge(n, tree[root]);
mrgup(root);
if (m<k)return root - leftmost_leaf;
else return root - 1 - leftmost_leaf;
}/*}}}*/
};/*}}}*/
#define boost ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define sz(a) int((a).size())
#define rep(i, s, n) for(int i = s; i <= (n); ++i)
#define rev(i, n, s) for(int i = (n); i >= s; --i)
#define fore(x, a) for(auto &&x : a)
const ll inf = mod-7;
ll w[M];
ll d[M], zo[M], s[M];
node a[M];
void upd(node &cur) {
cur.m = c[cur.li];
}
int main() {
#ifdef loc
if(!freopen((string(FOLDER) + "inp.txt").c_str(), "r", stdin)) {
assert(0);
}
freopen((string(FOLDER) + "out.txt").c_str(), "w", stdout);
#endif
boost;
int t;
cin >> t;
rep(z, 1, t) {
cout << "Case #" << z << ": ";
int n, m;
cin >> n >> m;
ll w1, aw, bw;
cin >> w1 >> aw >> bw;
w[1] = w1;
rep(i,2, m) {
w[i] = ((aw*w[i - 1] + bw) % n) + 1;
}
ll d1, ad, bd;
cin >> d1 >> ad >> bd;
d[1] = d1;
rep(i, 2, m) {
d[i] = (ad*d[i - 1] + bd) % 3;
}
rep(i, 1, m) {
zo[i] = max(1LL, min((ll)n, w[i] + d[i] - 1));
}
ll s1, as, bs;
cin >> s1 >> as >> bs;
s[1] = s1;
rep(i, 2, m) {
s[i] = ((as*s[i - 1] + bs) % inf) + 1;
}
rep(i, 0,n+1) {
a[i].init();
a[i].li = i;
a[i].ri = i;
}
memset(cl, 0, sizeof(cl));
memset(cr, 0, sizeof(cr));
memset(c, 0, sizeof(c));
rep(i, 1, n) c[i] = 1;
segtree<node> p;
p.init(n + 1, a, a[n + 1]);
int res = 0;
// cout << p.query(1, n).m << " ";
rep(i, 1, m) {
//cout << "(" << w[i] << " " << zo[i] << " " << s[i] << ") ";
if (w[i] == zo[i]) {
c[w[i]] += s[i];
if (c[w[i]] >= mod) c[w[i]] -= mod;
}
else if (w[i] == zo[i] - 1) {
cr[w[i]] += s[i];
if (cr[w[i]] >= mod) cr[w[i]] -= mod;
}
else {
cl[w[i]] += s[i];
if (cl[w[i]] >= mod) cl[w[i]] -= mod;
}
p.update<&upd>(w[i]);
res += p.query(1, n).m;
// cout << p.query(1, n).m << " ";
if (res >= mod) res -= mod;
}
cout << res << endl;
}
return 0;
}
I2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPGxpc3Q+CiNpbmNsdWRlIDxtYXA+CiNpbmNsdWRlIDxzZXQ+CiNpbmNsdWRlIDxkZXF1ZT4KI2luY2x1ZGUgPHF1ZXVlPgojaW5jbHVkZSA8c3RhY2s+CiNpbmNsdWRlIDxiaXRzZXQ+CiNpbmNsdWRlIDxhbGdvcml0aG0+CiNpbmNsdWRlIDxmdW5jdGlvbmFsPgojaW5jbHVkZSA8bnVtZXJpYz4KI2luY2x1ZGUgPHV0aWxpdHk+CiNpbmNsdWRlIDxzc3RyZWFtPgojaW5jbHVkZSA8aW9zdHJlYW0+CiNpbmNsdWRlIDxpb21hbmlwPgojaW5jbHVkZSA8Y3N0ZGlvPgojaW5jbHVkZSA8Y21hdGg+CiNpbmNsdWRlIDxjc3RkbGliPgojaW5jbHVkZSA8Y2N0eXBlPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8Y3N0cmluZz4KI2luY2x1ZGUgPGNzdGRpbz4KI2luY2x1ZGUgPGNtYXRoPgojaW5jbHVkZSA8Y3N0ZGxpYj4KI2luY2x1ZGUgPGN0aW1lPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxmc3RyZWFtPgojaW5jbHVkZSA8Y2Fzc2VydD4KdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCgp0eXBlZGVmIGxvbmcgbG9uZyBsbDsKY29uc3QgaW50IE0gPSAxZTY7CmNvbnN0IGxsIG1vZCA9IDFlOSArIDc7CgpsbCBjcltNXSwgY2xbTV0sIGNbTV07CgpzdHJ1Y3Qgbm9kZSB7Lyp7e3sqLwpwdWJsaWM6CiAgbGwgbSwgbWwsIG1yLCBtbTsKICBpbnQgbGksIHJpOwogIHZvaWQgbWVyZ2Uobm9kZSYgbCwgbm9kZSYgcikgewogICAgbGkgPSBsLmxpOwogICAgcmkgPSByLnJpOwogICAgbGwgcyA9IChjcltsLnJpXSAqIGNsW3IubGldKSAlIG1vZDsKICAgIG0gPSAobC5tKnIubSkgJSBtb2Q7CiAgICBtID0gKG0gKyAoKGwubWwqci5tcikgJSBtb2QpKnMpICUgbW9kOwogICAgbWwgPSAobC5tKnIubWwpICUgbW9kOwogICAgbWwgPSAobWwgKyAoKGwubWwqci5tbSkgJSBtb2QpKnMpICUgbW9kOwogICAgbXIgPSAoci5tKmwubXIpICUgbW9kOwogICAgbXIgPSAobXIgKyAoKHIubXIqbC5tbSkgJSBtb2QpKnMpICUgbW9kOwogICAgbW0gPSAobC5tcipyLm1sKSAlIG1vZDsKICAgIG1tID0gKG1tICsgKChsLm1tKnIubW0pICUgbW9kKSpzKSAlIG1vZDsKICB9CiAgbm9kZSgpIHsKICAgIGxpID0gMCwgcmkgPSAwLCBtbCA9IDEsIG1yID0gMSwgbW0gPSAwLCBtID0gMTsKICB9CiAgdm9pZCBpbml0KCkgewogICAgbGkgPSAwLCByaSA9IDAsIG1sID0gMSwgbXIgPSAxLCBtbSA9IDAsIG0gPSAxOwogIH0KfTsvKn19fSovCnRlbXBsYXRlPGNsYXNzIG5vZGU+CmNsYXNzIHNlZ3RyZWUgey8qe3t7Ki8KICB0ZW1wbGF0ZTxib29sIGI+Y2xhc3MgcGFyYW0ge307CiAgaW5saW5lIHZvaWQgc3BsdGR3bihpbnQgaWR4LCBwYXJhbTx0cnVlPikgeyBzcGx0KGlkeCk7IH0KICBpbmxpbmUgdm9pZCBzcGx0KGludCBpZHgpIHsvKnt7eyovCiAgICBpZHggPj49IDE7CiAgICBpZiAoaWR4PjApc3BsdChpZHgpOwogICAgdHJlZVtpZHhdLnNwbGl0KHRyZWVbaWR4IDw8IDFdLCB0cmVlWyhpZHggPDwgMSkgfCAxXSk7CiAgfS8qfX19Ki8KICBpbmxpbmUgdm9pZCBzcGx0ZHduKGludCwgcGFyYW08ZmFsc2U+KSB7fTsKICBpbmxpbmUgdm9pZCBzcGxpdChub2RlJiBhLCBub2RlJiBiLCBub2RlJiBjLCBwYXJhbTx0cnVlPikgeyByZXR1cm4gYS5zcGxpdChiLCBjKTsgfQogIGlubGluZSB2b2lkIHNwbGl0KG5vZGUmLCBub2RlJiwgbm9kZSYsIHBhcmFtPGZhbHNlPikge30KICB0ZW1wbGF0ZTx0eXBlbmFtZSB0LCB2b2lkICh0OjoqKSh0JiwgdCYpPiBjbGFzcyBUIHt9OwogIHRlbXBsYXRlPHR5cGVuYW1lIHQ+IHN0YXRpYyBjaGFyIHRlc3QoVDx0LCAmdDo6c3BsaXQ+KikgeyByZXR1cm4gMDsgfQogIHRlbXBsYXRlPHR5cGVuYW1lIHQ+IHN0YXRpYyBsb25nIGRvdWJsZSB0ZXN0KC4uLikgeyByZXR1cm4gMDsgfQogIGludCB1LCB2OwogIG5vZGUgcXVlcnkoaW50IHJvb3QsIGludCBsZWZ0X3JhbmdlLCBpbnQgcmlnaHRfcmFuZ2UpIHsvKnt7eyovCiAgICBpZiAodSA8PSBsZWZ0X3JhbmdlICYmIHJpZ2h0X3JhbmdlIDw9IHYpCiAgICAgIHJldHVybiB0cmVlW3Jvb3RdOwogICAgaW50IG1pZCA9IChsZWZ0X3JhbmdlICsgcmlnaHRfcmFuZ2UpID4+IDEsCiAgICAgIGwgPSByb290IDw8IDEsCiAgICAgIHIgPSBsIHwgMTsKICAgIGlmIChoYXNfc3BsaXQpc3BsaXQodHJlZVtyb290XSwgdHJlZVtsXSwgdHJlZVtyXSwgcGFyYW08aGFzX3NwbGl0PigpKTsKICAgIG5vZGUgcmVzOwogICAgaWYgKHUgPj0gbWlkKXJlcyA9IHF1ZXJ5KHIsIG1pZCwgcmlnaHRfcmFuZ2UpOwogICAgZWxzZSBpZiAodiA8PSBtaWQpcmVzID0gcXVlcnkobCwgbGVmdF9yYW5nZSwgbWlkKTsKICAgIGVsc2UgewogICAgICBub2RlIG4xID0gcXVlcnkobCwgbGVmdF9yYW5nZSwgbWlkKSwKICAgICAgICBuMiA9IHF1ZXJ5KHIsIG1pZCwgcmlnaHRfcmFuZ2UpOwogICAgICByZXMubWVyZ2UobjEsIG4yKTsKICAgIH0KICAgIGlmIChoYXNfc3BsaXQpIHRyZWVbcm9vdF0ubWVyZ2UodHJlZVtsXSwgdHJlZVtyXSk7CiAgICByZXR1cm4gcmVzOwogIH0vKn19fSovCiAgdGVtcGxhdGU8dm9pZCgqZm4pKG5vZGUmKT4KICB2b2lkIGxvY2FsX3VwZGF0ZShpbnQgcm9vdCwgaW50IGxlZnRfcmFuZ2UsIGludCByaWdodF9yYW5nZSkgey8qe3t7Ki8KICAgIGlmICh1IDw9IGxlZnRfcmFuZ2UgJiYgcmlnaHRfcmFuZ2UgPD0gdikgewogICAgICByZXR1cm4gZm4odHJlZVtyb290XSk7CiAgICB9CiAgICBpbnQgbWlkID0gKGxlZnRfcmFuZ2UgKyByaWdodF9yYW5nZSkgPj4gMSwKICAgICAgbCA9IHJvb3QgPDwgMSwKICAgICAgciA9IGwgfCAxOwogICAgaWYgKGhhc19zcGxpdClzcGxpdCh0cmVlW3Jvb3RdLCB0cmVlW2xdLCB0cmVlW3JdLCBwYXJhbTxoYXNfc3BsaXQ+KCkpOwogICAgaWYgKHY+bWlkKWxvY2FsX3VwZGF0ZTxmbj4ociwgbWlkLCByaWdodF9yYW5nZSk7CiAgICBpZiAodTxtaWQpbG9jYWxfdXBkYXRlPGZuPihsLCBsZWZ0X3JhbmdlLCBtaWQpOwogICAgdHJlZVtyb290XS5tZXJnZSh0cmVlW2xdLCB0cmVlW3JdKTsKICB9Lyp9fX0qLwogIHZvaWQgbXJndXAoaW50IGlkeCkgey8qe3t7Ki8KICAgIGlkeCA+Pj0gMTsKICAgIHdoaWxlIChpZHg+MCkKICAgICAgdHJlZVtpZHhdLm1lcmdlKHRyZWVbaWR4IDw8IDFdLCB0cmVlWyhpZHggPDwgMSkgfCAxXSksCiAgICAgIGlkeCA+Pj0gMTsKICB9Lyp9fX0qLwpwdWJsaWM6CiAgc3RhdGljIGJvb2wgY29uc3QgaGFzX3NwbGl0ID0gKHNpemVvZih0ZXN0PG5vZGU+KDApKSA9PSBzaXplb2YoY2hhcikpOwogIGludCBOOwogIGludCBsZWZ0bW9zdF9sZWFmLCByaWdodG1vc3RfbGVhZjsKICBub2RlKiB0cmVlOwogIG5vZGUgaWRlbnRpdHk7CiAgc2VndHJlZSgpIHsgdHJlZSA9IDA7IH0KICB+c2VndHJlZSgpIHsKICAgIGlmICh0cmVlKSBkZWxldGVbXSB0cmVlOwogIH0KICB2b2lkIGluaXQoaW50IG4sIGNvbnN0IG5vZGUgYVtdLCBjb25zdCBub2RlJiBpZGVudGl0eSkgey8qe3t7Ki8KICAgIGlmICh0cmVlKSBkZWxldGVbXSB0cmVlOwogICAgdGhpcy0+aWRlbnRpdHkgPSBpZGVudGl0eTsKICAgIE4gPSAwOwogICAgd2hpbGUgKCgxIDw8IE4pPG4pTisrOwogICAgbGVmdG1vc3RfbGVhZiA9IDEgPDwgTjsKICAgIHJpZ2h0bW9zdF9sZWFmID0gbGVmdG1vc3RfbGVhZiA8PCAxOwogICAgdHJlZSA9IG5ldyBub2RlW3JpZ2h0bW9zdF9sZWFmXTsKICAgIGZvciAoaW50IGkgPSAwOyBpPG47IGkrKykKICAgICAgdHJlZVtpICsgbGVmdG1vc3RfbGVhZl0gPSBhW2ldOwogICAgZm9yIChpbnQgaSA9IG4gKyBsZWZ0bW9zdF9sZWFmOyBpPHJpZ2h0bW9zdF9sZWFmOyBpKyspCiAgICAgIHRyZWVbaV0gPSBpZGVudGl0eTsKICAgIGZvciAoaW50IGkgPSBsZWZ0bW9zdF9sZWFmIC0gMTsgaTsgaS0tKQogICAgICB0cmVlW2ldLm1lcmdlKHRyZWVbaSA8PCAxXSwgdHJlZVsoaSA8PCAxKSB8IDFdKTsKICB9Lyp9fX0qLwogIG5vZGUgcXVlcnkoaW50IHUsIGludCB2KSB7Ly9bdSx2XS8qe3t7Ki8KICAgIHRoaXMtPnUgPSB1ICsgbGVmdG1vc3RfbGVhZjsKICAgIHRoaXMtPnYgPSB2ICsgbGVmdG1vc3RfbGVhZiArIDE7CiAgICByZXR1cm4gcXVlcnkoMSwgbGVmdG1vc3RfbGVhZiwgcmlnaHRtb3N0X2xlYWYpOwogIH0vKn19fSovCiAgbm9kZSBxdWVyeShpbnQgdSkgey8vZmFzdGVyIHZlcnNpb24gb2YgcXVlcnkodSx1KS8qe3t7Ki8KICAgICAgICAgICAgICAgICAgICAgLy9pbmRleGluZyBzdGFydHMgZnJvbSAwCiAgICB1ICs9IGxlZnRtb3N0X2xlYWY7CiAgICBzcGx0ZHduKHUsIHBhcmFtPGhhc19zcGxpdD4oKSk7CiAgICByZXR1cm4gdHJlZVt1XTsKICB9Lyp9fX0qLwogIHRlbXBsYXRlPHZvaWQoKmZuKShub2RlJik+CiAgdm9pZCB1cGRhdGUoaW50IHUsIGludCB2KSB7Lyp7e3sqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vMC1pbmRleGVkCiAgICB0aGlzLT51ID0gdSArIGxlZnRtb3N0X2xlYWY7CiAgICB0aGlzLT52ID0gdiArIGxlZnRtb3N0X2xlYWYgKyAxOwogICAgcmV0dXJuIGxvY2FsX3VwZGF0ZTxmbj4oMSwgbGVmdG1vc3RfbGVhZiwgcmlnaHRtb3N0X2xlYWYpOwogIH0vKn19fSovCiAgdGVtcGxhdGU8dm9pZCgqZm4pKG5vZGUmKT4KICB2b2lkIHVwZGF0ZShpbnQgdSkgey8vZmFzdGVyIHZlcnNpb24gb2YgdXBkYXRlKHUsdSkvKnt7eyovCiAgICAgICAgICAgICAgICAgICAgICAvL2luZGV4aW5nIHN0YXJ0cyBmcm9tIDAKICAgIHUgKz0gbGVmdG1vc3RfbGVhZjsKICAgIHNwbHRkd24odSwgcGFyYW08aGFzX3NwbGl0PigpKTsKICAgIGZuKHRyZWVbdV0pOwogICAgbXJndXAodSk7CiAgfS8qfX19Ki8KICB2b2lkIHNwbGl0X2Rvd24oaW50IGxlYWZfaWR4KSB7Lyp7e3sqLwogICAgc3BsdGR3bihsZWFmX2lkeCArIGxlZnRtb3N0X2xlYWYsIHBhcmFtPGhhc19zcGxpdD4oKSk7CiAgfS8qfX19Ki8KICB2b2lkIG1lcmdlX3VwKGludCBsZWFmX2lkeCkgey8qe3t7Ki8KICAgIG1yZ3VwKGxlYWZfaWR4ICsgbGVmdG1vc3RfbGVhZik7CiAgfS8qfX19Ki8KICBib29sIGlzX2xlYWYoaW50IHRyZWVfaWR4KSB7IHJldHVybiB0cmVlX2lkeCA+PSBsZWZ0bW9zdF9sZWFmOyB9CiAgaW50IGJpbmFyeV9zZWFyY2gobm9kZSBrKSB7Lyp7e3sqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vc2VhcmNoIHRoZSBsYXN0IHBsYWNlIGksIHN1Y2ggdGhhdCBtZXJnZSggZXZlcnl0aW5nIHRvIHRoZSBsZWZ0IG9mIGkoaW5jbHVkaW5nIGkpICkgY29tcGFyZXMgbGVzcyB0aGFuIGsKICAgIGludCByb290ID0gMTsKICAgIG5vZGUgbiA9IGlkZW50aXR5OwogICAgLy9pZGVudGl0eSBzYXRpc2ZpZXMgbWVyZ2UoaWRlbnRpdHkseSkgPSBtZXJnZSh5LGlkZW50aXR5KSA9IHkgZm9yIGFsbCB5LgogICAgYXNzZXJ0KCEoazxpZGVudGl0eSkpOwogICAgd2hpbGUgKCFpc19sZWFmKHJvb3QpKSB7CiAgICAgIGludCBsZWZ0X2NoaWxkID0gcm9vdCA8PCAxLAogICAgICAgIHJpZ2h0X2NoaWxkID0gbGVmdF9jaGlsZCB8IDE7CiAgICAgIGlmIChoYXNfc3BsaXQpCiAgICAgICAgc3BsaXQodHJlZVtyb290XSwgdHJlZVtsZWZ0X2NoaWxkXSwgdHJlZVtyaWdodF9jaGlsZF0sIHBhcmFtPGhhc19zcGxpdD4oKSk7CiAgICAgIG5vZGUgbTsKICAgICAgbS5tZXJnZShuLCB0cmVlW2xlZnRfY2hpbGRdKTsKICAgICAgaWYgKG08aykgey8vZ28gdG8gcmlnaHQgc2lkZQogICAgICAgIG4gPSBtOwogICAgICAgIHJvb3QgPSByaWdodF9jaGlsZDsKICAgICAgfQogICAgICBlbHNlIHJvb3QgPSBsZWZ0X2NoaWxkOwogICAgfQogICAgbm9kZSBtOwogICAgbS5tZXJnZShuLCB0cmVlW3Jvb3RdKTsKICAgIG1yZ3VwKHJvb3QpOwogICAgaWYgKG08aylyZXR1cm4gcm9vdCAtIGxlZnRtb3N0X2xlYWY7CiAgICBlbHNlIHJldHVybiByb290IC0gMSAtIGxlZnRtb3N0X2xlYWY7CiAgfS8qfX19Ki8KfTsvKn19fSovCgojZGVmaW5lIGJvb3N0IGlvc19iYXNlOjpzeW5jX3dpdGhfc3RkaW8oZmFsc2UpOyBjaW4udGllKDApOyBjb3V0LnRpZSgwKQojZGVmaW5lIHN6KGEpIGludCgoYSkuc2l6ZSgpKQojZGVmaW5lIHJlcChpLCBzLCBuKSAgZm9yKGludCBpID0gczsgaSA8PSAobik7ICsraSkKI2RlZmluZSByZXYoaSwgbiwgcykgIGZvcihpbnQgaSA9IChuKTsgaSA+PSBzOyAtLWkpCiNkZWZpbmUgZm9yZSh4LCBhKSBmb3IoYXV0byAmJnggOiBhKQpjb25zdCBsbCBpbmYgPSBtb2QtNzsKCmxsIHdbTV07CmxsIGRbTV0sIHpvW01dLCBzW01dOwoKbm9kZSBhW01dOwoKdm9pZCB1cGQobm9kZSAmY3VyKSB7CiAgY3VyLm0gPSBjW2N1ci5saV07Cn0KCmludCBtYWluKCkgewojaWZkZWYgbG9jCiAgaWYoIWZyZW9wZW4oKHN0cmluZyhGT0xERVIpICsgImlucC50eHQiKS5jX3N0cigpLCAiciIsIHN0ZGluKSkgewogICAgYXNzZXJ0KDApOwogIH0KICBmcmVvcGVuKChzdHJpbmcoRk9MREVSKSArICJvdXQudHh0IikuY19zdHIoKSwgInciLCBzdGRvdXQpOwojZW5kaWYKICBib29zdDsKICBpbnQgdDsKICBjaW4gPj4gdDsKICByZXAoeiwgMSwgdCkgewogICAgY291dCA8PCAiQ2FzZSAjIiA8PCB6IDw8ICI6ICI7CiAgICBpbnQgbiwgbTsKICAgIGNpbiA+PiBuID4+IG07CiAgICBsbCB3MSwgYXcsIGJ3OwogICAgY2luID4+IHcxID4+IGF3ID4+IGJ3OwogICAgd1sxXSA9IHcxOwogICAgcmVwKGksMiwgbSkgewogICAgICB3W2ldID0gKChhdyp3W2kgLSAxXSArIGJ3KSAlIG4pICsgMTsKICAgIH0KICAgIGxsIGQxLCBhZCwgYmQ7CiAgICBjaW4gPj4gZDEgPj4gYWQgPj4gYmQ7CiAgICBkWzFdID0gZDE7CiAgICByZXAoaSwgMiwgbSkgewogICAgICBkW2ldID0gKGFkKmRbaSAtIDFdICsgYmQpICUgMzsKICAgIH0KICAgIHJlcChpLCAxLCBtKSB7CiAgICAgIHpvW2ldID0gbWF4KDFMTCwgbWluKChsbCluLCB3W2ldICsgZFtpXSAtIDEpKTsKICAgIH0KICAgIGxsIHMxLCBhcywgYnM7CiAgICBjaW4gPj4gczEgPj4gYXMgPj4gYnM7CiAgICBzWzFdID0gczE7CiAgICByZXAoaSwgMiwgbSkgewogICAgICBzW2ldID0gKChhcypzW2kgLSAxXSArIGJzKSAlIGluZikgKyAxOwogICAgfQogICAgcmVwKGksIDAsbisxKSB7CiAgICAgIGFbaV0uaW5pdCgpOwogICAgICBhW2ldLmxpID0gaTsKICAgICAgYVtpXS5yaSA9IGk7CiAgICB9CiAgICBtZW1zZXQoY2wsIDAsIHNpemVvZihjbCkpOwogICAgbWVtc2V0KGNyLCAwLCBzaXplb2YoY3IpKTsKICAgIG1lbXNldChjLCAwLCBzaXplb2YoYykpOwogICAgcmVwKGksIDEsIG4pIGNbaV0gPSAxOwogICAgc2VndHJlZTxub2RlPiBwOwogICAgcC5pbml0KG4gKyAxLCBhLCBhW24gKyAxXSk7CiAgICBpbnQgcmVzID0gMDsKICAgLy8gY291dCA8PCBwLnF1ZXJ5KDEsIG4pLm0gPDwgIiAiOwogICAgcmVwKGksIDEsIG0pIHsKICAgICAgLy9jb3V0IDw8ICIoIiA8PCB3W2ldIDw8ICIgIiA8PCB6b1tpXSA8PCAiICIgPDwgc1tpXSA8PCAiKSAiOwogICAgICBpZiAod1tpXSA9PSB6b1tpXSkgewogICAgICAgIGNbd1tpXV0gKz0gc1tpXTsKICAgICAgICBpZiAoY1t3W2ldXSA+PSBtb2QpIGNbd1tpXV0gLT0gbW9kOwogICAgICB9CiAgICAgIGVsc2UgaWYgKHdbaV0gPT0gem9baV0gLSAxKSB7CiAgICAgICAgY3Jbd1tpXV0gKz0gc1tpXTsKICAgICAgICBpZiAoY3Jbd1tpXV0gPj0gbW9kKSBjclt3W2ldXSAtPSBtb2Q7CiAgICAgIH0KICAgICAgZWxzZSB7CiAgICAgICAgY2xbd1tpXV0gKz0gc1tpXTsKICAgICAgICBpZiAoY2xbd1tpXV0gPj0gbW9kKSBjbFt3W2ldXSAtPSBtb2Q7CiAgICAgIH0KICAgICAgcC51cGRhdGU8JnVwZD4od1tpXSk7CiAgICAgIHJlcyArPSBwLnF1ZXJ5KDEsIG4pLm07CiAgICAvLyAgY291dCA8PCBwLnF1ZXJ5KDEsIG4pLm0gPDwgIiAiOwogICAgICBpZiAocmVzID49IG1vZCkgcmVzIC09IG1vZDsKICAgIH0KICAgIGNvdXQgPDwgcmVzIDw8IGVuZGw7CiAgfQogIHJldHVybiAwOwp9