import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.nio.charset.StandardCharsets;

public class UnicodeInputStreamReader {
   public static void main(String[] args) {

      // Explicitly enforce UTF-8 encoding on the standard output stream
      System.setOut(new PrintStream(System.out, true, StandardCharsets.UTF_8));

      // Explicitly enforce UTF-8 decoding on the standard input stream
      try (BufferedReader reader = new BufferedReader(
                new InputStreamReader(System.in, StandardCharsets.UTF_8))) {
            
         int charCode;
         // read() returns -1 when the end of the stream is reached
         while ((charCode = reader.read()) != -1) {
               final char ch = (char) charCode;
               int codePoint = ch;

               // Handle UTF-16 Surrogate Pairs (Supplementary Characters)
               if (Character.isHighSurrogate(ch)) {
                  final int nextCharCode = reader.read();
                  if (nextCharCode != -1) {
                     final char nextCh = (char) nextCharCode;
                     if (Character.isLowSurrogate(nextCh)) {
                        codePoint = Character.toCodePoint(ch, nextCh);
                     }
                  }
               }

               // 1. Get the Unicode Hex Code Point
               String codePointHex = String.format("U+%04X", codePoint);

               // 2. Get the Official Character Name
               String name = Character.getName(codePoint);
               if (name == null) {
                    name = "UNNAMED_CHARACTER";
                }

                // 3. Get the Unicode Code Block
                Character.UnicodeBlock block = Character.UnicodeBlock.of(codePoint);
                String blockName = (block != null) ? block.toString() : "UNKNOWN_BLOCK";

                // 4. Handle rendering glyph text safely
                String glyph = new String(Character.toChars(codePoint));
                if (Character.isISOControl(codePoint)) {
                    glyph = " ";
                }

                // Print out clean, formatted columns
                System.out.printf("%-3s | %-7s | %-35s | %s%n", 
                                  glyph, codePointHex, name, blockName); 
         }

      } catch (final IOException e) {
         System.err.println("Error reading from standard input: " + e.getMessage());
      }
   }
}