#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
#define LONGMAX 1e14
#define dd double
#define MOD 998244353  
# define my_sizeof(type) ((char *)(&type+1)-(char*)(&type)) 
#define nl cout<<endl
#define fill(a,val) memset(a,val,sizeof(a))
#define rt ll Q[100005]={0}
#define mp make_pair
#define endl "\n"
#define test() ll t;cin>>t;while(t--)
#define pb push_back
#define ff first	
#define ss second
#define all(v) v.begin(),v.end()
#define s(ar,n) sort(ar,ar+n)
#define rs(ar,n) sort(ar, ar+n, greater<ll>()) 
#define oa(a,n) for(ll i=0;i<n;i++)cout<<a[i]<<" ";nl
#define cn(a,n) for(ll i=0;i<n;i++)cin>>a[i];
#define ov(a,n) for(ll i=n-1;i>=0;i--)cout<<a[i]<<" ";nl
#define maxa(ar,N) *max_element(ar,ar+N)
#define mina(ar,N) *min_element(ar,ar+N)
#define INF 1e15
#define fastio() ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define printclock cerr<<"Time : "<<1000*(long double)clock()/(long double)CLOCKS_PER_SEC<<"ms\n";
ll power(ll x, ll y){ll res=1;x=x%MOD;while(y>0){if(y&1)res = (res*x) % MOD;y = y>>1;x = (x*x) % MOD;}return res;}  
ll logtwo(ll n){if(n==1)return 0;return logtwo(n/2)+1;}
void ceilsearch(ll ar[],ll low,ll high,ll x,ll &y){if(low>high)return;ll mid=(low+high)/2;if(ar[mid]>=x){y=mid;ceilsearch(ar,low,mid-1,x,y);}else{ceilsearch(ar,mid+1,high,x,y);}}
/*struct Node
{
	ll maxPrefixSum;
	ll maxSuffixSum;
	ll totalSum;
	ll maxSubarraySum;
	Node()
	{
		maxSubarraySum=-LONGMAX;
		maxSuffixSum=-LONGMAX;
		totalSum=-LONGMAX;
		maxPrefixSum=-LONGMAX;
	}
};
void constructTreeUtil(Node* tree,ll ar[],ll ss,ll se,ll si)
{
	if(se==ss)
	{
		tree[si].maxPrefixSum=ar[se];
		tree[si].maxSuffixSum=ar[se];
		tree[si].maxSubarraySum=ar[se];
		tree[si].totalSum=ar[se];
		return;
	}
	ll mid=(se+ss)/2;
	constructTreeUtil(tree,ar,ss,mid,2*si+1);
	constructTreeUtil(tree,ar,mid+1,se,2*si+2);
	tree[si].maxPrefixSum=max(tree[2*si+1].maxPrefixSum,tree[2*si+1].totalSum+tree[2*si+2].maxPrefixSum);
	tree[si].maxSuffixSum=max(tree[2*si+2].maxSuffixSum,tree[2*si+1].maxSuffixSum+tree[2*si+2].totalSum);
	tree[si].totalSum=tree[2*si+1].totalSum+tree[2*si+2].totalSum;
	tree[si].maxSubarraySum=max({tree[2*si+1].maxSubarraySum,tree[2*si+2].maxSubarraySum,tree[2*si+1].maxSuffixSum+tree[2*si+2].maxPrefixSum});
}
void constructTree(ll ar[],ll N,Node *tree)
{
	constructTreeUtil(tree,ar,0,N-1,0);
}
Node queryUtil(Node* tree,ll ss,ll se,ll low,ll high,ll si)
{
	if(low>se||high<ss)
	{
		Node nullNode;
		return nullNode;
	}
	if(ss >= low && se <= high)
	{
		return tree[si];
	}
	ll mid=(se+ss)/2;
	Node left=queryUtil(tree,ss,mid,low,high,2*si+1);
	Node right=queryUtil(tree,mid+1,se,low,high,2*si+2);
	Node res;
	res.maxPrefixSum=max(left.maxPrefixSum,left.totalSum+right.maxPrefixSum);
	res.maxSuffixSum=max(right.maxSuffixSum,right.totalSum+left.maxSuffixSum);
	res.totalSum=left.totalSum+right.totalSum;
	res.maxSubarraySum=max({right.maxSubarraySum,left.maxSubarraySum,left.maxSuffixSum+right.maxPrefixSum});
	return res;
}
ll query(Node* tree,ll low,ll high,ll N)
{
	return queryUtil(tree,0,N-1,low,high,0).maxSubarraySum;
}*/
/*vector<ll> adj[100];
bool vis[100];
ll level[100];
ll X,C;
ll ans=-1;*/
vector<ll> adj[10005];
ll ar[100][100];
ll cost[10005];
ll N,M;
void dfs(ll par)
{
	for(auto i:adj[par])	
	{
		ll cos=0;
		if(ar[i/M][i%M]==ar[par/M][par%M])
			cos=cost[par];
		else
			cos=cost[par]+ar[i/M][i%M];
		if(cos<cost[i])
		{
			cost[i]=cos;
			dfs(i);
		}
	}	
}
signed main()
{
	fastio();	
    cin>>N>>M;
    for(ll i=0;i<10005;i++)
    	cost[i]=INF;
    for(ll i=0;i<N;i++)
    {
    	string s;
    	cin>>s;
    	for(ll j=0;j<M;j++)
    	{
    		if(s[j]=='#')
    			ar[i][j]=1;
    		else
    			ar[i][j]=0;
    	}
    }
    for(ll i=0;i<N;i++)
    {
    	for(ll j=0;j<M;j++)
    	{
    		if(i+1<N)
    		{
    			adj[i*M+j].pb((i+1)*M+j);
    		}
    		if(j+1<M)
    		{
    			adj[(i*M+j)].pb(i*M+j+1);
    		}
    	}
    }
    cost[0]=ar[0][0];
    dfs(0);
    cout<<cost[(N-1)*M+M-1]<<endl;
}	

Measured memory_bytes: 1024