Problem:
ICPC で良い成績を収めるには修行が欠かせない．うさぎは ICPC で勝ちたいので，今日も修行をすることにした．  今日の修行は，流行りのパズルをすばやく解いて，瞬発力を鍛えようというものである．今日挑戦するのは，色とりどりのタイルが並んでいてそれらを上手く消していくパズルだ  初期状態では，グリッド上のいくつかのマスにタイルが置かれている．各タイルには色がついている．プレイヤーはゲーム開始後，以下の手順で示される操作を何回も行うことができる．    1. タイルが置かれていないマスを 1 つ選択し，そのマスを叩く．   2. 叩いたマスから上に順に辿っていき，タイルが置かれているマスに至ったところでそのタイルに着目する．タイルが置かれているマスがないまま盤面の端に辿り着いたら何にも着目しない．   3. 同様の操作を叩いたマスから下・左・右方向に対して行う．最大 4 枚のタイルが着目されることになる．   4. 着目したタイルの中で同じ色のものがあれば，それらのタイルを盤面から取り除く．同じ色のタイルの組が 2 組あれば，それら両方を取り除く．   5. タイルを取り除いた枚数と同じ値の得点が入る．   6. 着目をやめる．  たとえば，以下のような状況を考えよう．タイルが置かれていないマスはピリオドで，タイルの色はアルファベット大文字で表されている．                 ..A....... .......B.. .......... ..B....... ..A.CC....   ここで上から 2 行目，左から 3 列目のマスを叩く操作を考える．着目することになるタイルは `A` , `B` , `B` の 3 枚であるから，`B` の 2 枚が消えて盤面は以下のようになり，2 点を得る．                 ..A....... .......... .......... .......... ..A.CC....   このパズルはゆっくりしていると時間切れになってしまい，盤面の一部が見えなくなりどのくらい修行が足りなかったのかがわからなくなってしまう． 各色のタイルは 2 枚ずつ置かれているが，それらをすべて消せるとは限らないので，予めプログラムに得点の最大値を計算させておきたい．

Incorrect submission (verdict: Wrong Answer):
import math,string,itertools,fractions,heapq,collections,re,array,bisect,sys,random,time,copy,functools

sys.setrecursionlimit(10**7)
inf = 10**20
eps = 1.0 / 10**10
mod = 10**9+7
dd = [(-1,0),(0,1),(1,0),(0,-1)]
ddn = [(-1,0),(-1,1),(0,1),(1,1),(1,0),(1,-1),(0,-1),(-1,-1)]

def LI(): return [int(x) for x in sys.stdin.readline().split()]
def LI_(): return [int(x)-1 for x in sys.stdin.readline().split()]
def LF(): return [float(x) for x in sys.stdin.readline().split()]
def LS(): return sys.stdin.readline().split()
def I(): return int(sys.stdin.readline())
def F(): return float(sys.stdin.readline())
def S(): return input()
def pf(s): return print(s, flush=True)


def main():
    m,n = LI()
    a = [[c for c in S()] for _ in range(m)]
    ad = collections.defaultdict(list)
    for i in range(m):
        for j in range(n):
            if a[i][j] != '.':
                ad[a[i][j]].append((i,j))
    ps = set(map(tuple,ad.values()))
    f = True
    r = 0
    while f:
        f = False
        for pa,pb in list(ps):
            i1,j1 = pa
            i2,j2 = pb
            if i1 == i2:
                ff = True
                for j in range(min(j1,j2)+1,max(j1,j2)):
                    if a[i1][j] != '.':
                        ff = False
                        break
                if ff:
                    f = True
                    a[i1][j1] = '.'
                    a[i2][j2] = '.'
                    ps.remove((pa,pb))
                    r += 2
            elif j1 == j2:
                ff = True
                for i in range(min(i1,i2)+1,max(i1,i2)):
                    if a[i][j1] != '.':
                        ff = False
                        break
                if ff:
                    f = True
                    a[i1][j1] = '.'
                    a[i2][j2] = '.'
                    ps.remove((pa,pb))
                    r += 2
            else:
                i,j = i1,j2
                ff = True
                for j3 in range(min(j,j2)+1,max(j,j2)):
                    if a[i][j3] != '.':
                        ff = False
                        break
                for i3 in range(min(i,i2)+1,max(i,i2)):
                    if a[i3][j] != '.':
                        ff = False
                        break
                if ff:
                    f = True
                    a[i1][j1] = '.'
                    a[i2][j2] = '.'
                    ps.remove((pa,pb))
                    r += 2
                    continue
                i,j = i2,j1
                ff = True
                for j3 in range(min(j,j1)+1,max(j,j1)):
                    if a[i][j3] != '.':
                        ff = False
                        break
                for i3 in range(min(i,i1)+1,max(i,i1)):
                    if a[i3][j] != '.':
                        ff = False
                        break
                if ff:
                    f = True
                    a[i1][j1] = '.'
                    a[i2][j2] = '.'
                    ps.remove((pa,pb))
                    r += 2

    return r



