#define rep(i,n) for (int i=0;i<n;i++)
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
 

int main() {
  ll h,w,co=0;
  cin >> h >> w;
  vector <vector <char>>s(h,vector<char>(w));
  rep(i,h){
    rep(j,w){
           cin >> s.at(i).at(j);
    }
  }
  
  //cout << 1 << endl;
  rep(i,h){
    rep(j,w-1){
      if(s.at(i).at(j)=='.' && s.at(i).at(j+1)=='.'){
      	co++;
      }      
    }
  }
 // cout << 1 << endl;
  
  rep(i,w){
    rep(j,h-1){
      if(s.at(j).at(i)=='.' && s.at(j+1).at(i)=='.'){
      	co++;
      }      
    }
  }
  cout << co << endl;
}
#include <unordered_map>
#include <unordered_set>
#include <algorithm>
#include <iostream>
#include <iostream>
#include <fstream>
#include <numeric>
#include <cstring>
#include <cassert>
#include <string>
#include <vector>
#include <queue>
#include <deque>
#include <cmath>
#include <set>
#include <map>
#include <functional>
#include <bitset>
#include <iomanip>
#include <stack>
#include <list>
#include <cstdint>
#include <chrono>
#include <hash_map>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>

using namespace __gnu_pbds;
using namespace std;

#define     lp(i,a,n)       for(ll i=a;i<n;i++)
#define     lp2(i,n,a)      for(ll i=a-1;i>=n;i--)
#define     all(arr,n)      arr,arr+n
#define     allv(v)         (v).begin(),(v).end()
#define     rallv(v)        (v).rbegin(),(v).rend()
#define     m_p             make_pair
#define     ll              long long
#define     pii             pair<int,int>
#define     vi              vector<int>
#define     vll             vector<ll>
#define     vii             vector<pii>
#define     sz(x)           (int)x.size()
#define     pb              push_back
#define     endl            '\n'
#define     Endl            '\n'
#define     f               first
#define     s               second
#define     mem(dp,n)       memset(dp,n,sizeof dp)
#define     ordered_set     tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update>
template<typename T>void max_self(T &a,T b){a=max(a,b);}
template<typename T>void min_self(T &a,T b){a=min(a,b);}
int dx[] = { 1 , 0 ,-1 , 0 ,-1 ,-1 , 1 , 1 };
int dy[] = { 0 , 1 , 0 ,-1 ,-1 , 1 ,-1 , 1 };
int KnightX[] = { 2, 1, -1, -2, -2, -1, 1, 2 };
int KnightY[] = { 1, 2, 2, 1, -1, -2, -2, -1 };
void fast(){
    std::ios_base::sync_with_stdio(0);
    cin.tie(NULL);
    cout.tie(NULL);
}
vector<string> vec_splitter(string s) {
    s += ',';
    vector<string> res;
    while(!s.empty()) {
        res.push_back(s.substr(0, s.find(',')));
        s = s.substr(s.find(',') + 1);
    }
    return res;
}
void debug_out(
        vector<string> __attribute__ ((unused)) args,
        __attribute__ ((unused)) int idx,
        __attribute__ ((unused)) int LINE_NUM) { cerr << endl; }
template <typename Head, typename... Tail>
void debug_out(vector<string> args, int idx, int LINE_NUM, Head H, Tail... T) {
    if(idx > 0) cerr << ", "; else cerr << "Line(" << LINE_NUM << ") ";
    stringstream ss; ss << H;
    cerr << args[idx] << " = " << ss.str();
    debug_out(args, idx + 1, LINE_NUM, T...);
}
#define debug(...) debug_out(vec_splitter(#__VA_ARGS__), 0, __LINE__, __VA_ARGS__)
const ll mxN=1e6+1,oo=0x3f3f3f3f,MOD=998244353;
const long double PI = acos(-1),eps=1e-9;

void solve(){
    int h,w;
    cin>>h>>w;
    char grid[h][w];
    lp(i,0,h){
        lp(j,0,w)
            cin>>grid[i][j];
    }
    int res=0;
    lp(i,0,h){
        lp(j,0,w){
            if(grid[i][j]!='.')continue;
            lp(k,0,4){
                int ti=i+dx[k],tj=j+dy[k];
                if(ti>=0&&ti<h&&tj>=0&&tj<w&&grid[ti][tj]=='.')
                    res++;
            }
        }
    }
    cout<<res/2<<endl;
}
int main() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif
    fast();
    int t=1;
    //cin>>t;
    while(t--)
        solve();
    return 0;
}
