import java.io.*;
import java.util.*;

public class LudoBottomUp {
    public static void main(String[] args) throws IOException {
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		System.out.println(solve(reader));
    }

	public static int solve(BufferedReader in) throws IOException {
        String[] parts = in.readLine().split(" ");
        int n = Integer.parseInt(parts[0]), m = Integer.parseInt(parts[1]);
		int[] a = new int[n/2];
		for (int i=n-1; i >= 0; i--) {
			String line = in.readLine();
			for (int j=0; j < m; j++)
				if (line.charAt(j) == '#')
					a[i/2] |= 1<<j;
		}

		int[] F = new int[m + 2];	
		F[0] = 0;
		F[1] = 1;
		for (int i=2; i < m+2; i++)
			F[i] = F[i-1] + F[i-2];

		int num_ways = F[m+1];
		int[] cover = new int[num_ways], pc = new int[num_ways];
		ArrayList[] supports = new ArrayList[num_ways];
		for (int i=0; i < num_ways; i++)
			supports[i] = new ArrayList<Integer>();
		supports[0].add(0);

		for (int i = 2; i <= m; i++) {
			for (int j = 0; j < F[i-1]; j++) {
				cover[F[i] + j] = cover[j] | (3<<(i-2));
				pc[F[i] + j] = pc[j] + 1;
			}
		}

		HashMap<Integer, Integer> lookup = new HashMap<Integer, Integer>();
		for (int i=0; i < num_ways; i++)
			lookup.put(cover[i], i);

		for (int i = 2; i <= m; i++) {
			for (int j = 0, k = F[i]; j < F[i-1]; j++, k++) {
				for (Integer sup : (ArrayList<Integer>) supports[j]) {
					int msk = cover[sup];

					// nothing added:
					supports[k].add(sup);

					// something added to the left:
					if (i > 2 && (msk & (3<<(i-3))) == 0)
						supports[k].add(lookup.get(msk | (3<<(i-3))));
					// something added above:
					if (         (msk & (3<<(i-2))) == 0)
						supports[k].add(lookup.get(msk | (3<<(i-2))));
					// something added to the right:
					if (i < m && (msk & (3<<(i-1))) == 0)
						supports[k].add(lookup.get(msk | (3<<(i-1))));
					// something added to the left and right:
					if (2 < i && i < m && (msk & (15<<(i-3))) == 0)
						supports[k].add(lookup.get(msk | (15<<(i-3))));
				}
			}
		}

		int[] curDP = new int[num_ways];
		for (int i=0; i < num_ways; i++)
			curDP[i] = ((a[0] & ~cover[i]) != 0) ? Integer.MAX_VALUE : pc[i];

		for (int row = 1; 2*row < n; row++) {
			int[] newDP = new int[num_ways];
			for (int j = 0; j < num_ways; j++)
				newDP[j] = Integer.MAX_VALUE;
			for (int j = 0; j < num_ways; j++) {
				if (curDP[j] == Integer.MAX_VALUE)
					continue;
				for (Integer k : (ArrayList<Integer>) supports[j]) {
					if ((a[row] & ~cover[k]) != 0)
						continue;
					newDP[k] = Math.min(newDP[k], curDP[j] + pc[k]);
				}
			}
			curDP = newDP;
		}

		int result = Integer.MAX_VALUE;
		for (int j=0; j < num_ways; j++)
			result = Math.min(result, curDP[j]);
		return result;
	}
}
