#include <bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
using namespace std;
// using namespace __gnu_pbds;
// template <typename T>
// using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
#define int long long
#define pb push_back
#define eb emplace_back
#define pf push_front
#define ppb pop_back
#define ppf pop_front
#define ins insert
#define ff first
#define ss second
// mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
constexpr int inf = 1e15, mod = 998244353, maxn = 1000005;
void solve(){
int n, m;
cin >> n >> m;
vector<string> a(n);
for (auto& s: a){
cin >> s;
}
int ans=0;
vector<int> b(m);
for (int i=n-1; 0 <= i; --i){
int cur=0;
for (int j=m-1; 0 <= j; --j){
if (a[i][j]=='O'){
cur++;
continue;
}
if (a[i][j]=='J'){
ans += cur*b[j];
}
}
for (int j = m-1; 0 <= j; --j){
b[j]+=(a[i][j]=='I');
}
}
cout << ans << '\n';
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t = 1;
// cin >> t;
for (int i = 0; i < t; i++) {
solve();
}
return 0;
}