#include <iostream>
#include <string>
#include <vector>
#include <cstdint>
#include <sstream>
#include <algorithm>
using namespace std;
const double MAXX = 1e308;
const double MINN = 1e-308;
const int BATCH_SIZE = 8;
const int IDX_BITS = 11;
const int FULL_MASK = (1 << IDX_BITS) - 1;
int permute_pow2(int x, int key1, int key2) {
x &= FULL_MASK;
x = (x + key1) & FULL_MASK;
x ^= (x << 5) & FULL_MASK;
x ^= (x >> 7);
x = (x + key2) & FULL_MASK;
x ^= (x << 3) & FULL_MASK;
x ^= (x >> 2);
x = (x + (key1 ^ key2)) & FULL_MASK;
return x & FULL_MASK;
}
int permute_restricted(int n, int seed, int idx) {
int key1 = (seed * 73 + n * 19 + 7) & FULL_MASK;
int key2 = (seed * 199 + n * 11 + 13) & FULL_MASK;
int x = idx & FULL_MASK;
for (int i = 0; i < (1 << 12); ++i) {
x = permute_pow2(x, key1, key2);
if (x < n) {
return x;
}
}
return idx % n;
}
int encode_state(int seed, int batch) {
return ((seed & 0xFF) << 8) | (batch & 0xFF);
}
pair<int, int> decode_state(int state) {
int seed = (state >> 8) & 0xFF;
int batch = state & 0xFF;
return {seed, batch};
}
string handle_init(int n, int &seed_counter) {
(void)n;
int seed = seed_counter;
seed_counter = (seed_counter + 1) & 0xFF;
if (seed_counter == 0) {
seed_counter = 1;
}
int state = encode_state(seed, 0);
ostringstream out;
out << "{\"state\":" << state << "}";
return out.str();
}
string handle_next(int n, int state) {
auto [seed, batch] = decode_state(state);
int start_idx = batch * BATCH_SIZE;
if (start_idx >= n) {
ostringstream out;
out << "{\"state\":" << state << ",\"indices\":[]}";
return out.str();
}
int take = min(BATCH_SIZE, n - start_idx);
vector<int> indices;
indices.reserve(take);
for (int i = start_idx; i < start_idx + take; ++i) {
indices.push_back(permute_restricted(n, seed, i));
}
int new_state = encode_state(seed, batch + 1);
ostringstream out;
out << "{\"state\":" << new_state << ",\"indices\":[";
for (int i = 0; i < (int)indices.size(); ++i) {
if (i > 0) out << ",";
out << indices[i];
}
out << "]}";
return out.str();
}
string trim(const string &s) {
size_t l = 0;
while (l < s.size() && isspace((unsigned char)s[l])) ++l;
size_t r = s.size();
while (r > l && isspace((unsigned char)s[r - 1])) --r;
return s.substr(l, r - l);
}
string get_json_string_field(const string &line, const string &key) {
string pattern = "\"" + key + "\"";
size_t pos = line.find(pattern);
if (pos == string::npos) return "";
pos = line.find(':', pos);
if (pos == string::npos) return "";
pos = line.find('"', pos);
if (pos == string::npos) return "";
size_t end = line.find('"', pos + 1);
if (end == string::npos) return "";
return line.substr(pos + 1, end - pos - 1);
}
bool get_json_int_field(const string &line, const string &key, long long &value) {
string pattern = "\"" + key + "\"";
size_t pos = line.find(pattern);
if (pos == string::npos) return false;
pos = line.find(':', pos);
if (pos == string::npos) return false;
++pos;
while (pos < line.size() && isspace((unsigned char)line[pos])) ++pos;
if (pos >= line.size()) return false;
size_t end = pos;
while (end < line.size() && (isdigit((unsigned char)line[end]) || line[end] == '-' || line[end] == '+')) {
++end;
}
if (end == pos) return false;
try {
value = stoll(line.substr(pos, end - pos));
} catch (...) {
return false;
}
return true;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int seed_counter = 1;
string line;
while (getline(cin, line)) {
line = trim(line);
if (line.empty()) continue;
string rtype = get_json_string_field(line, "type");
if (rtype.empty()) continue;
string resp;
if (rtype == "ping") {
resp = "{}";
} else if (rtype == "init") {
long long n_ll = 0;
if (!get_json_int_field(line, "n", n_ll)) {
resp = "{}";
} else {
int n = static_cast<int>(n_ll);
resp = handle_init(n, seed_counter);
}
} else if (rtype == "next") {
long long n_ll = 0;
long long state_ll = 0;
bool ok_n = get_json_int_field(line, "n", n_ll);
bool ok_state = get_json_int_field(line, "state", state_ll);
if (!ok_n || !ok_state) {
resp = "{}";
} else {
int n = static_cast<int>(n_ll);
int state = static_cast<int>(state_ll);
resp = handle_next(n, state);
}
} else {
resp = "{}";
}
cout << resp << "\n";
cout.flush();
}
return 0;
}