#include <bits/stdc++.h>
using namespace std;
#define SZ(x) (int)(x.size())
#define REP(i, n) for(int i=0;i<(n);++i)
#define FOR(i, a, b) for(int i=(a);i<(b);++i)
#define RREP(i, n) for(int i=(int)(n)-1;i>=0;--i)
#define RFOR(i, a, b) for(int i=(int)(b)-1;i>=(a);--i)
#define ALL(a) a.begin(),a.end()
#define DUMP(x) cerr<<#x<<" = "<<(x)<<endl
#define DEBUG(x) cerr<<#x<<" = "<<(x)<<" (L"<<__LINE__<<")"<< endl;
using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using P = pair<int, int>;
const double eps = 1e-8;
const ll MOD = 1000000007;
const int INF = INT_MAX / 2;
const ll LINF = LLONG_MAX / 2;
template <typename T1, typename T2>
bool chmax(T1 &a, const T2 &b) {
    if (a < b) { a = b; return true; }
    return false;
}
template <typename T1, typename T2>
bool chmin(T1 &a, const T2 &b) {
    if (a > b) { a = b; return true; }
    return false;
}
template<typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p) {
    os << p.first << ":" << p.second;
    return os;
}
template<typename T1, typename T2>
ostream &operator<<(ostream &os, const map<T1, T2> &mp) {
    os << "{";
    int a = 0;
    for (auto &tp : mp) {
        if (a) os << ", "; a = 1;
        os << tp;
    }
    return os << "}";
}
template<typename T>
ostream &operator<<(ostream &os, const vector<T> &v) {
    os << "[";
    REP(i, SZ(v)) {
        if (i) os << ", ";
        os << v[i];
    }
    return os << "]";
}


int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(10);


    int M, N; cin >> M >> N;
    vector<string> C(M);
    REP(i, M) {
        cin >> C[i];
    }

    int ans = 0;
    for (bool updated = true; updated;) {
        updated = false;
        REP(c, 26) {
            vector<P> ps;
            REP(i, M) REP(j, N) if (C[i][j] == c + 'A') ps.emplace_back(i, j);
            if (ps.size() == 0) continue;
            int si, sj, ti, tj;
            tie(si, sj) = ps[0], tie(ti, tj) = ps[1];

            bool valid = true;
            if (si == ti) {
                if (abs(sj - tj) == 1) valid = false;
                FOR(j, min(sj, tj)+1, max(sj, tj)) {
                    if (C[si][j] != '.') valid = false;
                }
            }
            else if (sj == tj) {
                if (abs(si - ti) == 1) valid = false;
                FOR(i, min(si, ti)+1, max(si, ti)) {
                    if (C[i][sj] != '.') valid = false;
                }
            }
            else {
                valid = false;
                {
                    bool v = true;
                    if (C[si][tj] != '.') v = false;
                    FOR(i, min(si, ti) + 1, max(si, ti)) {
                        if (C[i][tj] != '.') v = false;
                    }
                    FOR(j, min(sj, tj) + 1, max(sj, tj)) {
                        if (C[si][j] != '.') v = false;
                    }
                    if (v) valid = true;
                }
                {
                    bool v = true;
                    if (C[ti][sj] != '.') v = false;
                    FOR(i, min(si, ti) + 1, max(si, ti)) {
                        if (C[i][sj] != '.') v = false;
                    }
                    FOR(j, min(sj, tj) + 1, max(sj, tj)) {
                        if (C[ti][j] != '.') v = false;
                    }
                    if (v) valid = true;
                }
            }
            if (valid) {
                C[si][sj] = C[ti][tj] = '.';
                updated = true;
                ans += 2;
                break;
            }
        }
    }

    cout << ans << endl;

    return 0;
}



Measured memory_bytes: 3364