#include "testlib.h"

using Coordinate = int32_t;
using PathLength = int64_t;
using Index = uint32_t;

const Index MIN_T = 1, MAX_T = 5e4;
const Index MIN_N = 1, MAX_N = 2e5;
const Index MAX_S = 2e5;
const Coordinate MIN_X = -1e6;
const Coordinate MAX_X = 1e6;

Index validate_test_and_return_size(const Index test_index, const Index size_limit) {
    setTestCase(test_index);
    Index n = static_cast<Index>(inf.readLong(static_cast<int64_t>(MIN_N), static_cast<int64_t>(MAX_N), "n"));
    ensuref(n <= size_limit, "%s", std::format("after {}{} test, the total size {} exceeds the limit {}",
                                               test_index, englishEnding(test_index), MAX_S - size_limit + n,
                                               MAX_S).c_str());
    inf.readSpace();
    std::map<Coordinate, std::string> reason;
    auto addLong = [&](Coordinate low, Coordinate high, const std::string& name) {
        Coordinate x = static_cast<Coordinate>(inf.readLong(static_cast<int64_t>(low), static_cast<int64_t>(high), name));
        auto it = reason.find(x);
        if (it != reason.end()) // if I straight up take ensuref(it == reason.end()), won't there be a UB if the condition is true but the further operands depend on its falsity
            ensuref(it == reason.end(), "%s", std::format("coordinate collision: {} = {} = {}", it->second, it->first, name).c_str());
        reason[x] = name;
    };
    addLong(MIN_X, MAX_X, "start");
    inf.readSpace();
    addLong(MIN_X, MAX_X, "end");
    inf.readEoln();
    for (Index point_index = 1; point_index <= n; ++point_index) {
        addLong(MIN_X, MAX_X, std::format("key[{}]", point_index));
        inf.readSpace();
        addLong(MIN_X, MAX_X, std::format("grate[{}]", point_index));
        inf.readEoln();
    }
    return n;
}

int main(int argc, char *argv[]) {
    registerValidation(argc, argv);
    Index t = static_cast<Index>(inf.readLong(static_cast<int64_t>(MIN_T), static_cast<int64_t>(MAX_T), "t"));
    inf.readEoln();
    Index size_limit = MAX_S;
    for (Index test_index = 1; test_index <= t; ++test_index)
        size_limit -= validate_test_and_return_size(test_index, size_limit);
    inf.readEof();
}
