#include<algorithm>
#include<iomanip>
#include<iostream>
#include<map>
#include<set>
#include<stack>
#include<string>
#include<vector>
#include<bitset>
#include<cmath>
#define FOR(i,a,b) for(int i=(a); i<int(b); ++i)
#define RFOR(i,a,b) for(int i=(b)-1; i>=int(a); --i)
#define rep(i,n) FOR(i,0,n)
#define rep1(i,n) FOR(i,1,int(n)+1)
#define rrep(i, n) RFOR(i, 0, n)
#define rrep1(i, n) RFOR(i, 1, int(n) + 1)
#define all(c) begin(c), end(c)
#define al(d) d.begin(),d.end()
using namespace std;
template <typename T>
void putv(vector<T>& V){
	// cout << "The elements in the vector are: " << endl;
	for(auto x: V)
		cout << x << " ";
	cout << endl;
}
template <class T>
vector<T> getv(int n){
	vector<T> vec;
	rep(i,n){
		T input;
		cin >> input;
		vec.emplace_back(input);
	}
	return vec;
}

bool search(int x, int y);
int H,W;
vector<string> s;
int main(){
	cin >>H>>W;
	s = getv<string>(H);

	bool ans = true;
	rep(x,H){
		if(!ans) break;
		rep(y,W){
			if(!ans) break;
			if(s[x][y]=='#' && !search(x,y)) ans = false;
		}
	}
	Out(ans);
}

// 上下左右のいずれかに黒が隣接していればtrueを返す
bool search(int x, int y){
	if(0<=x-1 && s[x-1][y] == '#') return true;
	if(0<=y-1 && s[x][y-1] == '#') return true;
	if(y+1<W  && s[x][y+1] == '#') return true;
	if(x+1<H  && s[x+1][y] == '#') return true;
	return false;
}