#!/usr/bin/python

(nRows,nCols) = map(int,raw_input().split())

sqList = []

bldg = []
inUse = []
for r in xrange(nRows):
    bldg.append(list(raw_input()))
    inUse.append([])
    for c in xrange(nCols):
        inUse[r].append(False)

def trySquare(r,c):
    # skip rocks
    while True:
        if r == nRows:
            break
        if bldg[r][c] != '#':
            break
        c += 1
        if c == nCols:
            c = 0
            r += 1

#    print "trying",r,c
    if r == nRows:
        for s in xrange(len(sqList)):
            for y in xrange(sqList[s][2]):
                for x in xrange(sqList[s][2]):
                    bldg[sqList[s][0]+y][sqList[s][1]+x] = \
                    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"[s]
        for line in bldg:
            print ''.join(line)

        return True

    sqList.append([r,c,0])

    sq = sqList[len(sqList)-1]

    # get smallest valid size
    isBad = False
    while True:
        # increment square size
        sq[2] += 1
        # check for in bounds
        if sq[0] + sq[2] - 1 == nRows or sq[1] + sq[2] - 1 == nCols:
            isBad = True
            break
        # count treasure and look for rocks
        nTreasure = 0
        for y in xrange(sq[2]):
            for x in xrange(sq[2]):
                if bldg[sq[0]+y][sq[1]+x] == '#':
                    isBad = True
                if bldg[sq[0]+y][sq[1]+x] == '$':
                    nTreasure += 1
                if inUse[sq[0]+y][sq[1]+x]:
                    isBad = True

        if nTreasure > 1:
            isBad = True
            break

        if nTreasure == 1 or isBad:
            break

    # no square works here, backtrack
    if isBad:
#        print "no size works"
        del sqList[-1]
        return False

    # try all valid square sizes
    while True:
        # check for in bounds
        if sq[0] + sq[2] - 1 == nRows or sq[1] + sq[2] - 1 == nCols:
            break
        # count treasure and look for rocks
        nTreasure = 0
        for y in xrange(sq[2]):
            for x in xrange(sq[2]):
                if bldg[sq[0]+y][sq[1]+x] == '#':
                    isBad = True
                if bldg[sq[0]+y][sq[1]+x] == '$':
                    nTreasure += 1
                if inUse[sq[0]+y][sq[1]+x]:
                    isBad = True

        if nTreasure > 1 or isBad:
            break

        # mark square in use
        for y in xrange(sq[2]):
            for x in xrange(sq[2]):
                inUse[sq[0]+y][sq[1]+x] = True

        # look for next square location
        y = r
        x = c + sq[2]
        if x == nCols:
            x = 0
            y += 1
        while True:
            if y == nRows:
                break
            isBad = False
            for s in sqList:
                if y >= s[0] and y < s[0] + s[2] and x >= s[1] and x < s[1] + s[2]:
                    isBad = True
                    break

            if bldg[y][x] == '#':
                isBad = True

            if not isBad:
                break

            x += 1
            if x == nCols:
                x = 0
                y += 1

#        print "size",sq[2]
        result = trySquare(y,x)
        if result:
            return True

        # mark square not in use
        for y in xrange(sq[2]):
            for x in xrange(sq[2]):
                inUse[sq[0]+y][sq[1]+x] = False

        # increment square size
        sq[2] += 1

    # no more choices, backtrack
#    print "out of choices"
    del sqList[-1]
    return False

result = trySquare(0,0)
if not result:
    print "elgnatcer"
