### BUGGY CODE ###

#!/usr/bin/env python3
import sys
import heapq
from collections import deque

def solve(H: int, W: int, s: "List[str]"):
    minScore = 10**16
    def isBlock(x,y):
        return s[y][x] == "#"
    first = isBlock(0,0)
    current = deque([(0,0)])
    map = [[None for j in range(H)] for i in range(W)]
    map[0][0] = (1,True) if first else (0,False)
    def addNextIfCan(x,y,prevScore,prevBlock):
        if x >= W or y >= H:
            return
        c = isBlock(x,y)
        current.appendleft((x,y))
        cScore = prevScore + 1 if c and not prevBlock else prevScore
        if map[x][y] == None:
            map[x][y] = (cScore,c)
            return
        if map[x][y][0] > prevScore:
            map[x][y] = (cScore,c)
        elif c and map[x][y][0] == prevScore:
            map[x][y] = (cScore,c)
    
    while len(current) > 0:
        n = current.pop()
        prevScore = map[n[0]][n[1]][0]
        prevBlock = map[n[0]][n[1]][1]
        addNextIfCan(n[0]+1,n[1],prevScore,prevBlock)
        addNextIfCan(n[0],n[1]+1,prevScore,prevBlock)
    print(map[W-1][H-1][0])
    return


# Generated by 1.1.6 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    H = int(next(tokens))  # type: int
    W = int(next(tokens))  # type: int
    s = [next(tokens) for _ in range(H)]  # type: "List[str]"
    solve(H, W, s)

if __name__ == '__main__':
    main()


### FIXED CODE ###

#!/usr/bin/env python3
import sys
import heapq
from collections import deque

def solve(H: int, W: int, s: "List[str]"):
    minScore = 10**16
    def isBlock(x,y):
        return s[y][x] == "#"
    first = isBlock(0,0)
    current = set([(0,0)])
    next = set()
    map = [[None for j in range(H)] for i in range(W)]
    map[0][0] = (1,True) if first else (0,False)
    def addNextIfCan(x,y,prevScore,prevBlock):
        if x >= W or y >= H:
            return
        c = isBlock(x,y)
        next.add((x,y))
        cScore = prevScore + 1 if c and not prevBlock else prevScore
        if map[x][y] == None:
            map[x][y] = (cScore,c)
        if map[x][y][0] > cScore:
            map[x][y] = (cScore,c)
        elif c and map[x][y][0] == cScore:
            map[x][y] = (cScore,c)
    while len(current) > 0:
        while len(current) > 0:
            n = current.pop()
            prevScore = map[n[0]][n[1]][0]
            prevBlock = map[n[0]][n[1]][1]
            addNextIfCan(n[0]+1,n[1],prevScore,prevBlock)
            addNextIfCan(n[0],n[1]+1,prevScore,prevBlock)
        current = next
        next = set()
    print(map[W-1][H-1][0])
    return


# Generated by 1.1.6 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    H = int(next(tokens))  # type: int
    W = int(next(tokens))  # type: int
    s = [next(tokens) for _ in range(H)]  # type: "List[str]"
    solve(H, W, s)

if __name__ == '__main__':
    main()