#include "testlib.h"
#include <ranges>
 
const uint32_t MAX_T = 10'000;
const uint32_t MAX_N = 200'000;
const uint32_t MAX_TOTAL_N = 200'000;
const uint32_t MAX_X = 1'000'000;
const uint32_t MAX_M = 1'000'000;
 
const pattern RED_OR_BLUE("[RB]");
const pattern RED("[R]");
 
struct ChipCell {
    uint32_t index;
    uint32_t x, m;
    bool red_cell;
};
 
struct ChipsStorage {
    uint32_t test_number;
    std::vector<uint32_t> cell_coordinates;
    bool have_red = false, have_blue = false;
    
    ChipsStorage(const uint32_t test_number) : test_number(test_number) {}
    
    ChipsStorage(const ChipsStorage&) = default;
 
    ChipsStorage&& operator+(const ChipCell chip_cell) && {
        if (!cell_coordinates.empty() && cell_coordinates.back() >= chip_cell.x)
            ensuref(false, "%s", std::format("x[{}][{}] == {} >= {} == x[{}][{}]",
                                       test_number, chip_cell.index - 1, cell_coordinates.back(),
                                       chip_cell.x, test_number, chip_cell.index).c_str());
        cell_coordinates.push_back(chip_cell.x);
        if (chip_cell.red_cell)
            have_red = true;
        else
            have_blue = true;
        return std::move(*this);
    }
};
 
uint32_t readTestCase(uint32_t total_non_empty_cells, const uint32_t test_number) {
    setTestCase(test_number);
    uint32_t n = inf.readInt(2, MAX_N, std::format("n[{}]", test_number));
    total_non_empty_cells += n;
    ensuref(total_non_empty_cells <= MAX_TOTAL_N, "%s",
            std::format("total_non_empty_cells == {} exceeded {}", total_non_empty_cells, MAX_TOTAL_N).c_str());
    inf.readEoln();
    ChipsStorage chips_storage = std::ranges::fold_left(std::ranges::views::iota(static_cast<uint32_t>(1), n + 1) | std::ranges::views::transform([test_number](uint32_t cell_index) {
        ChipCell cell{.index = cell_index};
        cell.x = inf.readInt(1, MAX_X, std::format("x[{}][{}]", test_number, cell_index));
        inf.readSpace();
        cell.m = inf.readInt(1, MAX_M, std::format("m[{}][{}]", test_number, cell_index));
        inf.readSpace();
        std::string color = inf.readToken(RED_OR_BLUE, std::format("c[{}][{}]", test_number, cell_index));
        inf.readEoln();
        cell.red_cell = RED.matches(color);
        return cell;
    }), ChipsStorage(test_number), std::plus<>());
    ensuref(chips_storage.have_red, "there are no red chips at all");
    ensuref(chips_storage.have_blue, "there are no blue chips at all");
    return total_non_empty_cells;
}
 
int main(int argc, char* argv[]) {
    registerValidation(argc, argv);
    uint32_t T = inf.readInt(1, MAX_T, "T");
    inf.readEoln();
    uint32_t non_empty_cells = std::ranges::fold_left(std::ranges::views::iota(static_cast<uint32_t>(1), T + 1), 0, readTestCase);
    inf.readEof();
}
