#if defined(_USE_PCH_)
#include "pch.hpp"
#else
#include <bits/stdc++.h>
#endif
#define RNG(V_, A_, B_, ...) for (int V_ = (A_), V_##_END = (B_) __VA_OPT__(, ) __VA_ARGS__; V_ <= V_##_END; V_++)
#define IRNG(V_, A_, B_, ...) for (int V_ = (A_), V_##_END = (B_) __VA_OPT__(, ) __VA_ARGS__; V_ >= V_##_END; V_--)
#ifdef _WIN32
#define long int64_t
#endif
#define fir first
#define sec second
#define _UN using namespace
using namespace std;
typedef pair<int, int> pii;
typedef __int128 i128;

#define PRINTF_STRINGVIEW(X_) (int) ((X_).size()), (X_).data()

static __attribute__((format(printf, 1, 2))) int eprintf(const char* fmt, ...) {
    va_list args;
    va_start(args, fmt);
    int ret = vfprintf(stderr, fmt, args);
    va_end(args);
    return ret;
}

static bool is_debugger_attached() {
    static int result_cache = -1;
    if (result_cache != -1) return result_cache;
    static char buf[1024];
    memset(buf, 0, sizeof(buf));
    auto f = fopen("/proc/self/status", "r");
    if (!f) return false;
    fread(buf, 1, sizeof(buf) - 1, f);
    if (auto p = strstr(buf, "TracerPid:")) {
        p += 10;
        int a = 0;
        sscanf(p, "%d", &a);
        if (a) return (bool) (result_cache = true);
    }
    return (bool) (result_cache = false);
}

static void debug_break_or_exit() {
    if (is_debugger_attached()) {
        __asm__ volatile("int3");
    } else {
        eprintf("Critical error occurred. Program terminated.\n");
        exit(1);
    }
}

static void my_report_error(const char* expr, const char* file, int line, const char* function) {
    eprintf("Error: %s\n  file %s, line %d, function %s\n", expr, file, line, function);
    if (errno) eprintf("  errno: %s (%d)\n", strerror(errno), errno);
    if (is_debugger_attached()) { __asm__ volatile("int3"); }
}

#define __REPORT_ERR(_EXPR_S) my_report_error(_EXPR_S, __FILE__, __LINE__, __ASSERT_FUNCTION)

