#!/usr/bin/env python3
import sys, random, math

MAXFLOOR = 1000000000
MAXN = 100000
MAXQ = 100000

def cmdlinearg(name, default=None):
    for arg in sys.argv:
        if arg.startswith(name + "="):
            return arg.split("=")[1]
    assert default is not None, name
    return default

random.seed(int(cmdlinearg('seed', sys.argv[-1])))
MAXN = int(cmdlinearg('maxn', MAXN))
N = int(cmdlinearg('n', random.randint(2, MAXN)))
MAXQ = int(cmdlinearg('maxq', MAXQ))
Q = int(cmdlinearg('q', random.randint(1, MAXQ)))
MAXFLOOR = int(cmdlinearg('maxfloor', MAXFLOOR))
BIAS = int(cmdlinearg('bias', 10 * N))
MOVENUM = int(cmdlinearg('movenum', Q // 2))
movesfirst = int(cmdlinearg('movesfirst', 0))
mode = cmdlinearg('mode', '')
if mode == 'moveonce':
    MOVENUM = min(MOVENUM, N)
QNUM = Q - MOVENUM

# modes: moveonce (every elevator moves at most once), movesfirst (moves are first, queries after)

print(N, Q)
print(" ".join(str(random.randint(1, MAXFLOOR)) for _ in range(N)))

# one pair of elevators that is queried/moved extremely often and many that are queried only rarely
weights = [BIAS]
weights += [1] * (N - 2)

queries = random.choices(range(1, N), weights=weights, k=QNUM)
moves = [x - random.randint(0, 1) for x in random.choices(range(1, N), weights=weights, k=MOVENUM)] if mode != "moveonce" else random.sample(list(range(1, N)) + [0], MOVENUM)

if mode == "incmoves":
    moves.sort(reverse=True)

order = ['!' for _ in range(MOVENUM)] + ['?' for _ in range(QNUM)]
if movesfirst == 0:
    random.shuffle(order)
for c in order:
    if c == '?':
        print(c, queries[-1])
        queries.pop()
    else:
        print(c, moves[-1], random.randint(1, MAXFLOOR))
        moves.pop()
