#pragma region head
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vi = vector<int>;
using vll = vector<ll>;
using pi = pair<int, int>;
using pll = pair<ll, ll>;
template <class T>
using vv = vector<vector<T>>;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define repi(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, n) for (int i = (int)(n)-1; i >= 0; i--)
#define rrepi(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define bit(n) (1LL << (n))
template <class T>
inline bool chmax(T& a, const T& b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <class T>
inline bool chmin(T& a, const T& b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
const int INF = 1002003004;
const ll LINF = 1002003004005006007ll;
struct preprocess {
    preprocess() {
        cin.tie(nullptr);
        ios::sync_with_stdio(false);
        cout << fixed << setprecision(20);
    }
} ____;
#pragma endregion head

#pragma region library
const int MOD = 1000000007;
struct mint {
    ll x;  // typedef long long ll;
    mint(ll x = 0) : x((x % MOD + MOD) % MOD) {}
    mint operator-() const { return mint(-x); }
    mint& operator+=(const mint a) {
        if ((x += a.x) >= MOD) x -= MOD;
        return *this;
    }
    mint& operator-=(const mint a) {
        if ((x += MOD - a.x) >= MOD) x -= MOD;
        return *this;
    }
    mint& operator*=(const mint a) {
        (x *= a.x) %= MOD;
        return *this;
    }
    mint operator+(const mint a) const {
        mint res(*this);
        return res += a;
    }
    mint operator-(const mint a) const {
        mint res(*this);
        return res -= a;
    }
    mint operator*(const mint a) const {
        mint res(*this);
        return res *= a;
    }
    mint pow(ll t) const {
        if (!t) return 1;
        mint a = pow(t >> 1);
        a *= a;
        if (t & 1) a *= *this;
        return a;
    }
    // for prime MOD
    mint inv() const {
        return pow(MOD - 2);
    }
    mint& operator/=(const mint a) {
        return (*this) *= a.inv();
    }
    mint operator/(const mint a) const {
        mint res(*this);
        return res /= a;
    }
    bool operator==(const mint a) const {
        return x == a.x;
    }
    bool operator!=(const mint a) const {
        return x != a.x;
    }
    friend ostream& operator<<(ostream& os, const mint& value) {
        os << value.x;
        return os;
    }
    friend istream& operator>>(istream& is, mint& value) {
        ll t;
        is >> t;
        value = mint(t);
        return is;
    }
};
struct combination {
    vector<mint> fact, ifact;
    combination(int n) : fact(n + 1), ifact(n + 1) {
        assert(n < MOD);
        fact[0] = 1;
        for (int i = 1; i <= n; ++i) fact[i] = fact[i - 1] * i;
        ifact[n] = fact[n].inv();
        for (int i = n; i >= 1; --i) ifact[i - 1] = ifact[i] * i;
    }
    mint operator()(int n, int k) {
        if (k < 0 || k > n) return 0;
        return fact[n] * ifact[k] * ifact[n - k];
    }
};

#pragma endregion library

int main() {
    int n;
    cin >> n;
    vector<char> c(4);
    rep(i, 4) cin >> c[i];
    if (n <= 3 || (c[0] == 'A' && c[1] == 'A') || (c[1] == 'B' && c[3] == 'B')) {
        cout << 1 << '\n';
        return 0;
    } else {
        if (c[1] != c[2]) {
            mint two = 2;
            cout << two.pow(n - 3) << '\n';
        } else {
            mint ans = 0;
            combination cb(2000);
            rep(i, n) {
                int cnta = n - 3 - i;
                if (cnta < 0) break;
                ans += cb(cnta + 1, i);
            }
            cout << ans << '\n';
        }
    }
}

#include <bits/stdc++.h>
using namespace std;

const int MAX_LEN = 50;
string DIR[5] = {"U", "D", "L", "R", ""};
int dir2int(char c) {
  if ( c == 'U' ) { return 0; }
  if ( c == 'D' ) { return 1; }
  if ( c == 'L' ) { return 2; }
  if ( c == 'R' ) { return 3; }
  return 4;
}
void move(int* i, int* j, int dir) {
  if ( dir == 0 && *i > 0 ) { *i -= 1; }
  if ( dir == 1 && *i < MAX_LEN-1 ) { *i += 1; }
  if ( dir == 2 && *j > 0 ) { *j -= 1; }
  if ( dir == 3 && *j < MAX_LEN-1 ) { *j += 1; }
}
int si, sj;
int t[MAX_LEN][MAX_LEN], p[MAX_LEN][MAX_LEN];

const double TIME_LIMIT = 1.3;
double now_time(clock_t start, clock_t now) {
  return ((double)(now - start) / CLOCKS_PER_SEC);
}

int next_dir(int i, int j, bool visited[]) {
  int ret = 4;
  int next_p = -1;
 
  if ( i > 0 && (! visited[t[i-1][j]]) && p[i-1][j] > next_p ) { ret = 0; next_p = p[i-1][j]; }
  if ( i < MAX_LEN-1 && (! visited[t[i+1][j]]) && p[i+1][j] > next_p ) { ret = 1; next_p = p[i+1][j]; }
  if ( j > 0 && (! visited[t[i][j-1]]) && p[i][j-1] > next_p ) { ret = 2; next_p = p[i][j-1]; }
  if ( j < MAX_LEN-1 && (! visited[t[i][j+1]]) && p[i][j+1] > next_p ) { ret = 3; next_p = p[i][j+1]; }
 
  return ret;
}

int next_dir_2(int i, int j, bool visited[]) {
  int ret = 4;
  int next_p = -1;
 
  if ( i > 0 && (! visited[t[i-1][j]]) && p[i-1][j] > next_p ) { ret = 0; next_p = p[i-1][j]; }
  if ( i < MAX_LEN-1 && (! visited[t[i+1][j]]) && p[i+1][j] > next_p ) { ret = 1; next_p = p[i+1][j]; }
  if ( j > 0 && (! visited[t[i][j-1]]) && p[i][j-1] > next_p ) { ret = 2; next_p = p[i][j-1]; }
  if ( j < MAX_LEN-1 && (! visited[t[i][j+1]]) && p[i][j+1] > next_p ) { ret = 3; next_p = p[i][j+1]; }
 
  return ret;
}

struct STATE {
  string route;
};

void init(STATE& state) {
  state.route = "";
  int i = si, j = sj;
  bool visited[2500] = {};
  visited[t[i][j]] = true;

  // 貪欲
  while ( true ) {
    int next = next_dir(i, j, visited);
    if ( next == 4 ) { break; }
    state.route += DIR[next];
    move(&i, &j, next);
    visited[t[i][j]] = true;
  }
}

void modify(STATE& state) {
  string mod_route = "";
  int i = si;
  int j = sj;
  bool visited[2500] = {};
  visited[t[i][j]] = true;

  int use_len = rand() % state.route.size();
  for ( int k = 0; k < use_len; k++ ) {
    mod_route += state.route[k];
    move(&i, &j, dir2int(state.route[k]));
    visited[t[i][j]] = true;
  }

  // randに変更
  int r = rand() % 4;
  mod_route += DIR[r];
  move(&i, &j, r);
  visited[t[i][j]] = true;

  // それ以降貪欲
  while ( true ) {
    int next = next_dir(i, j, visited);
    if ( next == 4 ) { break; }
    mod_route += DIR[next];
    move(&i, &j, next);
    visited[t[i][j]] = true;
  }

  state.route = mod_route;
}

int calc_score(STATE& state) {
  int point = p[si][sj];
  int i = si;
  int j = sj;
  bool visited[2500] = {};
  visited[t[i][j]] = true;
  for ( int k = 0; k < state.route.size(); k++ ) {
    move(&i, &j, dir2int(state.route[k]));
    point += p[i][j];
    if ( visited[t[i][j]] ) { return 0; }
    visited[t[i][j]] = true;
  }
  return point;
}

void mountain(STATE& state) {
  init(state);
  
  clock_t start = clock();
  while ( true ) {
    clock_t now = clock();
    if ( now_time(start, now) > TIME_LIMIT ) { break; }

    STATE new_state = state;
    modify(new_state);
    int new_score = calc_score(new_state);
    int pre_score = calc_score(state);

    if ( new_score > pre_score ) {
      state = new_state;
    }
  }
}

int main() {
  srand(time(NULL));
  cin >> si >> sj;

  for ( int i = 0; i < MAX_LEN; i++ ) {
    for ( int j = 0; j < MAX_LEN; j++ ) {
      cin >> t[i][j];
    }
  }
  for ( int i = 0; i < MAX_LEN; i++ ) {
    for ( int j = 0; j < MAX_LEN; j++ ) {
      cin >> p[i][j];
    }
  }

  STATE ans;
  mountain(ans);
  cout << ans.route << endl;
  return 0;
}
