#include"iostream"
#include"cstdio"
#include"cmath"
#include"cstring"
#include"algorithm"
#include"stack"
#include"queue"
using namespace std;

#define read(x) scanf("%d",&x)
#define readl(x) scanf("%lld",&x)
#define ll long long
#define ull unsigned long long
#define MOD 998244353
#define MAXN 15

int n;
ll k;
ll e[MAXN][MAXN];
int f[MAXN];
int ans=0;

int main()
{
	read(n),readl(k);
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++) readl(e[i][j]);
		f[i]=i;
	}
	do
	{
		int lst=1;
		ll now=0;
		for(int i=2;i<=n;i++)
		{
			now+=e[lst][f[i]];
			lst=f[i];
		}
		now+=e[lst][1];
		if(now==k) ans++;
	}while(next_permutation(f+2,f+n+1));
	printf("%d\n",ans);
	return 0;
}

#include <iostream>
#include <algorithm>
#include <string>
#include <complex>
#include <vector>
#include <set>
#include <cmath>
#include <queue>
#include <map>
#include <stack>
#include <bitset>
#include <numeric> //lcm
#include <iomanip> //double精度 setprecision

//#include <atcoder/all>

using namespace std;
//using namespace atcoder;

#define rep(i,n) for(int i = 0; i < (n); ++i)
#define rrep(i,n) for(int i = n-1; i >= 0; --i)
#define rep1(i,n) for(int i = 1; i <= (n); ++i)
#define rrep1(i,n) for(int i = (n); i >= 1; --i)
#define REP(i,n,m) for(int i = (n); i < (m); ++i)
#define all(vec) (vec).begin(),(vec).end()

#define debug(vec) for(auto v : vec) cerr << v << " "; cerr << endl;
#define debug2D(vec2D, w) for(auto vec : vec2D) { for (auto v : vec) cerr << setw(w) << v << " "; cerr << endl; } 
#define debugP(vec) for(auto v : vec) cerr << "(" << v.first << "," << v.second << ") "; cerr << endl;
#define debug2DP(vec2D) for(auto vec : vec2D) { for (auto v : vec) cerr << "(" << v.first << "," << v.second << ") "; cerr << endl; } 

typedef long long ll;

template<class T> using vvec = vector<vector<T>>;
template<class T> using vvvec = vector<vvec<T>>;

constexpr ll INF = 1e14; //32 ~2*10^10 //64 ~9*10^19
//const ll MOD = 998244353;
constexpr ll MOD = 1000000007;
constexpr double EPS = 1e-6;

struct Edge {
	Edge(int _s, int _t, ll f, ll _cost = 1) : from(_s), to(_t), cost(_cost), fee(f) {};
	int from, to;
	ll cost;
	ll fee;
};

typedef vector<vector<Edge>> Graph;

void add_edge(Graph& g, int from, int to, ll fee, ll cost = 1) {
	g[from].push_back(Edge(from, to, fee, cost));
}

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return true; } else return false; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return true; } else return false; }

//int dx[4] = {0,1,0,-1}, dy[4] = {1,0,-1,0};


int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);

	ll h,w; cin >> h >> w;
	vector<string> s(h);
	rep(i,h) cin >> s[i];
	

	ll ans = 0;
	rep(i, h) rep(j, w) {
		if (s[i][j] == '.') {
			if (i+1 < h && s[i+1][j] == '.') ++ans;
			if (j + 1 < w && s[i][j+1] == '.') ++ans;
		}
	}
  
	cout << ans << endl;
}