#include <bits/stdc++.h>
// #include <atcoder/all>
// using namespace atcoder;
#define _overload3(_1,_2,_3,name,...) name
#define _rep(i,n) repi(i,0,n)
#define repi(i,a,b) for(int i=int(a);i<int(b);++i)
#define rep(...) _overload3(__VA_ARGS__,repi,_rep,)(__VA_ARGS__)
#define rrep(i,n) for(int i=int(n-1);i>=int(0);--i)
#define fore(i,a) for(auto &i:a)
#define all(x) x.begin(),x.end() 
#define sz(x) ((int)(x).size())
#define bp(x) (__builtin_popcount((long long)(x)))
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define V vector
#define P pair<int,int>
#define TP tuple<int,int,int>
#define F first
#define S second
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return 1; } return 0; }
using ll = long long;
using ld = long double;
using namespace std;
const int INF = 1001001001;
const ll INFL = 1001001001001001001;
const int MAX = 2e6+1;






template<int MOD> struct Fp {
    long long val;
    constexpr Fp(long long v = 0) noexcept : val(v % MOD) {
        if (val < 0) val += MOD;
    }
    constexpr int getmod() { return MOD; }
    constexpr Fp operator - () const noexcept {
        return val ? MOD - val : 0;
    }
    constexpr Fp operator + (const Fp& r) const noexcept { return Fp(*this) += r; }
    constexpr Fp operator - (const Fp& r) const noexcept { return Fp(*this) -= r; }
    constexpr Fp operator * (const Fp& r) const noexcept { return Fp(*this) *= r; }
    constexpr Fp operator / (const Fp& r) const noexcept { return Fp(*this) /= r; }
    constexpr Fp& operator += (const Fp& r) noexcept {
        val += r.val;
        if (val >= MOD) val -= MOD;
        return *this;
    }
    constexpr Fp& operator -= (const Fp& r) noexcept {
        val -= r.val;
        if (val < 0) val += MOD;
        return *this;
    }
    constexpr Fp& operator *= (const Fp& r) noexcept {
        val = val * r.val % MOD;
        return *this;
    }
    constexpr Fp& operator /= (const Fp& r) noexcept {
        long long a = r.val, b = MOD, u = 1, v = 0;
        while (b) {
            long long t = a / b;
            a -= t * b; swap(a, b);
            u -= t * v; swap(u, v);
        }
        val = val * u % MOD;
        if (val < 0) val += MOD;
        return *this;
    }
    constexpr bool operator == (const Fp& r) const noexcept {
        return this->val == r.val;
    }
    constexpr bool operator != (const Fp& r) const noexcept {
        return this->val != r.val;
    }
    friend constexpr ostream& operator << (ostream &os, const Fp<MOD>& x) noexcept {
        return os << x.val;
    }
    friend constexpr Fp<MOD> modpow(const Fp<MOD> &a, long long n) noexcept {
        if (n == 0) return 1;
        auto t = modpow(a, n / 2);
        t = t * t;
        if (n & 1) t = t * a;
        return t;
    }
};
const int MOD = 1000000007;
//const int MOD = 998244353;
using mint = Fp<MOD>;

int main() {
    int n;cin>>n;
    V<ll> a(n);
    rep(i,n)cin>>a[i];
    a.push_back(0);
    sort(all(a));
    mint ans=1;
    rep(i,1,n+1){
        ans*=a[i]-a[i-1]+1;
    }
    cout<<ans<<endl;
    return 0;
}
#include <bits/stdc++.h>

// #include <atcoder/all>
#define rep(i, s, t) for (int i = s; i < t; ++i)
using namespace std;
// using namespace atcoder;

using ll = long long;
using P = pair<int, int>;
constexpr int INF = (int)2e9;
constexpr ll INFll = (ll)1e18;
constexpr int MOD = 1e9 + 7;

struct edge {
  int to, cost;
  edge(int t, int c) : to(t), cost(c) {}
};

vector<vector<edge>> G;
int R, C;

int dijkstra(int s, int t) {
  priority_queue<P, vector<P>, greater<P>> que;
  vector<int> d(2 * R * C, INF);

  que.emplace(s, 0);
  d[s] = 0;

  while (!que.empty()) {
    auto p = que.top();
    que.pop();
    int curd = p.first, curv = p.second;
    if (curd > d[curv]) continue;
    for (auto e : G[curv]) {
      if (curd + e.cost < d[e.to]) {
        d[e.to] = curd + e.cost;
        que.emplace(d[e.to], e.to);
      }
    }
  }
  return d[t];
}

int main() {
  cin >> R >> C;
  G.resize(2 * R * C);
  rep(r, 0, R) rep(c, 0, C - 1) {
    int a;
    cin >> a;
    G[r * C + c].emplace_back(r * C + c + 1, a);
    G[r * C + c + 1].emplace_back(r * C + c, a);
  }
  rep(r, 0, R - 1) rep(c, 0, C) {
    int b;
    cin >> b;
    G[r * C + c].emplace_back((r + 1) * C + c, b);
  }
  rep(r, 0, R) rep(c, 0, C) {
    G[r * C + c].emplace_back(r * C + c + R * C, 1);
    G[r * C + c + R * C].emplace_back(r * C + c, 0);
  }
  rep(r, 0, R - 1) rep(c, 0, C) {
    G[(r + 1) * C + c + R * C].emplace_back(r * C + c + R * C, 1);
  }

  cout << dijkstra(0, R * C - 1) << endl;
}