#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <functional>
#include <utility>
#include <tuple>
#include <cctype>
#include <bitset>
#include <complex>
#include <cmath>
#include <array>
#include <numeric>
#include <cassert>
#include <memory>
#include <random>
#include <chrono>
using namespace std;
#define INF 0x3f3f3f3f
#define INFLL 0x3f3f3f3f3f3f3f3fLL
//#define MOD 998244353
#define MOD 1000000007
#define mp make_pair
#define mt make_tuple
#define pb push_back
#define eb emplace_back
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pint;
typedef pair<ll,ll> pll;
typedef tuple<int,int,int> tint;
typedef vector<int> vint;
typedef vector<ll> vll;
typedef vector<ull> vull;
typedef vector<pint> vpint;
typedef vector<tint> vtint;
typedef vector<vint> vvint;
// int dx[8]={0,0,-1,1,1,1,-1,-1};
// int dy[8]={-1,1,0,0,1,-1,1,-1};
const int SIZE=50;
//↑templete
int si, sj;
int t[SIZE][SIZE] = {};
int p[SIZE][SIZE] = {};

string nowStr = "";
string bestStr = "";

bool usedTile[2500] = {};
int score = 0;
int bestScore = 0;

int dx[4] = {0, 1, 0, -1};
int dy[4] = {-1, 0, 1, 0};
string com[4] = {"L", "D", "R", "U"};
std::random_device seed_gen;
std::mt19937 engine(seed_gen());
chrono::system_clock::time_point start;
bool isEnd = 0;
void DFS(int x, int y){
    if (isEnd)
        return;
    int nowTime = chrono::duration_cast<chrono::milliseconds>(chrono::system_clock::now() - start).count();

    if (nowTime > 100)
    {
        isEnd = 1;
        // cout << bestStr << endl;
        return;
    }
    
    //現在位置が入力される
    //マスを埋めて、スコアを加算する
    int tile = t[x][y];
    if (usedTile[tile])
        return;
    score += p[x][y];
    usedTile[tile] = 1;
    if (bestScore < score)
    {
        bestScore = score;
        bestStr = nowStr;
        // cout<<bestScore <<" "<< bestStr<< " " <<nowTime<<endl;
    }

    //探索順をランダムに決めてみる
    vint ran = {0, 1, 2, 3};
    shuffle(ran.begin(), ran.end(), engine);
    for (int a=0;a<4;a++)
    {
        int k = ran[a];
        //コマンドを作って次のマスに
        int X = x + dx[k], Y = y + dy[k];
        // cout << X <<" "<< Y <<endl;
        if (X < 0 || SIZE <= X || Y < 0 || SIZE <= Y)
            continue;
        nowStr += com[k];
        DFS(X, Y);
        nowStr.pop_back();
    }

    //全方向見たら、マスを開放してスコアを減算する
    score -= p[x][y];
    usedTile[tile] = 0;
    return;
}
signed main(){
    start = chrono::system_clock::now();
    cin>>si>>sj;
    for (int i=0;i<SIZE;i++)
        for (int j=0;j<SIZE;j++)
            cin>>t[i][j];
    for (int i=0;i<SIZE;i++)
        for (int j=0;j<SIZE;j++)
            cin>>p[i][j];

    int ret = 0;
    string retStr = "";
    for (int i=0;i<19;i++)
    {
        start = chrono::system_clock::now();
        bestScore = 0;
        score = 0;
        bestStr = "";
        nowStr = "";
        usedTile[2500] = {};
        isEnd = 0;
        DFS(si, sj);
        // cout << bestScore << endl;

        if (ret < bestScore)
        {
            ret = bestScore;
            retStr = bestStr;
        }
    }
    cout << retStr << endl;
    return 0;
}

#include <bits/stdc++.h>
using namespace std;
using st = string;
using ll = long long;
using ld = long double;
using vl = vector<ll>;
using vvl = vector<vector<ll>>;
using vs = vector<string>;
using vi = vector<int>;
using vd = vector<double>;
using vb = vector<bool>;
const ll MOD = 1000000007;
const ll INF_I = 0x3fffffff;
const ll INF_L = 0x7fffffffffffffff;
const ld PI = 3.141592653589793;
const st Y = "Yes", N = "No";
#define rep(i, n) for (ll i = 0; i < n; i++)
#define Mod(x, mod)                               \
	if (x < 0)                                    \
		x = (x + mod * (abs(x) / mod + 1)) % mod; \
	else                                          \
		x %= mod;
#define ExactMinority(degits) \
	cout << fixed << setprecision(degits)
#define UniqueVector(vec)         \
	sort(vec.begin(), vec.end()); \
	vec.erase(unique(vec.begin(), vec.end()), vec.end())
#define all(x) x.begin(), x.end()
#define deb(a) cout << "//" << a << endl;
ll Permutation(ll x, ll y)
{
	ll ret = 1;
	for (ll i = x - y + 1; i <= x; i++)
	{
		ret *= i;
	}
	return ret;
}
ll Combination(ll x, ll y)
{
	return Permutation(x, y) / Permutation(y, y);
}
ll Gcd(ll x, ll y)
{
	if (x < y)
	{
		swap(x, y);
	}
	if (x % y != 0)
	{
		return Gcd(y, x % y);
	}
	else
	{
		return y;
	}
}
ll Lcm(ll x, ll y)
{
	return x / Gcd(x, y) * y;
}

/////////////////////////////////////////////////////////bebebe
int main()
{
	int n, k;
	cin >> n >> k;
	vi a(n);
	vector<vector<int>> t(n, vector<int>(n));
	rep(i, n)
	{
		a[i] = i;
		rep(j, n)
		{
			cin >> t[i][j];
		}
	}
	ll time;
	ll count = 0;
	do
	{
		if (a[0] == 0)
		{
			time = 0;
			//cout << "[";
			rep(i, n - 1)
			{
				time += t[a[i]][a[i + 1]];
				//cout << t[i][a[i + 1]] << " ";
			}
			time += t[a[n-1]][0];
			//cout << t[n - 1][0] << "]" << endl;
			if (time == k)
			{
				count++;
			}
			/*rep(i, n)
			{
				cout << a[i] << " ";
			}
			cout << endl
				 << "//" << time << endl;*/
		}

	} while (next_permutation(all(a)));
	cout << count << endl;
}