
// A
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i,n) for(int i = 0; i < n; ++i)

vector<vector<pair<int,int>>> graph(250001);
vector<ll> d_d;
void Dijkstra(int start, int goal, ll t_max){
    d_d.assign(graph.size(), t_max);
    d_d[start] = 0;
    priority_queue<pair<ll,int>, vector<pair<ll,int>>, greater<pair<ll, int>> > que;
    que.emplace(0, start);
    while(!que.empty()){
        ll dist = que.top().first;
        int now = que.top().second;
        que.pop();
        if(d_d[now] < dist) continue;
        if(now == goal) return ; // ここの行を失くせばstart全頂点への距離が求められる
        for(int i = 0; i < graph[now].size(); ++i){
            int next = graph[now][i].first;
            int next_cost = graph[now][i].second;
            if(d_d[next] > d_d[now] + next_cost){
                d_d[next] = d_d[now] + next_cost;
                que.emplace(d_d[next], next);
            }
        }
    }
}

int main(){
    std::cin.tie(0);
    std::ios::sync_with_stdio(false);

    int r, c; cin >> r >> c;

    rep(i, r) {
        rep(j, c-1) {
            int a; cin >> a;
            graph[i*c+j].emplace_back(i*c+j+1, a);
            graph[i*c+j+1].emplace_back(i*c+j, a);
        }
    }

    rep(i, r-1) {
        rep(j, c) {
            int b; cin >> b;
            graph[i*c+j].emplace_back((i+1)*c+j, b);
            rep(k, i) {
                if(i-k-1 >= 0) graph[i*c+j].emplace_back((i-k-1)*c+j, k+2);
            }
        }
    }
    rep(j,c) rep(k, r-1) if(r-k-2 >= 0) graph[(r-1)*c+j].emplace_back((r-k-2)*c+j, k+2);


    Dijkstra(0, r*c-1, (1<<30));

    cout << d_d[r*c-1] << endl;
}
#define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;

//template
#define rep(i,a,b) for(int i=(int)(a);i<(int)(b);i++)
#define ALL(v) (v).begin(),(v).end()
using ll=long long int;
const int inf = 0x3fffffff; const ll INF = 0x1fffffffffffffff; const double eps=1e-12;
template<typename T>inline bool chmax(T& a,T b){if(a<b){a=b;return 1;}return 0;}
template<typename T>inline bool chmin(T& a,T b){if(a>b){a=b;return 1;}return 0;}
//end

using P=pair<int,int>;
bitset<10101> res,used,decide;
vector<P> g[110];
int N,M,cnt[110]={};
void dfs(int v,int p){
   used[v]=1;
   for(auto& [nxt,id]:g[v])if(nxt!=p){
      if(cnt[nxt]==1)continue;
      if(id>=M){
         if(!decide[id-M])res[id-M]=0;
         decide[id-M]=1;
      }
      else{
         if(!decide[id])res[id]=1;
         decide[id]=1;
      }
      cnt[nxt]--;
      if(!used[nxt])dfs(nxt,v);
   }
}

int main(){
   cin>>N>>M;
   vector<P> es(M);
   rep(i,0,M){
      cin>>es[i].first>>es[i].second;
      es[i].first--;
      es[i].second--;
   }
   vector<int> c(N);
   rep(i,0,N)cin>>c[i];

   rep(i,0,M){
      if(c[es[i].first]!=c[es[i].second]){
         res[i]=(c[es[i].first]>c[es[i].second]);
      }
      else{
         g[es[i].first].emplace_back(es[i].second,i);
         g[es[i].second].emplace_back(es[i].first,i+M);
         cnt[es[i].first]++;
         cnt[es[i].second]++;
      }
   }
   rep(i,0,N)if(!used[i])dfs(i,-1);

   rep(i,0,M)cout<<(res[i]?"->":"<-")<<'\n';
   return 0;
}