#!/usr/bin/env python3

import sys
from functools import lru_cache

def main():
    data = sys.stdin.read().strip().splitlines()
    N = int(data[0].strip())
    rows = [list(data[i+1].rstrip("\n")) for i in range(N)]
    W = 2 * N - 1

    # Find pyramid span on each row and prefix counts of mines on that span
    L, R, width, pref = [0]*N, [0]*N, [0]*N, []
    total = 0
    for r in range(N):
        row = rows[r]
        l = 0
        while l < W and row[l] == '#':
            l += 1
        rr = W - 1
        while rr >= 0 and row[rr] == '#':
            rr -= 1
        if l > rr:
            print("Impossible")
            return
        L[r], R[r] = l, rr
        w = rr - l + 1
        width[r] = w
        p = [0] * (w + 1)
        for i, ch in enumerate(row[l:rr+1], start=1):
            p[i] = p[i-1] + (1 if ch == 'C' else 0)
        pref.append(p)
        total += p[w]

    # If total mines odd, impossible
    if total % 2 == 1:
        print("Impossible")
        return
    target = total // 2

    # Trivial zero-mine case
    if total == 0:
        out = []
        for r in range(N):
            line = ['#'] * W
            for k, c in enumerate(range(L[r], R[r]+1)):
                line[c] = 'A' if (r == 0 and k == 0) else 'B'
            out.append(''.join(line))
        print('\n'.join(out))
        return

    # ---------- DP: min/max achievable from row r if row r uses exactly 'a' A-cells ----------
    # Valid transitions (to maintain connectivity for A and B):
    #   Let w = width[r], wnext = width[r+1].
    #   If a == 0: next a' ∈ {0} ∪ [1..w] ∪ {wnext}
    #   If 1 <= a <= w-1: next a' ∈ [max(1, a-1) .. w] ∪ {wnext}
    #   If a == w: next a' = wnext
    #
    # min_suf[r][a] = minimal #mines A can collect from rows r..N-1 with a_r = a
    # max_suf[r][a] = maximal #mines A can collect from rows r..N-1 with a_r = a
    INF = 10**15
    min_suf = [None] * N
    max_suf = [None] * N

    # Base at last row
    min_suf[N-1] = pref[N-1][:]
    max_suf[N-1] = pref[N-1][:]

    for r in range(N-2, -1, -1):
        w = width[r]
        wnext = width[r+1]
        next_min = min_suf[r+1]
        next_max = max_suf[r+1]

        # We need range mins/maxes for indices up to 'w' on the next row.
        # Build suffix min/max limited to indices 0..w.
        suf_min_upto_w = [INF] * (w + 2)
        suf_max_upto_w = [-INF] * (w + 2)
        suf_min_upto_w[w] = next_min[w]
        suf_max_upto_w[w] = next_max[w]
        for k in range(w-1, -1, -1):
            suf_min_upto_w[k] = min(next_min[k], suf_min_upto_w[k+1])
            suf_max_upto_w[k] = max(next_max[k], suf_max_upto_w[k+1])

        v0_min, v0_max = next_min[0], next_max[0]
        full_min, full_max = next_min[wnext], next_max[wnext]

        cur_min = [0] * (w + 1)
        cur_max = [0] * (w + 1)

        for a in range(w + 1):
            here = pref[r][a]
            if a == 0:
                best_min = min(v0_min,
                               suf_min_upto_w[1] if w >= 1 else INF,
                               full_min)
                best_max = max(v0_max,
                               suf_max_upto_w[1] if w >= 1 else -INF,
                               full_max)
            elif a == w:
                best_min = full_min
                best_max = full_max
            else:
                Lb = max(1, a - 1)
                rng_min = suf_min_upto_w[Lb]
                rng_max = suf_max_upto_w[Lb]
                best_min = min(rng_min, full_min)
                best_max = max(rng_max, full_max)

            cur_min[a] = here + best_min
            cur_max[a] = here + best_max

        min_suf[r] = cur_min
        max_suf[r] = cur_max

    # ---------- Backtrack with pruning to hit target exactly ----------
    @lru_cache(maxsize=None)
    def dfs(r, prev_a, remaining):
        if remaining < 0:
            return None
        if r == N:
            return [] if remaining == 0 else None
        w = width[r]

        if r == 0:
            candidates = [a for a in range(w+1)
                          if min_suf[0][a] <= remaining <= max_suf[0][a]]
        else:
            wprev = width[r-1]
            a = prev_a
            if a == 0:
                allowed = [0] + list(range(1, wprev+1)) + [w]
            elif a == wprev:
                allowed = [w]
            else:
                Lb = max(1, a-1)
                allowed = list(range(Lb, wprev+1)) + [w]
            candidates = [x for x in allowed if 0 <= x <= w and
                          min_suf[r][x] <= remaining <= max_suf[r][x]]

        # Small heuristic: prioritize a whose "here" is close to what's needed
        candidates.sort(key=lambda a: abs(pref[r][a] - (remaining - (min_suf[r+1][a] if r+1 < N else 0))))

        for a in candidates:
            res = dfs(r+1, a, remaining - pref[r][a])
            if res is not None:
                return [a] + res
        return None

    a_seq = dfs(0, -1, target)
    if a_seq is None:
        print("Impossible")
        return

    # Build output grid
    out = []
    for r in range(N):
        w = width[r]
        line = ['#'] * W
        a = a_seq[r]
        for k, c in enumerate(range(L[r], R[r]+1)):
            line[c] = 'A' if k < a else 'B'
        out.append(''.join(line))
    print('\n'.join(out))

if __name__ == "__main__":
    main()
