// #include <bits/stdc++.h>
// using namespace std;
// #define MAX_HEIGHT 100000

// // Tree Node
// struct Node
// {
//    int data;
//    Node* left;
//    Node* right;
// };

// // Utility function to create a new Tree Node
// Node* newNode(int val)
// {
//    Node* temp = new Node;
//    temp->data = val;
//    temp->left = NULL;
//    temp->right = NULL;

//    return temp;
// }



// Node* insert(Node* node, int data);

// // Function to Build Tree
// Node* buildTree(string str)
// {
//    // Corner Case
//    if(str.length() == 0 || str[0] == 'N')
//        return NULL;

//    // Creating vector of strings from input
//    // string after spliting by space
//    vector<string> ip;

//    istringstream iss(str);
//    for(string str; iss >> str; )
//        ip.push_back(str);

//    // Create the root of the tree
//    Node* root = newNode(stoi(ip[0]));

//    // Push the root to the queue
//    queue<Node*> queue;
//    queue.push(root);

//    // Starting from the second element
//    int i = 1;
//    while(!queue.empty() && i < ip.size()) {

//        // Get and remove the front of the queue
//        Node* currNode = queue.front();
//        queue.pop();

//        // Get the current node's value from the string
//        string currVal = ip[i];

//        // If the left child is not null
//        if(currVal != "N") {

//            // Create the left child for the current node
//            currNode->left = newNode(stoi(currVal));

//            // Push it to the queue
//            queue.push(currNode->left);
//        }

//        // For the right child
//        i++;
//        if(i >= ip.size())
//            break;
//        currVal = ip[i];

//        // If the right child is not null
//        if(currVal != "N") {

//            // Create the right child for the current node
//            currNode->right = newNode(stoi(currVal));

//            // Push it to the queue
//            queue.push(currNode->right);
//        }
//        i++;
//    }

//    return root;
// }

// void inorder(Node *root, vector<int> &v)
// {
//     if(root==NULL)
//         return;

//     inorder(root->left, v);
//     v.push_back(root->data);
//     inorder(root->right, v);
// }

// int main() {
//    freopen("input.txt","r", stdin);
//    freopen("output.txt","w", stdout);
//    int t;
//    string tc;
//    getline(cin, tc);
//    t=stoi(tc);
//    while(t--)
//    {
//         string s; 
//        getline(cin, s);
//        Node* root = buildTree(s);

//        getline(cin, s);
//         int k = stoi(s);
//         getline(cin, s);

//         insert(root, k);
//         vector<int> v;
//         inorder(root, v);
//         for(int i=0;i<v.size();i++)
//             cout << v[i] << " ";
//         cout << endl;

//        cout<<"~"<<endl;
//    }
//    return 0;
// }


// Node* insert(Node* node, int data)
// {
//     if (node == NULL) return newNode(data);
//     if (data < node->data)
//         node->left  = insert(node->left, data);
//     else if (data > node->data)
//         node->right = insert(node->right, data);
//     return node;
// }






//--------------------------------------division----------------------------------------------------




















// #include<bits/stdc++.h>

// using namespace std;

// // Tree Node
// struct Node {
//     int data;
//     Node *left;
//     Node *right;

//     Node(int val) {
//         data = val;
//         left = right = NULL;
//     }
// };


// int getRandomFromRange(int l, int r) {
//     return (l + (rand() % (r - l + 1)));
// }

// // Return the string representing the BST
// // with n nodes where every node is from
// // the range [l, r]
// // Note that the number of integers in
// // the range [l, r] must be >= n
// string generateBST(int n, int l, int r) {
//     string str = "";

//     queue<pair<int, pair<int, int> > > queue;

//     // Create the root node
//     int root = getRandomFromRange(l, r);

//     // Add the root node and its
//     // range in the queues
//     queue.push({root, {l, r}});

//     str += (to_string(root) + " ");

//     // Number of nodes in the current tree
//     int valid = 1;

//     while (!queue.empty()) {

//         // Get the current node
//         pair<int, pair<int, int>> currNode = queue.front();
//         queue.pop();

//         // If the tree has been generated
//         if (valid >= n)
//             break;

//         // If the left node is not possible
//         if (currNode.first == currNode.second.first) {
//             str += "N ";
//         } else {

//             // Generate the left child
//             int leftChild = getRandomFromRange(currNode.second.first, currNode.first - 1);

//             // Add the left child and its range to the queue
//             queue.push({leftChild, {currNode.second.first, currNode.first - 1}});

//             str += (to_string(leftChild) + " ");
//             valid++;
//         }

//         // If the tree has been generated
//         if (valid >= n)
//             break;

//         // If the right node is not possible
//         if (currNode.first == currNode.second.second) {
//             str += "N ";
//         } else {

//             // Generate the right child
//             int rightChild = getRandomFromRange(currNode.first + 1, currNode.second.second);

//             // Add the left child and its range to the queue
//             queue.push({rightChild, {currNode.first + 1, currNode.second.second}});
//             str += (to_string(rightChild) + " ");
//             valid++;
//         }
//     }
//     return str;
// }

// // Return the string representing the binary tree with
// // n nodes where every node is from the range [l, r]
// string generalTreeDuplicates(int n, int l, int r, int factor) {
//     string str = "";

//     // To store the count of total nodes including
//     // null children of every valid node
//     int count = 2;

//     // To store the count of all valid nodes
//     int valid = 1;


//     // Generate the root node to the queue
//     int root = getRandomFromRange(l, r);
//     str += (to_string(root) + " ");

//     while (valid < n) {

//         // Time to hit null
//         if ((count % factor) == 0) {
//             str += "N ";
//         }

//             // Generate the left child
//         else {

