#!/usr/bin/env python3

import os, os.path
import sys

from typing import *

def writebinat(dest: bytearray, src: bytes, off: int):
    for i in range(0, len(src)): dest[off + i] = src[i]

def calcsum_hdr_cgb(data: bytearray, start: int, end: int) -> int:
    x = 0
    for i in range(start, end+1): x = (x - data[i] - 1) & 0xFF
    return x

def calcsum_gba(data: bytearray, start: int, end: int) -> int:
    r = 0
    for i in range(start, end+1):
        r = r - data[i]
        r = (r - 0x19) & 0xFF
    return r

def calcsum_nds(data: bytearray, start: int, end: int) -> int:
    coeffs = [0xC0C1,0xC181,0xC301,0xC601,0xCC01,0xD801,0xF001,0xA001]
    crc = 0xFFFF
    for i in range(start, end):
        crc = crc ^ data[i]
        for j in range(8):
            carry = (crc & 1) != 0
            crc = crc >> 1
            if carry:
                crc = crc ^ (coeffs[j] << (7-j))
    return crc & 0xFFFF

def shred(data: bytearray) -> bytearray:
    while data[-1] == 0: del data[-1]

    return data

data = bytearray(sys.stdin.buffer.read())

#imghdr = open('./nintendo.bin', 'rb').read()
#print('%04X'%calcsum(imghdr, 0, len(imghdr)))
#assert calcsum(imghdr, 0, len(imghdr)) == 0xCF56

data[0xB2] = 0x96

cgbcs = calcsum_hdr_cgb(data, 0x134, 0x14C)
data[0x14D] = cgbcs

logcs = calcsum_nds(data, 0x0C0, 0x15C)
data[0x15C] =  logcs    &0xFF
data[0x15D] = (logcs>>8)&0xFF

gbacs = calcsum_gba(data, 0xA0, 0xBC)
data[0xBD] = 0 # gbacs # XXX

crc  = calcsum_nds(data, 0x000, 0x15E)
data[0x15E] =  crc    &0xFF
data[0x15F] = (crc>>8)&0xFF

data = shred(data)

assert data[0xB2] == 0x96 # GBA header thing

sys.stdout.buffer.write(data)

