#include<bits/stdc++.h>
using namespace std;
 
#define ff              first
#define ss              second
#define int             long long
#define pb              push_back
#define pii             pair<int,int>
#define vi              vector<int>
#define mii             map<int,int>
#define pqb             priority_queue<int>
#define pqs             priority_queue<int,vi,greater<int> >
#define setbits(x)      __builtin_popcountll(x)
#define zrobits(x)      __builtin_ctzll(x)
#define mod             1000000007
#define inf             1e18
#define ps(x,y)         cout<<setprecision(y)<<x
#define mk(arr,n,type)  type *arr=new type[n];
#define w(x)            int x; cin>>x; while(x--)
#define pw(b,p)         pow(b,p) + 0.1
#define endl            "\n"
mt19937                 rng(chrono::steady_clock::now().time_since_epoch().count());


void __print(int32_t x) {cerr << x;}
void __print(long x) {cerr << x;}
void __print(long long x) {cerr << x;}
void __print(unsigned x) {cerr << x;}
void __print(unsigned long x) {cerr << x;}
void __print(unsigned long long x) {cerr << x;}
void __print(float x) {cerr << x;}
void __print(double x) {cerr << x;}
void __print(long double x) {cerr << x;}
void __print(char x) {cerr << '\'' << x << '\'';}
void __print(const char *x) {cerr << '\"' << x << '\"';}
void __print(const string &x) {cerr << '\"' << x << '\"';}
void __print(bool x) {cerr << (x ? "true" : "false");}

template<typename T, typename V>
void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ','; __print(x.second); cerr << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";}
void _print() {cerr << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}
#ifndef ONLINE_JUDGE
#define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
#define debug(x...)
#endif
 
char myHeap[200 * 1024 * 1024];
int sz = 0;
void assert_tle(bool q) { while (!q); }
void* operator new  ( std::size_t count ) {
    sz += count;
    assert_tle(sz <= 200 * 1024 * 1024);
    return myHeap + sz - count;
}
 
void operator delete (void *ptr) { }
 
 
void fastIO()
{
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
}

struct djsets
{
    vector<int> leader;
    vector<int> rank;

    void init(int n)
    {
        rank.assign(n,1);
        for(int i=0;i<n;i++)
        {
            leader.push_back(i);
        }
    }

    int retleader(int node)
    {
        if(leader[node]==node)
            return node;
        int p= retleader(leader[node]);
        leader[node]=p;

        return p;
    }
    void connect(int a,int b)
    {
        a=retleader(a);
        b=retleader(b);

        if(rank[a]>rank[b])
        {
            leader[b]=a;
        }
        else if(rank[b]>rank[a])
        {
            leader[a]=b;
        }
        else
        {
            leader[b]=a;
            rank[a]++;
        }
    }

    int retans()
    {
        int ans=0;
        for(int i=0;i<leader.size();i++)
            if(leader[i]==i&&rank[i]>1) ans++;

        return ans-1;
    }
};



void solve()
{
    int h,w;
    cin>>h>>w;

    string str[h];

    for(int i=0;i<h;i++)
    {
        cin>>str[i];
    }

    str[0][0]=str[h-1][0]=str[h-1][w-1]=str[0][w-1]='#';

    djsets d;
    d.init(h+w);

    for(int i=0;i<h;i++)
    {
        for(int j=0;j<w;j++)
        {
            if(str[i][j]=='#')
            {
                d.connect(i,h+j);
            }
        }
    }

    int rows=0,col=0;

    for(int i=0;i<h;i++)
    {
        if(d.rank[d.retleader(i)]==1) rows++;
    }
    for(int i=h;i<h+w;i++)
    {
        if(d.rank[d.retleader(i)]==1) col++;
    }
    cout<<d.retans()+min(rows,col);

}
 
int32_t main()
{
    fastIO();
    //w(t)
    {
        solve();
        cout<<endl;
    }
    return 0;
}
// Artur Kraska, II UWr

#include <bits/stdc++.h>

#define forr(i, n)                  for(int i=0; i<n; i++)
#define FOREACH(iter, coll)         for(auto iter = coll.begin(); iter != coll.end(); ++iter)
#define FOREACHR(iter, coll)        for(auto iter = coll.rbegin(); iter != coll.rend(); ++iter)
#define lbound(P,R,PRED)            ({typeof(P) X=P,RRR=(R), PPP = P; while(PPP<RRR) {X = (PPP+(RRR-PPP)/2); if(PRED) RRR = X; else PPP = X+1;} PPP;})
#define testy()                     int _tests; scanf("%d", &_tests); FOR(_test, 1, _tests)
#define CLEAR(tab)                  memset(tab, 0, sizeof(tab))
#define CONTAIN(el, coll)           (coll.find(el) != coll.end())
#define FOR(i, a, b)                for(int i=a; i<=b; i++)
#define FORD(i, a, b)               for(int i=a; i>=b; i--)
#define MP                          make_pair
#define PB                          push_back
#define ff                          first
#define ss                          second
#define deb(X)                      X;

#define M 1000000007
#define INF 1000000007LL

using namespace std;

int n, m, a;
char slowo[1007][1007];
int o[1000007], byl[1000007];

int Find(int nr)
{
    if(o[nr] < 0)
        return nr;
    o[nr] = Find(o[nr]);
    return o[nr];
}

void Union(int a, int b)
{
    a = Find(a);
    b = Find(b);
    if(a != b)
        o[a] = b;
}

int solve()
{
    forr(i, n+5)
    {
        o[i] = -1;
        byl[i] = 0;
    }
    Union(0, n-1);

    FOR(i, 1, n-2)
        if(slowo[i][0] == '#' || slowo[i][m-1] == '#')
            Union(i, 0);


    FOR(j, 1, m-2)
    {
        int last = -1;
        FOR(i, 0, n-1)
            if(slowo[i][j] == '#')
            {
                if(last != -1)
                {
                    Union(last, i);
                }
                last = i;
            }
    }

    byl[Find(0)] = 1;
    int res = 0;
    FOR(i, 0, n-1)
    {
        int x = Find(i);
        if(!byl[x])
        {
            byl[x] = 1;
            res++;
        }
    }

    return res;
}

int main()
{
    scanf("%d %d", &n, &m);
    forr(i, n)
    {
        scanf("%s", slowo[i]);
    }

    int x = solve();
    swap(n, m);

    FOR(i, 0, max(n, m))
        FOR(j, 0, i-1)
        {
            swap(slowo[i][j], slowo[j][i]);
        }

    int y = solve();

    printf("%d\n", min(x, y));

    return 0;
}
