/* Notas Emoji — C17 reference solution, Diogo Peralta Cordeiro.
 * Decode Unicode scalar values explicitly; no locale or wide-character API.
 * O(input bytes + output bytes) time, O(students * maximum name length) space.
 */
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

enum { MAX_STUDENTS = 10000, MAX_NAME = 80, MAX_LINE = 4096 };
typedef struct { char name[MAX_NAME + 1]; int grade; } Student;
static Student students[MAX_STUDENTS];

static int scalar(const unsigned char *s, size_t n, size_t *at, uint32_t *cp) {
    if (*at == n) return 0;
    unsigned char first = s[(*at)++];
    int extra;
    uint32_t minimum;
    if (first < 0x80) { *cp = first; return 1; }
    if (first >= 0xc2 && first <= 0xdf) { extra = 1; *cp = first & 31u; minimum = 0x80; }
    else if (first >= 0xe0 && first <= 0xef) { extra = 2; *cp = first & 15u; minimum = 0x800; }
    else if (first >= 0xf0 && first <= 0xf4) { extra = 3; *cp = first & 7u; minimum = 0x10000; }
    else return 0;
    while (extra--) {
        if (*at == n || (s[*at] & 0xc0u) != 0x80u) return 0;
        *cp = (*cp << 6) | (s[(*at)++] & 63u);
    }
    return *cp >= minimum && *cp <= 0x10ffff && !(*cp >= 0xd800 && *cp <= 0xdfff);
}

static int decode(const unsigned char *s, size_t n, char *out) {
    uint32_t code[MAX_LINE]; size_t count = 0, at = 0, used = 0;
    while (at < n) { if (!scalar(s, n, &at, &code[count])) return 0; ++count; }
    for (size_t i = 0; i < count; ++i) {
        uint32_t cp = code[i]; char letter = 0; int special = 0;
        if (cp >= 0x1f1e6 && cp <= 0x1f1ff) letter = (char)('A' + cp - 0x1f1e6);
        else if ((cp >= 'A' && cp <= 'Z') || cp == ' ') letter = (char)cp;
        else if (cp >= '0' && cp <= '9') {
            letter = (char)cp;
            if (i + 1 < count && code[i + 1] == 0xfe0f) {
                if (i + 2 >= count || code[i + 2] != 0x20e3) return 0;
                i += 2;
            } else if (i + 1 < count && code[i + 1] == 0x20e3) ++i;
        } else {
            switch (cp) {
                case 0x1f170: letter = 'A'; break;
                case 0x1f171: letter = 'B'; break;
                case 0x24c2: letter = 'M'; break;
                case 0x1f17e: letter = 'O'; break;
                case 0x1f17f: letter = 'P'; break;
                default: return 0;
            }
            special = 1;
        }
        if (special && i + 1 < count && code[i + 1] == 0xfe0f) ++i;
        out[used++] = letter;
    }
    out[used] = '\0'; return 1;
}

static int invalid(void) { fputs("Invalid grade sheet\n", stderr); return EXIT_FAILURE; }

int main(void) {
    unsigned char raw[MAX_LINE]; char line[MAX_LINE + 1];
    size_t total = 0, width = 4; int header = 0, trailing_blank = 0, c;
    while ((c = getchar()) != EOF) {
        size_t n = 0;
        do {
            if (c == '\n') break;
            if (n == MAX_LINE) return invalid();
            raw[n++] = (unsigned char)c;
        } while ((c = getchar()) != EOF);
        if (c == '\n' && n && raw[n - 1] == '\r') --n;
        if (!decode(raw, n, line)) return invalid();
        size_t len = strlen(line), untrimmed = len;
        while (len && line[len - 1] == ' ') line[--len] = '\0';
        if (!len) { if (header) trailing_blank = 1; continue; }
        if (trailing_blank || untrimmed - len > 16) return invalid();
        char *sep = strstr(line, "  ");
        if (!sep) return invalid();
        char *value = sep; while (*value == ' ') ++value;
        if (value - sep > 32) return invalid();
        *sep = '\0';
        if (!header) {
            if (strcmp(line, "NOME") || strcmp(value, "NOTA")) return invalid();
            header = 1; continue;
        }
        size_t name_len = strlen(line), digits = strlen(value);
        if (!name_len || name_len > MAX_NAME || total == MAX_STUDENTS || line[0] == ' ' || line[name_len - 1] == ' ') return invalid();
        for (size_t i = 0; i < name_len; ++i) if (line[i] != ' ' && (line[i] < 'A' || line[i] > 'Z')) return invalid();
        if (digits < 1 || digits > 2) return invalid();
        int grade = 0;
        for (size_t i = 0; i < digits; ++i) { if (value[i] < '0' || value[i] > '9') return invalid(); grade = grade * 10 + value[i] - '0'; }
        if (grade > 20) return invalid();
        strcpy(students[total].name, line); students[total++].grade = grade;
        if (name_len > width) width = name_len;
    }
    if (ferror(stdin) || !header || !total) return invalid();
    printf("%-*s  NOTA\n", (int)width, "NOME");
    for (size_t i = 0; i < total; ++i) printf("%-*s  %d\n", (int)width, students[i].name, students[i].grade);
    puts("Cumprimentos algorítmicos!");
    return ferror(stdout) ? EXIT_FAILURE : EXIT_SUCCESS;
}