//             // Get a random value for the left child
//             int leftChild = getRandomFromRange(l, r);
//             str += (to_string(leftChild) + " ");

//             // Increment the count of valid nodes
//             valid++;
//         }

//         // A node has been added
//         count++;

//         // If the tree has been generated
//         if (valid >= n)
//             break;

//         // Time to hit null
//         if ((count % factor) == 0) {
//             str += "N ";
//         }

//             // Generate the right child
//         else {

//             // Get a random value for the right child
//             int rightChild = getRandomFromRange(l, r);
//             str += (to_string(rightChild) + " ");

//             // Increment the count of valid nodes
//             valid++;
//         }

//         // Another node has been added
//         count++;
//     }
//     str += "\n";
//     return str;
// }

// Node *buildTree(string str) {
//     // Corner Case
//     if (str.length() == 0 || str[0] == 'N')
//         return NULL;

//     // Creating vector of strings from input
//     // string after spliting by space
//     vector<string> ip;

//     istringstream iss(str);
//     for (string str; iss >> str;)
//         ip.push_back(str);

//     // Create the root of the tree
//     Node *root = new Node(stoi(ip[0]));

//     // Push the root to the queue
//     queue<Node *> queue;
//     queue.push(root);

//     // Starting from the second element
//     int i = 1;
//     while (!queue.empty() && i < ip.size()) {

//         // Get and remove the front of the queue
//         Node *currNode = queue.front();
//         queue.pop();

//         // Get the current node's value from the string
//         string currVal = ip[i];

//         // If the left child is not null
//         if (currVal != "N") {

//             // Create the left child for the current node
//             currNode->left = new Node(stoi(currVal));

//             // Push it to the queue
//             queue.push(currNode->left);
//         }

//         // For the right child
//         i++;
//         if (i >= ip.size())
//             break;
//         currVal = ip[i];

//         // If the right child is not null
//         if (currVal != "N") {

//             // Create the right child for the current node
//             currNode->right = new Node(stoi(currVal));

//             // Push it to the queue
//             queue.push(currNode->right);
//         }
//         i++;
//     }

//     return root;
// }

// void storeNodesInOrder(Node *root, vector<Node *> &inOrder) {
//     if (!root)
//         return;

//     storeNodesInOrder(root->left, inOrder);
//     inOrder.push_back(root);
//     storeNodesInOrder(root->right, inOrder);
// }

// string toString(Node *root) {
//     if (root == nullptr)
//         return "N\n";

//     string str;
//     queue<Node *> qq;
//     qq.push(root);

//     while (!qq.empty()) {
//         Node *curr = qq.front();
//         qq.pop();

//         if (curr == nullptr) {
//             str += "N ";
//             continue;
//         }
//         str += (to_string(curr->data) + " ");
//         qq.push(curr->left);
//         qq.push(curr->right);
//     }
//     str += "\n";
//     return str;
// }




// const int N = 10000, MAXI = 500000;

// int main() {
//     freopen("output.txt", "r", stdin);
//     freopen("input.txt", "w", stdout);
//     srand(time(nullptr));
//     int tc = 10;
//     cout << tc << "\n";
//     while (tc--) {
//         int n = rand()%N+1;
//         int l = 1, r = rand() % MAXI + 1;
//         int factor = 2 + rand() % 8;


//         auto treeString = generateBST(n, l, r);
//         Node *root = buildTree(treeString);

//         cout << treeString << endl;

//         cout << rand()%MAXI + 1 << endl;
        
        
//         cout << "~\n";
//     }

//     return 0;
// }








//---------------------------------------------//





/* while(!cin.eof()) */
 
#include<bits/stdc++.h>
using namespace std; 
#define int long long 
#define mod (int)(1e9+7)
#define MAXI (int)(1e17+100)
#define N 105
 
int n, m;
vector<string> str;

int dp[N][N];

// Driver code to test above functions
int32_t main()
{
    
 
  
    ios_base::sync_with_stdio(0);
    cin.tie(NULL);
    cout.tie(NULL);

    cin >> n >> m;
    for(int i=1;i<=n;i++){
        string s;
        cin >> s;
        str.push_back(s);
    }

    if(str[0][0]=='#')
        dp[0][0] = 1;

    for(int i=1;i<n;i++)
    {
        if(str[i][0]=='#' and str[i-1][0]=='.')
            dp[i][0] = 1 + dp[i-1][0];
        else
            dp[i][0] = dp[i-1][0];
    }  

    for(int i=1;i<m;i++)
    {
        if(str[0][i]=='#' and str[0][i-1]=='.')
            dp[0][i] = 1 + dp[0][i-1];
        else
            dp[0][i] = dp[0][i-1];
    }    

    for(int i=1;i<n;i++)
    {
        for(int j=1;j<m;j++)
        {
            if(str[i][j]=='.')
                dp[i][j] = min(dp[i-1][j], dp[i][j-1]);
            else
            {
                if(str[i-1][j]=='#' and str[i][j-1]=='#')
                    dp[i][j] = min(dp[i-1][j], dp[i][j-1]);
                else if(str[i-1][j]=='#')
                    dp[i][j] = dp[i-1][j];
                else if(str[i][j-1]=='#')
                    dp[i][j] = dp[i][j-1];
                else
                    dp[i][j] = 1 + min(dp[i-1][j], dp[i][j-1]);
            }
        }
    }

    // for(int i=0;i<n;i++)
    // {
    //     for(int j=0;j<m;j++)
    //     {
    //         cout << dp[i][j] << " ";
    //     }
    //     cout << endl;
    // }

    cout << dp[n-1][m-1];

    return 0;
    
}  




Measured memory_bytes: 384