#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#define rep(i, a, b) for(int i=(a); i<(b); i++)
#define repi(i, a, b) for(int i=(a); i>(b); i--)
#define db(x) (cerr << #x << ": " << (x) << '\n')
#define sync ios_base::sync_with_stdio(false), cin.tie(NULL)
#define tests(t) int t; cin >> t; while(t--)
#define iceil(n, x) (((n) + (x) - 1) / (x))
#define ll long long
#define gcd __gcd
#define eb emplace_back
#define pb push_back
#define pf push_front
#define pob pop_back
#define pof pop_front
#define sz size()
#define all(v) (v).begin(), (v).end()
#define uni(v) sort(all(v)), (v).erase(unique(all(v)), (v).end())
#define pii pair<int, int>
#define vi vector<int>
#define vpii vector<pii>
#define vvi vector<vi>
#define fi first
#define se second
#define pqueue priority_queue
#define bitcount(x) __builtin_popcount(x)
#define cps CLOCKS_PER_SEC
#define PI acos(-1.0)
#define EPS 1e-9
#define mod 1000000007
using namespace std;
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
cerr << name << " : " << arg1 << '\n';
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
const char* comma = strchr(names + 1, ','); cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
}
template<typename T1, typename T2>
ostream& operator << (ostream& os, const pair<T1, T2>& p) { return os << '(' << p.fi << ", " << p.se << ')'; }
template<typename T>
void printv(const T& v) { for(auto i : v) cerr << i << ' '; cerr << '\n'; }
template<typename T>
using minpq = priority_queue<T, vector<T>, greater<T>>;
template<typename T>
using maxpq = priority_queue<T>;
//All indexing is 0-based
using namespace __gnu_pbds;
template<class key, class cmp = std::less<key>>
using ordered_set = tree<key, null_type, cmp, rb_tree_tag, tree_order_statistics_node_update>;
//methods: find_by_order(k); & order_of_key(k);
//To make it an ordered_multiset, use pairs of (value, time_of_insertion)
//to distinguish values which are similar
template<class key, class value, class cmp = std::less<key>>
using ordered_map = tree<key, value, cmp, rb_tree_tag, tree_order_statistics_node_update>;
//Returns no. of values x for which ceil(n / x) == y (y must be > 1).
inline ll CC(ll n, ll y) { return iceil(n, y-1) - iceil(n, y); }
//Returns no. of values x for which floor(n / x) == y
inline ll FF(ll n, ll y) { return n / y - n / (y+1); }
//a and b are assumed to be taken modulo p
inline int add(int a, int b, int p = mod){ int c = a + b; if(c >= p) c -= p; return c; }
inline int sub(int a, int b, int p = mod){ int c = a - b; if(c < 0) c += p; return c; }
inline int mul(int a, int b, int p = mod){ return (a * 1ll * b) % p; }
#define N 1000005
#define int ll
// #define trace(...) 42
//Link: https://c...content-available-to-author-only...s.com/string/suffix-automaton.html
string s; int n;
struct state {
int len, link; //len: Length of longest string ending at the state
//link: suffix link
bool terminal; //Is the state terminal ?
map<char, int> next;
};
state st[N << 1];
int cnt, last;
void init(int cur) {
st[cur].len = 0;
st[cur].link = -1;
st[cur].terminal = 0;
st[cur].next.clear();
}
void sa_init() {
cnt = 0;
//source node is at index 0.
// st[0].len = 0, st[0].link = -1;
// st[0].terminal = 0;
// st[0].next.clear();
init(0);
last = 0;
cnt++;
}
void sa_extend(char c) {
int cur = cnt++;
init(cur);
st[cur].len = st[last].len + 1;
int p = last;
while(p != -1 && !st[p].next.count(c)) {
st[p].next[c] = cur;
p = st[p].link;
}
if(p == -1) {
st[cur].link = 0;
}
else {
int q = st[p].next[c];
if(st[q].len == st[p].len + 1) {
st[cur].link = q;
}
else {
int clone = cnt++;
st[clone].terminal = 0;
st[clone].len = st[p].len + 1;
st[clone].link = st[q].link;
st[clone].next = st[q].next;
st[cur].link = st[q].link = clone;
while(p != -1 && st[p].next[c] == q) {
st[p].next[c] = clone;
p = st[p].link;
}
}
}
last = cur;
}
void find_terminals() {
int p = last;
while(p) {
st[p].terminal = 1;
p = st[p].link;
}
}
//O(N lg K), where K is the size of the alphabet
void SuffixAutomaton() {
sa_init();
n = s.size();
for(int i = 0; i < n; i++) {
sa_extend(s[i]);
}
find_terminals();
}
void printSA() {
for(int i = 0; i < cnt; i++) {
cout << "i: " << i << '\n';
cout << "Terminal: " << st[i].terminal << '\n';
cout << "Transitions:\n";
for(auto p : st[i].next) {
cout << p.first << " -> " << p.second << '\n';
}
cout << "Suf Link: " << st[i].link << '\n';
cout << '\n';
}
}
int tot[N], pret[N];
int ans[N], pre[N];
bool vis[N];
void dfs(int cur) {
vis[cur] = 1;
if(cur) {
int l, r;
l = st[st[cur].link].len + 1;
r = st[cur].len;
ans[l]++, ans[r+1]--;
// trace(l, r);
}
for(auto p : st[cur].next) {
int i = p.se;
if(!vis[i]) dfs(i);
}
}
int norm(int x) {
if(x < 0) x += mod;
if(x >= mod) x -= mod;
return x;
}
void prep() {
SuffixAutomaton();
fill_n(ans, n + 5, 0);
fill_n(vis, cnt, 0);
dfs(0);
for(int i = 1; i <= n; i++)
ans[i] += ans[i-1];
for(int i = 0; i <= n; i++) {
// trace(i, ans[i]);
pre[i] = ans[i];
if(i) pre[i] = add(pre[i], pre[i-1]);
}
assert(!pre[0]);
}
main()
{
#ifdef CP
freopen("/home/tarun/Desktop/input.txt", "r", stdin);
// freopen("/home/tarun/Desktop/output.txt", "w", stdout);
#endif
sync;
clock_t clk = clock();
cerr << "I will return...\n";
rep(i, 0, N) {
if(i == 0) tot[i] = pre[i] = 1;
else {
tot[i] = mul(26, tot[i-1]);
pret[i] = add(pret[i-1], tot[i]);
}
}
int oo = 1;
tests(t) {
// trace(t);
cout << "Case " << oo++ << ":\n";
cin >> s; n = s.size();
prep();
int q; cin >> q;
while(q--) {
int l, r; cin >> l >> r;
--l;
int ans = pret[r];
ans = sub(ans, pret[l]);
ans = sub(ans, sub(pre[r], pre[l]));
// trace(sub(pre[r], pre[l]));
cout << ans << '\n';
}
}
cerr << "...don't you ever hang your head.\n";
cerr << "Time (in ms): " << (double)(clock() - clk) * 1000.0 / cps << '\n';
}
//Compile using:
//g++ -o filename.exe --std=c++11 filename.cpp
//Use -D CP for defining a macro CP in the local environment
I2luY2x1ZGU8Yml0cy9zdGRjKysuaD4KI2luY2x1ZGU8ZXh0L3BiX2RzL2Fzc29jX2NvbnRhaW5lci5ocHA+CiNpbmNsdWRlPGV4dC9wYl9kcy90cmVlX3BvbGljeS5ocHA+CiNkZWZpbmUgcmVwKGksIGEsIGIpIGZvcihpbnQgaT0oYSk7IGk8KGIpOyBpKyspCiNkZWZpbmUgcmVwaShpLCBhLCBiKSBmb3IoaW50IGk9KGEpOyBpPihiKTsgaS0tKQojZGVmaW5lIGRiKHgpIChjZXJyIDw8ICN4IDw8ICI6ICIgPDwgKHgpIDw8ICdcbicpCiNkZWZpbmUgc3luYyBpb3NfYmFzZTo6c3luY193aXRoX3N0ZGlvKGZhbHNlKSwgY2luLnRpZShOVUxMKQojZGVmaW5lIHRlc3RzKHQpIGludCB0OyBjaW4gPj4gdDsgd2hpbGUodC0tKQojZGVmaW5lIGljZWlsKG4sIHgpICgoKG4pICsgKHgpIC0gMSkgLyAoeCkpCiNkZWZpbmUgbGwgbG9uZyBsb25nCiNkZWZpbmUgZ2NkIF9fZ2NkCiNkZWZpbmUgZWIgZW1wbGFjZV9iYWNrCiNkZWZpbmUgcGIgcHVzaF9iYWNrCiNkZWZpbmUgcGYgcHVzaF9mcm9udAojZGVmaW5lIHBvYiBwb3BfYmFjawojZGVmaW5lIHBvZiBwb3BfZnJvbnQKI2RlZmluZSBzeiBzaXplKCkKI2RlZmluZSBhbGwodikgKHYpLmJlZ2luKCksICh2KS5lbmQoKQojZGVmaW5lIHVuaSh2KSBzb3J0KGFsbCh2KSksICh2KS5lcmFzZSh1bmlxdWUoYWxsKHYpKSwgKHYpLmVuZCgpKQojZGVmaW5lIHBpaSBwYWlyPGludCwgaW50PgojZGVmaW5lIHZpIHZlY3RvcjxpbnQ+CiNkZWZpbmUgdnBpaSB2ZWN0b3I8cGlpPgojZGVmaW5lIHZ2aSB2ZWN0b3I8dmk+CiNkZWZpbmUgZmkgZmlyc3QKI2RlZmluZSBzZSBzZWNvbmQKI2RlZmluZSBwcXVldWUgcHJpb3JpdHlfcXVldWUKI2RlZmluZSBiaXRjb3VudCh4KSBfX2J1aWx0aW5fcG9wY291bnQoeCkKI2RlZmluZSBjcHMgQ0xPQ0tTX1BFUl9TRUMKI2RlZmluZSBQSSBhY29zKC0xLjApCiNkZWZpbmUgRVBTIDFlLTkKI2RlZmluZSBtb2QgMTAwMDAwMDAwNwp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKI2RlZmluZSB0cmFjZSguLi4pIF9fZigjX19WQV9BUkdTX18sIF9fVkFfQVJHU19fKQp0ZW1wbGF0ZSA8dHlwZW5hbWUgQXJnMT4Kdm9pZCBfX2YoY29uc3QgY2hhciogbmFtZSwgQXJnMSYmIGFyZzEpewogICAgY2VyciA8PCBuYW1lIDw8ICIgOiAiIDw8IGFyZzEgPDwgJ1xuJzsKfQp0ZW1wbGF0ZSA8dHlwZW5hbWUgQXJnMSwgdHlwZW5hbWUuLi4gQXJncz4Kdm9pZCBfX2YoY29uc3QgY2hhciogbmFtZXMsIEFyZzEmJiBhcmcxLCBBcmdzJiYuLi4gYXJncyl7CiAgICBjb25zdCBjaGFyKiBjb21tYSA9IHN0cmNocihuYW1lcyArIDEsICcsJyk7IGNlcnIud3JpdGUobmFtZXMsIGNvbW1hIC0gbmFtZXMpIDw8ICIgOiAiIDw8IGFyZzE8PCIgfCAiO19fZihjb21tYSsxLCBhcmdzLi4uKTsKfQoKdGVtcGxhdGU8dHlwZW5hbWUgVDEsIHR5cGVuYW1lIFQyPgpvc3RyZWFtJiBvcGVyYXRvciA8PCAob3N0cmVhbSYgb3MsIGNvbnN0IHBhaXI8VDEsIFQyPiYgcCkgeyByZXR1cm4gb3MgPDwgJygnIDw8IHAuZmkgPDwgIiwgIiA8PCBwLnNlIDw8ICcpJzsgfQoKdGVtcGxhdGU8dHlwZW5hbWUgVD4Kdm9pZCBwcmludHYoY29uc3QgVCYgdikgeyBmb3IoYXV0byBpIDogdikgY2VyciA8PCBpIDw8ICcgJzsgY2VyciA8PCAnXG4nOyB9Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBUPgp1c2luZyBtaW5wcSA9IHByaW9yaXR5X3F1ZXVlPFQsIHZlY3RvcjxUPiwgZ3JlYXRlcjxUPj47Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBUPgp1c2luZyBtYXhwcSA9IHByaW9yaXR5X3F1ZXVlPFQ+OwoKLy9BbGwgaW5kZXhpbmcgaXMgMC1iYXNlZAp1c2luZyBuYW1lc3BhY2UgX19nbnVfcGJkczsKdGVtcGxhdGU8Y2xhc3Mga2V5LCBjbGFzcyBjbXAgPSBzdGQ6Omxlc3M8a2V5Pj4KdXNpbmcgb3JkZXJlZF9zZXQgPSB0cmVlPGtleSwgbnVsbF90eXBlLCBjbXAsIHJiX3RyZWVfdGFnLCB0cmVlX29yZGVyX3N0YXRpc3RpY3Nfbm9kZV91cGRhdGU+OwovL21ldGhvZHM6IGZpbmRfYnlfb3JkZXIoayk7ICYgb3JkZXJfb2Zfa2V5KGspOwovL1RvIG1ha2UgaXQgYW4gb3JkZXJlZF9tdWx0aXNldCwgdXNlIHBhaXJzIG9mICh2YWx1ZSwgdGltZV9vZl9pbnNlcnRpb24pCi8vdG8gZGlzdGluZ3Vpc2ggdmFsdWVzIHdoaWNoIGFyZSBzaW1pbGFyCgp0ZW1wbGF0ZTxjbGFzcyBrZXksIGNsYXNzIHZhbHVlLCBjbGFzcyBjbXAgPSBzdGQ6Omxlc3M8a2V5Pj4KdXNpbmcgb3JkZXJlZF9tYXAgPSB0cmVlPGtleSwgdmFsdWUsIGNtcCwgcmJfdHJlZV90YWcsIHRyZWVfb3JkZXJfc3RhdGlzdGljc19ub2RlX3VwZGF0ZT47CgovL1JldHVybnMgbm8uIG9mIHZhbHVlcyB4IGZvciB3aGljaCBjZWlsKG4gLyB4KSA9PSB5ICh5IG11c3QgYmUgPiAxKS4KaW5saW5lIGxsIENDKGxsIG4sIGxsIHkpIHsgcmV0dXJuIGljZWlsKG4sIHktMSkgLSBpY2VpbChuLCB5KTsgfQoKLy9SZXR1cm5zIG5vLiBvZiB2YWx1ZXMgeCBmb3Igd2hpY2ggZmxvb3IobiAvIHgpID09IHkKaW5saW5lIGxsIEZGKGxsIG4sIGxsIHkpIHsgcmV0dXJuIG4gLyB5IC0gbiAvICh5KzEpOyB9CgovL2EgYW5kIGIgYXJlIGFzc3VtZWQgdG8gYmUgdGFrZW4gbW9kdWxvIHAKaW5saW5lIGludCBhZGQoaW50IGEsIGludCBiLCBpbnQgcCA9IG1vZCl7IGludCBjID0gYSArIGI7IGlmKGMgPj0gcCkgYyAtPSBwOyByZXR1cm4gYzsgfQppbmxpbmUgaW50IHN1YihpbnQgYSwgaW50IGIsIGludCBwID0gbW9kKXsgaW50IGMgPSBhIC0gYjsgaWYoYyA8IDApIGMgKz0gcDsgcmV0dXJuIGM7IH0KaW5saW5lIGludCBtdWwoaW50IGEsIGludCBiLCBpbnQgcCA9IG1vZCl7IHJldHVybiAoYSAqIDFsbCAqIGIpICUgcDsgfQoKI2RlZmluZSBOIDEwMDAwMDUKI2RlZmluZSBpbnQgbGwKLy8gI2RlZmluZSB0cmFjZSguLi4pIDQyCgovL0xpbms6IGh0dHBzOi8vYy4uLmNvbnRlbnQtYXZhaWxhYmxlLXRvLWF1dGhvci1vbmx5Li4ucy5jb20vc3RyaW5nL3N1ZmZpeC1hdXRvbWF0b24uaHRtbAoKc3RyaW5nIHM7IGludCBuOyAKCnN0cnVjdCBzdGF0ZSB7CiAgICBpbnQgbGVuLCBsaW5rOyAvL2xlbjogTGVuZ3RoIG9mIGxvbmdlc3Qgc3RyaW5nIGVuZGluZyBhdCB0aGUgc3RhdGUKICAgICAgICAgICAgICAgICAgIC8vbGluazogc3VmZml4IGxpbmsKICAgIGJvb2wgdGVybWluYWw7IC8vSXMgdGhlIHN0YXRlIHRlcm1pbmFsID8KICAgIG1hcDxjaGFyLCBpbnQ+IG5leHQ7Cn07CgpzdGF0ZSBzdFtOIDw8IDFdOwppbnQgY250LCBsYXN0OwoKdm9pZCBpbml0KGludCBjdXIpIHsKICAgIHN0W2N1cl0ubGVuID0gMDsKICAgIHN0W2N1cl0ubGluayA9IC0xOwogICAgc3RbY3VyXS50ZXJtaW5hbCA9IDA7CiAgICBzdFtjdXJdLm5leHQuY2xlYXIoKTsKfQoKdm9pZCBzYV9pbml0KCkgewogICAgY250ID0gMDsKICAgIC8vc291cmNlIG5vZGUgaXMgYXQgaW5kZXggMC4KICAgIC8vIHN0WzBdLmxlbiA9IDAsIHN0WzBdLmxpbmsgPSAtMTsKICAgIC8vIHN0WzBdLnRlcm1pbmFsID0gMDsKICAgIC8vIHN0WzBdLm5leHQuY2xlYXIoKTsKICAgIGluaXQoMCk7CiAgICBsYXN0ID0gMDsKICAgIGNudCsrOwp9Cgp2b2lkIHNhX2V4dGVuZChjaGFyIGMpIHsKICAgIGludCBjdXIgPSBjbnQrKzsKICAgIGluaXQoY3VyKTsKICAgIHN0W2N1cl0ubGVuID0gc3RbbGFzdF0ubGVuICsgMTsKICAgIGludCBwID0gbGFzdDsKICAgIHdoaWxlKHAgIT0gLTEgJiYgIXN0W3BdLm5leHQuY291bnQoYykpIHsKICAgICAgICBzdFtwXS5uZXh0W2NdID0gY3VyOwogICAgICAgIHAgPSBzdFtwXS5saW5rOwogICAgfQogICAgaWYocCA9PSAtMSkgewogICAgICAgIHN0W2N1cl0ubGluayA9IDA7CiAgICB9CiAgICBlbHNlIHsKICAgICAgICBpbnQgcSA9IHN0W3BdLm5leHRbY107CiAgICAgICAgaWYoc3RbcV0ubGVuID09IHN0W3BdLmxlbiArIDEpIHsKICAgICAgICAgICAgc3RbY3VyXS5saW5rID0gcTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIGludCBjbG9uZSA9IGNudCsrOwogICAgICAgICAgICBzdFtjbG9uZV0udGVybWluYWwgPSAwOwogICAgICAgICAgICBzdFtjbG9uZV0ubGVuID0gc3RbcF0ubGVuICsgMTsKICAgICAgICAgICAgc3RbY2xvbmVdLmxpbmsgPSBzdFtxXS5saW5rOwogICAgICAgICAgICBzdFtjbG9uZV0ubmV4dCA9IHN0W3FdLm5leHQ7CiAgICAgICAgICAgIHN0W2N1cl0ubGluayA9IHN0W3FdLmxpbmsgPSBjbG9uZTsKICAgICAgICAgICAgd2hpbGUocCAhPSAtMSAmJiBzdFtwXS5uZXh0W2NdID09IHEpIHsKICAgICAgICAgICAgICAgIHN0W3BdLm5leHRbY10gPSBjbG9uZTsKICAgICAgICAgICAgICAgIHAgPSBzdFtwXS5saW5rOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgbGFzdCA9IGN1cjsKfQoKdm9pZCBmaW5kX3Rlcm1pbmFscygpIHsKICAgIGludCBwID0gbGFzdDsKICAgIHdoaWxlKHApIHsKICAgICAgICBzdFtwXS50ZXJtaW5hbCA9IDE7CiAgICAgICAgcCA9IHN0W3BdLmxpbms7CiAgICB9Cn0KCi8vTyhOIGxnIEspLCB3aGVyZSBLIGlzIHRoZSBzaXplIG9mIHRoZSBhbHBoYWJldAp2b2lkIFN1ZmZpeEF1dG9tYXRvbigpIHsKICAgIHNhX2luaXQoKTsKICAgIG4gPSBzLnNpemUoKTsKICAgIGZvcihpbnQgaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgICAgICBzYV9leHRlbmQoc1tpXSk7CiAgICB9CiAgICBmaW5kX3Rlcm1pbmFscygpOwp9Cgp2b2lkIHByaW50U0EoKSB7CiAgICBmb3IoaW50IGkgPSAwOyBpIDwgY250OyBpKyspIHsKICAgICAgICBjb3V0IDw8ICJpOiAiIDw8IGkgPDwgJ1xuJzsKICAgICAgICBjb3V0IDw8ICJUZXJtaW5hbDogIiA8PCBzdFtpXS50ZXJtaW5hbCA8PCAnXG4nOwogICAgICAgIGNvdXQgPDwgIlRyYW5zaXRpb25zOlxuIjsgCiAgICAgICAgZm9yKGF1dG8gcCA6IHN0W2ldLm5leHQpIHsKICAgICAgICAgICAgY291dCA8PCBwLmZpcnN0IDw8ICIgLT4gIiA8PCBwLnNlY29uZCA8PCAnXG4nOwogICAgICAgIH0KICAgICAgICBjb3V0IDw8ICJTdWYgTGluazogIiA8PCBzdFtpXS5saW5rIDw8ICdcbic7CiAgICAgICAgY291dCA8PCAnXG4nOwogICAgfQp9CgppbnQgdG90W05dLCBwcmV0W05dOwppbnQgYW5zW05dLCBwcmVbTl07CmJvb2wgdmlzW05dOwoKdm9pZCBkZnMoaW50IGN1cikgewogICAgdmlzW2N1cl0gPSAxOwogICAgaWYoY3VyKSB7CiAgICAgICAgaW50IGwsIHI7CiAgICAgICAgbCA9IHN0W3N0W2N1cl0ubGlua10ubGVuICsgMTsKICAgICAgICByID0gc3RbY3VyXS5sZW47CiAgICAgICAgYW5zW2xdKyssIGFuc1tyKzFdLS07CiAgICAgICAgLy8gdHJhY2UobCwgcik7CiAgICB9CiAgICBmb3IoYXV0byBwIDogc3RbY3VyXS5uZXh0KSB7CiAgICAgICAgaW50IGkgPSBwLnNlOwogICAgICAgIGlmKCF2aXNbaV0pIGRmcyhpKTsKICAgIH0KfQoKaW50IG5vcm0oaW50IHgpIHsKICAgIGlmKHggPCAwKSB4ICs9IG1vZDsKICAgIGlmKHggPj0gbW9kKSB4IC09IG1vZDsKICAgIHJldHVybiB4Owp9Cgp2b2lkIHByZXAoKSB7CiAgICBTdWZmaXhBdXRvbWF0b24oKTsKICAgIGZpbGxfbihhbnMsIG4gKyA1LCAwKTsKICAgIGZpbGxfbih2aXMsIGNudCwgMCk7CiAgICBkZnMoMCk7CgogICAgZm9yKGludCBpID0gMTsgaSA8PSBuOyBpKyspCiAgICAgICAgYW5zW2ldICs9IGFuc1tpLTFdOwoKICAgIGZvcihpbnQgaSA9IDA7IGkgPD0gbjsgaSsrKSB7CiAgICAgICAgLy8gdHJhY2UoaSwgYW5zW2ldKTsKICAgICAgICBwcmVbaV0gPSBhbnNbaV07CiAgICAgICAgaWYoaSkgcHJlW2ldID0gYWRkKHByZVtpXSwgcHJlW2ktMV0pOwogICAgfQogICAgYXNzZXJ0KCFwcmVbMF0pOwp9CgptYWluKCkKeyAgIAogICAgI2lmZGVmIENQCiAgICAgICAgZnJlb3BlbigiL2hvbWUvdGFydW4vRGVza3RvcC9pbnB1dC50eHQiLCAiciIsIHN0ZGluKTsKICAgICAvLyBmcmVvcGVuKCIvaG9tZS90YXJ1bi9EZXNrdG9wL291dHB1dC50eHQiLCAidyIsIHN0ZG91dCk7CiAgICAjZW5kaWYKICAgIHN5bmM7CiAgICBjbG9ja190IGNsayA9IGNsb2NrKCk7CiAgICBjZXJyIDw8ICJJIHdpbGwgcmV0dXJuLi4uXG4iOwoKICAgIHJlcChpLCAwLCBOKSB7CiAgICAgICAgaWYoaSA9PSAwKSB0b3RbaV0gPSBwcmVbaV0gPSAxOwogICAgICAgIGVsc2UgewogICAgICAgICAgICB0b3RbaV0gPSBtdWwoMjYsIHRvdFtpLTFdKTsKICAgICAgICAgICAgcHJldFtpXSA9IGFkZChwcmV0W2ktMV0sIHRvdFtpXSk7CiAgICAgICAgfQogICAgfQoKICAgIGludCBvbyA9IDE7CiAgICB0ZXN0cyh0KSB7CiAgICAgICAgLy8gdHJhY2UodCk7CiAgICAgICAgY291dCA8PCAiQ2FzZSAiIDw8IG9vKysgPDwgIjpcbiI7CiAgICAgICAgY2luID4+IHM7IG4gPSBzLnNpemUoKTsKICAgICAgICBwcmVwKCk7CiAgICAgICAgaW50IHE7IGNpbiA+PiBxOwogICAgICAgIHdoaWxlKHEtLSkgewogICAgICAgICAgICBpbnQgbCwgcjsgY2luID4+IGwgPj4gcjsKICAgICAgICAgICAgLS1sOwogICAgICAgICAgICBpbnQgYW5zID0gcHJldFtyXTsKICAgICAgICAgICAgYW5zID0gc3ViKGFucywgcHJldFtsXSk7CiAgICAgICAgICAgIGFucyA9IHN1YihhbnMsIHN1YihwcmVbcl0sIHByZVtsXSkpOwogICAgICAgICAgICAvLyB0cmFjZShzdWIocHJlW3JdLCBwcmVbbF0pKTsKICAgICAgICAgICAgY291dCA8PCBhbnMgPDwgJ1xuJzsKICAgICAgICB9CiAgICB9CgogICAgY2VyciA8PCAiLi4uZG9uJ3QgeW91IGV2ZXIgaGFuZyB5b3VyIGhlYWQuXG4iOwogICAgY2VyciA8PCAiVGltZSAoaW4gbXMpOiAiIDw8IChkb3VibGUpKGNsb2NrKCkgLSBjbGspICogMTAwMC4wIC8gY3BzIDw8ICdcbic7Cn0KCi8vQ29tcGlsZSB1c2luZzoKLy9nKysgLW8gZmlsZW5hbWUuZXhlIC0tc3RkPWMrKzExIGZpbGVuYW1lLmNwcAovL1VzZSAtRCBDUCBmb3IgZGVmaW5pbmcgYSBtYWNybyBDUCBpbiB0aGUgbG9jYWwgZW52aXJvbm1lbnQKCgo=