#define CHK(_EXPR)                                                           \
    do {                                                                     \
        if (!static_cast<bool>((_EXPR))) return __REPORT_ERR(#_EXPR), false; \
    } while (0)

#define CHK_EXIT(_EXPR)                                                                      \
    do {                                                                                     \
        if (!static_cast<bool>((_EXPR))) return __REPORT_ERR(#_EXPR), debug_break_or_exit(); \
    } while (0)

template<typename T, typename U>
bool elem_in(const T& x, initializer_list<U> lst) {
    for (auto& y : lst) {
        if (x == y) return true;
    }
    return false;
}

enum TokenType {
    TK_NL,
    TK_COMMENT,
    TK_STR,
    TK_WORD,
    TK_SYM,
    TK_EOF,
};

struct Token {
    int pos, len, ln, col;
    TokenType type;
    string_view content;
    int data;
    int child, next, next_comma;
};

constexpr int BUFFER_SIZE = 1048576, N_TOKEN = 1048576;
char buf[BUFFER_SIZE], tmp[BUFFER_SIZE];
int file_size;
Token tokens[N_TOKEN];
int n_token;
int line_pos[BUFFER_SIZE], n_line;

bool verify_ascii(string_view str) {
    for (int i = 0; i < str.size(); i++) {
        int ch = ((uint8_t*) str.data())[i];
        if ((ch < 32 && (ch != '\n' && ch != '\t' && ch != '\r')) || ch > 126) return false;
    }
    return true;
}

bool init(const char* filename) {
    auto file = fopen(filename, "rb");
    CHK(file);
    CHK(!fseek(file, 0, SEEK_END));
    constexpr auto FILE_SIZE_LIM = BUFFER_SIZE - 10;
    long len = ftell(file);
    CHK(len >= 0 && len <= FILE_SIZE_LIM);
    file_size = int(len);
    CHK(!fseek(file, 0, SEEK_SET));
    CHK(file_size == fread(buf, 1, BUFFER_SIZE, file));
    fclose(file);

    CHK(verify_ascii(string_view(buf, file_size)));

    n_token = 0;

    line_pos[n_line = 1] = 0;
    for (int i = 1; i < file_size; i++) {
        if (buf[i - 1] == '\n') { line_pos[++n_line] = i; }
    }
    line_pos[n_line + 1] = file_size;
    return true;
}

pair<int, int> find_ln_col(int pos) {
    int ln = upper_bound(line_pos + 1, line_pos + n_line + 1, pos) - line_pos - 1;
    int col = pos - line_pos[ln] + 1;
    return {ln, col};
}

bool ascii_isspace(int ch) { return elem_in(ch, {' ', '\t', '\r', '\n'}); }
bool ascii_isdigit(int ch) { return ch >= '0' && ch <= '9'; }
bool ascii_isalpha(int ch) { return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'); }

bool tokenize() {
    auto char_category = [](int ch) {
        if (!ch) return 0;
        if (ascii_isspace(ch)) return 1;
        if (ascii_isdigit(ch)) return 2;
        if (ascii_isalpha(ch) || ch == '_') return 3;
        return 4;
    };

    auto append_token = [](int pos, int len, TokenType type, int data) {
        assert(len >= 0 && pos >= 0 && pos + len <= file_size);
        auto [ln, col] = find_ln_col(pos);
        tokens[++n_token] = {pos, len, ln, col, type, string_view(buf + pos, len), data, 0, 0, 0};
    };

    for (int i = 0; i < file_size;) {
        int ch = buf[i];
        int a = char_category(ch);
        if (a == 1) {
#if 0
            if (ch == '\n') append_token(i, 1, TK_NL, 0);
#endif
            i++;
            continue;
        }
        if (a == 4) {
            if (ch == '/' && buf[i + 1] == '/') {
                int l = i;
                while (buf[i] && buf[i] != '\n') i++;
                append_token(l, i - l, TK_COMMENT, 0);
                i++;
                continue;
            }
            if (ch == '/' && buf[i + 1] == '*') {
                int l = i;
                while (buf[i] && (buf[i] != '*' || buf[i + 1] != '/')) i++;
                i += 2;
                append_token(l, i - l, TK_COMMENT, 0);
                continue;
            }
            if (ch == '\'') {
                i++;
                int l = i;
                while (buf[i] && !(buf[i] == '\'' && (buf[i - 1] != '\\' || (i >= 2 && buf[i - 2] == '\\')))) i++;
                CHK(buf[i] == '\'');
                append_token(l, i - l, TK_STR, 0);
                i++;
                continue;
            }
            if (ch == '\"') {
                if (i > 0 && buf[i - 1] == 'R') {
                    int l = i;
                    i++;
                    auto p = strchr(buf + i, '(');
                    CHK(p);
                    snprintf(tmp, BUFFER_SIZE, ")%.*s\"", int(p - (buf + i)), buf + i);
                    i = p + 1 - buf;
                    p = strstr(buf + i, tmp);
                    CHK(p);
                    i = p + strlen(tmp) - buf;
                    append_token(l, i - l, TK_STR, 0);
                    continue;
                } else {
                    int l = i;
                    i++;
                    while (buf[i] && !(buf[i] == '\"' && (buf[i - 1] != '\\' || (i >= 2 && buf[i - 2] == '\\')))) i++;
                    CHK(buf[i] == '\"');
                    i++;
                    append_token(l, i - l, TK_STR, 0);
                    continue;
                }
            }
            append_token(i, 1, TK_SYM, ch);
            i++;
            continue;
        }
        {
            int l = i;
            while (buf[i] && !elem_in(char_category(buf[i]), {1, 4})) i++;
            append_token(l, i - l, TK_WORD, 0);
            continue;
        }
    }
    append_token(file_size, 0, TK_EOF, 0);
    return true;
}

bool _do_build_token_tree(int& p, bool toplvl) {
    int to_match = -1;
    if (!toplvl) {
        auto x = tokens[p++];
        assert(x.type == TK_SYM);
        switch (x.data) {
        case '(': to_match = ')'; break;
        case '[': to_match = ']'; break;
        case '{': to_match = '}'; break;
        default: assert(0);
        }
    }
    int prv = 0;
    while (true) {
        auto& x = tokens[p];
        if (prv) tokens[prv].next = p;
        prv = p, p++;
        if (x.type == TK_EOF) {
            if (toplvl) return true;
            else return false;
        }
        if (x.type == TK_SYM) {
            if (x.data == to_match) return true;
            switch (x.data) {
            case ')':
            case ']':
            case '}': debug_break_or_exit(); return false;  // Unmatched
            case '(':
            case '[':
            case '{':
                p--;
                tokens[prv].child = p + 1;
                if (!_do_build_token_tree(p, false)) return false;
                continue;
            default: break;
            }
        }
    }
}

bool build_token_tree() {
    int p = 1;
    return _do_build_token_tree(p, 1);
}

int main() {
#if defined(_LOCAL_)
//  freopen("in", "r", stdin);
//  freopen("out","w",stdout);
//  freopen("/dev/null","w",stderr);
#else
    freopen("paint.in", "r", stdin);
    freopen("paint.out", "w", stdout);
#endif
    // ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    init("main.cpp");
    assert(tokenize());
    assert(build_token_tree());
    auto f = fopen("out", "w");
    for (int i = 1; i <= n_token; i++) {
        auto x = tokens[i];
        if (x.type != TK_NL)
            fprintf(f, "%d %d %d %d %d\n\t%.*s\n", i, x.ln, x.col, x.next, x.child, PRINTF_STRINGVIEW(x.content));
    }
    fclose(f);
    /*COMMENT*/
}