print(main())



Fixed, accepted submission:
import math,string,itertools,fractions,heapq,collections,re,array,bisect,sys,random,time,copy,functools

sys.setrecursionlimit(10**7)
inf = 10**20
eps = 1.0 / 10**10
mod = 10**9+7
dd = [(-1,0),(0,1),(1,0),(0,-1)]
ddn = [(-1,0),(-1,1),(0,1),(1,1),(1,0),(1,-1),(0,-1),(-1,-1)]

def LI(): return [int(x) for x in sys.stdin.readline().split()]
def LI_(): return [int(x)-1 for x in sys.stdin.readline().split()]
def LF(): return [float(x) for x in sys.stdin.readline().split()]
def LS(): return sys.stdin.readline().split()
def I(): return int(sys.stdin.readline())
def F(): return float(sys.stdin.readline())
def S(): return input()
def pf(s): return print(s, flush=True)


def main():
    m,n = LI()
    a = [[c for c in S()] for _ in range(m)]
    ad = collections.defaultdict(list)
    for i in range(m):
        for j in range(n):
            if a[i][j] != '.':
                ad[a[i][j]].append((i,j))
    ps = set(map(tuple,ad.values()))
    f = True
    r = 0
    while f:
        f = False
        for pa,pb in list(ps):
            i1,j1 = pa
            i2,j2 = pb
            if i1 == i2:
                ff = abs(j1-j2) > 1
                for j in range(min(j1,j2)+1,max(j1,j2)):
                    if a[i1][j] != '.':
                        ff = False
                        break
                if ff:
                    f = True
                    a[i1][j1] = '.'
                    a[i2][j2] = '.'
                    ps.remove((pa,pb))
                    r += 2
            elif j1 == j2:
                ff = abs(i1-i2) > 1
                for i in range(min(i1,i2)+1,max(i1,i2)):
                    if a[i][j1] != '.':
                        ff = False
                        break
                if ff:
                    f = True
                    a[i1][j1] = '.'
                    a[i2][j2] = '.'
                    ps.remove((pa,pb))
                    r += 2
            else:
                i,j = i1,j2
                ff = a[i][j] == '.'
                for j3 in range(min(j,j1)+1,max(j,j1)):
                    if a[i][j3] != '.':
                        ff = False
                        break
                for i3 in range(min(i,i2)+1,max(i,i2)):
                    if a[i3][j] != '.':
                        ff = False
                        break
                if ff:
                    f = True
                    a[i1][j1] = '.'
                    a[i2][j2] = '.'
                    ps.remove((pa,pb))
                    r += 2
                    continue

                i,j = i2,j1
                ff = a[i][j] == '.'
                for j3 in range(min(j,j2)+1,max(j,j2)):
                    if a[i][j3] != '.':
                        ff = False
                        break
                for i3 in range(min(i,i1)+1,max(i,i1)):
                    if a[i3][j] != '.':
                        ff = False
                        break
                if ff:
                    f = True
                    a[i1][j1] = '.'
                    a[i2][j2] = '.'
                    ps.remove((pa,pb))
                    r += 2

    return r



print(main())