#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <climits>
#include <cfloat>
#include <ctime>
#include <map>
#include <utility>
#include <set>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
#include <sstream>
#include <complex>
#include <stack>
#include <queue>

using namespace std;
static const double EPS = 1e-8;
typedef long long ll;

struct Range
{
    Range() : a(-3){}
    Range(int a, int b, int c, int d)
  : a(a), b(b), c(c), d(d){}
    int a, b, c, d;
};
char grid[512][512];

bool all_empty_x(int y, int l, int u)
{
    if (l > u)
        swap(l, u);
    for (int x = l; x <= u; ++x)
        if (grid[y][x] != '.')
            return false;
    return true;
}
bool all_empty_y(int x, int l, int u)
{
    if (l > u)
        swap(l, u);
    for (int y = l; y <= u; ++y)
        if (grid[y][x] != '.')
            return false;
    return true;
}

vector<pair<int, int> > p[26];
int main()
{
    int M, N;
    scanf("%d %d", &M, &N);
    for (int i = 0; i < M; ++i)
        scanf("%s", grid[i]);

    for (int i = 0; i < M; ++i)
        for (int j = 0; j < N; ++j)
            if (grid[i][j] != '.')
                p[grid[i][j]-'A'].push_back(make_pair(j, i));

    Range r[26];
    for (int i = 0; i < 26; ++i)
    {
        if (!p[i].size())
            continue;

        int x1, y1, x2, y2;
        x1 = p[i][0].first;
        y1 = p[i][0].second;
        x2 = p[i][1].first;
        y2 = p[i][1].second;

        if (y1 == y2 && abs(x1-x2) != 1)
            r[i] = Range(-1, y1, min(x1, x2), max(x1, x2));
        else if (x1 == x2 && abs(y1-y2) != 1)
            r[i] = Range(-2, x1, min(y1, y2), max(y1, y2));
        else if (x1 != x2 && y1 != y2)
            r[i] = Range(x1, y1, x2, y2);
    }

    int ans = 0;
    for (bool update = true; update; )
    {
        update = false;
        for (int i = 0; i < 26; ++i)
        {
            if (r[i].a == -3)
                continue;

            if (r[i].a == -1)
            {
                if (all_empty_x(r[i].b, r[i].c+1, r[i].d-1))
                {
                    r[i].a = -3;
                    grid[r[i].b][r[i].c] = grid[r[i].b][r[i].d] = '.';
                    ans += 2;
                    update = true;
                }
            }
            else if (r[i].a == -2)
            {
                if (all_empty_y(r[i].b, r[i].c+1, r[i].d-1))
                {
                    r[i].a = -3;
                    grid[r[i].c][r[i].b] = grid[r[i].d][r[i].b] = '.';
                    ans += 2;
                    update = true;
                }
            }
            else if (r[i].a != -3)
            {
                int x1, y1, x2, y2;
                x1 = r[i].a;
                y1 = r[i].b;
                x2 = r[i].c;
                y2 = r[i].d;
                int x[4], y[4];
                x[0] = x1;
                y[0] = y2;
                x[1] = x2 + (x1 > x2 ? 1 : -1);
                y[1] = y1 + (y2 > y1 ? 1 : -1);
                x[2] = x2;
                y[2] = y1;
                x[3] = x1 + (x2 > x1 ? 1 : -1);
                y[3] = y2 + (y1 > y2 ? 1 : -1);
                if (all_empty_x(y2, x[0], x[1]) && all_empty_y(x1, y[0], y[1])
                    || all_empty_x(y1, x[2], x[3]) && all_empty_y(x2, y[2], y[3]))
                {
                    r[i].a = -3;
                    grid[y1][x1] = grid[y2][x2] = '.';
                    ans += 2;
                    update = true;
                }
            }
        }
    }
    printf("%d\n", ans);

    return 0;
}

Measured memory_bytes: 1448