Problem:
改元

平成31年4月30日をもって現行の元号である平成が終了し，その翌日より新しい元号が始まることになった．平成最後の日の翌日は新元号元年5月1日になる．

ACM-ICPC OB/OGの会 (Japanese Alumni Group; JAG) が開発するシステムでは，日付が和暦（元号とそれに続く年数によって年を表現する日本の暦）を用いて "平成 y 年 m 月 d 日" という形式でデータベースに保存されている．この保存形式は変更することができないため，JAGは元号が変更されないと仮定して和暦で表した日付をデータベースに保存し，出力の際に日付を正しい元号を用いた形式に変換することにした．

あなたの仕事はJAGのデータベースに保存されている日付を，平成または新元号を用いた日付に変換するプログラムを書くことである．新元号はまだ発表されていないため，"?" を用いて表すことにする．

Input

入力は複数のデータセットからなる．各データセットは次の形式で表される．

g y m d

g は元号を表す文字列であり， g=HEISEI が成り立つ．y, m, d は整数であり，それぞれ年，月，日を表す．1 ≤ y ≤ 100, 1 ≤ m ≤ 12, 1 ≤ d ≤ 31 が成り立つ．

2月30日などの和暦に存在しない日付はデータセットとして与えられない．和暦として正しく変換したときに，平成よりも前の元号を用いる必要がある日付もデータセットとして与えられない．

入力の終わりは '#' 一つのみからなる行であらわされる．データセットの個数は 100 個を超えない．

Output

各データセットについて，変換後の元号，年，月，日を空白で区切って 1 行に出力せよ．変換後の元号が "平成" である場合は "HEISEI" を元号として用い，新元号であれば "?" を用いよ．

通常，元号の第 1 年目は元年と表記するが，本問題の出力ではこの規則を無視し，1 を年として出力せよ．

Sample Input

HEISEI 1 1 8
HEISEI 31 4 30
HEISEI 31 5 1
HEISEI 99 12 31
HEISEI 38 8 30
HEISEI 98 2 22
HEISEI 2 3 26
HEISEI 28 4 23
#

Output for the Sample Input

HEISEI 1 1 8
HEISEI 31 4 30
? 1 5 1
? 69 12 31
? 8 8 30
? 68 2 22
HEISEI 2 3 26
HEISEI 28 4 23

Solution in C# (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace _2881
{
    public class Program

    {
        const string NEW_ERA_NAME = "?";

        public static void Main(string[] args)
        {
            while (true)
            {
                string[] line = ReadStAr();
                if (line[0] == "#") break;
                string eraName = (int.Parse(line[1]+ line[2].PadLeft(2, '0')) < 3105) ? line[0] : NEW_ERA_NAME;
                string newYear = (eraName == line[0]) ? line[1] : (int.Parse(line[1]) - 30).ToString();
                Console.WriteLine("{0} {1} {2} {3}",eraName, newYear, line[2],line[3]);
            }  
        }

        static string ReadSt() { return Console.ReadLine(); }
        static int ReadInt() { return int.Parse(Console.ReadLine()); }
        static long ReadLong() { return long.Parse(Console.ReadLine()); }
        static double ReadDouble() { return double.Parse(Console.ReadLine()); }
        static string[] ReadStAr(char sep = ' ') { return Console.ReadLine().Split(sep); }
        static int[] ReadIntAr(char sep = ' ') { return Array.ConvertAll(Console.ReadLine().Split(sep), e => int.Parse(e)); }
        static long[] ReadLongAr(char sep = ' ') { return Array.ConvertAll(Console.ReadLine().Split(sep), e => long.Parse(e)); }
        static double[] ReadDoubleAr(char sep = ' ') { return Array.ConvertAll(Console.ReadLine().Split(sep), e => double.Parse(e)); }

    }

}