
/**
 * Dont raise your voice, improve your argument.
 * --Desmond Tutu
 */
#include <bits/stdc++.h>
using namespace std;

const bool ready = [](){
    ios_base::sync_with_stdio(false); cin.tie(0);
    cout << fixed << setprecision(12);
    return true;
}();

using ld=long double;
const ld PI = acos((ld)-1);
using ll= long long;
#define int ll
#define all(v) (v).begin(), (v).end()
#define fori(n) for(int i=0; i<int(n); i++)

#define cini(i) int i; cin>>i;
#define cins(s) string s; cin>>s;
#define cind(d) ld d; cin>>d;
#define cinai(a,n) vi a(n); fori(n) { cin>>a[i]; }
#define cinas(s,n) vs s(n); fori(n) { cin>>s[i]; }
#define cinad(a,n) vd a(n); fori(n) { cin>>a[i]; }

using pii= pair<int, int>;
using pdd= pair<ld, ld>;
using vd= vector<ld>;
using vb= vector<bool>;
using vi= vector<int>;
using vvi= vector<vi>;
using vs= vector<string>;

#define endl "\n"

using t3=tuple<int,int,int>;

/* dijkstra */
const int INF=1e18;
void solve() {
    cini(n);
    cini(m);
    cini(x); x--;
    cini(y); y--;

    vector<vector<t3>> adj(n);
    for(int i=0; i<m; i++) {
        cini(a); a--;
        cini(b); b--;
        cini(t);
        cini(k);
        adj[a].emplace_back(b,t,k);
        adj[b].emplace_back(a,t,k);
    }

    vi dp(n, INF);
    dp[x]=0;
    priority_queue<pii> q;  /* <-time, vertex> */
    q.emplace(0, x);
    while(q.size()) {
        auto [tt,v]=q.top();
        q.pop();
        if(dp[v]!=-tt)
            continue;

        for(auto [chl,t,k] : adj[v]) {
            int wait=dp[v]%k;
            if(wait==0)
                wait=k;
            wait=k-wait;
            int next=dp[v]+wait+t;
            if(dp[chl]>next) {
                dp[chl]=next;
                q.emplace(-dp[chl], chl);
            }
        }
    }

    if(dp[y]==INF)
        cout<<-1<<endl;
    else
        cout<<dp[y]<<endl;

}

signed main() {
    solve();
}
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
#include <cmath>
#include <iomanip>
#include <stack>
#include <queue>
#include <numeric>
#include <map>
#include <unordered_map>
#include <set>
#include <fstream>
#include <chrono>
#include <random>
#include <bitset>
//#include <atcoder/all>
#define rep(i,n) for(int i=0;i<(n);i++)
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define sz(x) ((int)(x).size())
#define pb push_back
using ll = long long;
using namespace std;
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; }
ll gcd(ll a, ll b) {return b?gcd(b,a%b):a;}
ll lcm(ll a, ll b) {return a/gcd(a,b)*b;}
using vi = vector<int>;
using vvi = vector<vi>;
using vvvi = vector<vvi>;

#define n50 250000

int f(int r,int c){
  return r*500+c;
}

int main(){
  int R,C; cin >> R >> C;
  vvi g(n50);
  vvi co(n50);
  rep(r,R) rep(c,C-1){
    int in; cin >> in;
    int ff=f(r,c);
    g[ff].pb(ff+1);
    g[ff+1].pb(ff);
    co[ff].pb(in);
    co[ff+1].pb(in);
  }
  rep(r,R-1) rep(c,C){
    int in; cin >> in;
    int ff=f(r,c);
    g[ff].pb(ff+500);
    co[ff].pb(in);
  }
  rep(c,C){
    rep(r,R){
      rep(s,r){
        int ff=f(r,c);
        g[ff].pb(f(s,c));
        co[ff].pb(r-s+1);
      }
    }
  }
  vector<int> D(n50, 1e9);
  vector<bool> used(n50, false);
  priority_queue<pair<int,int>,
                 vector<pair<int,int>>,
                 greater<pair<int,int>>> q;
  q.push({0,0});
  while(!q.empty()){
    int d = q.top().first; int to = q.top().second; q.pop();
    if(used[to]) continue;
    used[to] = true; D[to] = d;
    rep(i,sz(g[to])){
      int nxt=g[to][i];
      int nd = D[to] + co[to][i];
      if(D[nxt] <= nd) continue;
      D[nxt] = nd;
      q.push({nd, nxt});
    }
  }

  int ans = D[f(R-1,C-1)];
  cout << ans << endl;
  return 0;
}
