#pragma region

#include <bits/stdc++.h>

#define _GLIBCXX_DEBUG

using namespace std;

using ll = long long;
using ld = long double;
const int INF = INT_MAX;
const ll LLINF = LLONG_MAX;

#define all(x) x.begin(), x.end()

#define rep(i, s, e) for(ll i = s; i < e; ++i)
#define repr(i, s, e) for(ll i = s; i > e; --i)

template <class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template <class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

void CIN() {}
template<class T, class ...Ts> void CIN(T &&t, Ts &&...ts){ cin >> t; CIN(ts...); }
void COUT() { cout << endl; }
template<class T, class ...Ts> void COUT(T &&t, Ts &&...ts){ cout << t << " "; COUT(ts...); }

#pragma endregion

int main()
{
    cin.tie(nullptr);

    string n; cin >> n;
    int len_n = n.size(), max_step = n.size();
    rep(step, 0, max_step) {
        int same = 1;
        rep(idx, 0, len_n / 2) {
            if (n[idx] != n[len_n - idx - 1]) {
                same = 0;
                break;
            }
        }
        if (same) {
            cout << "Yes" << endl;
            return 0;
        } else {
            n = '0' + n;
            len_n ++;
            continue;
        }
    }
    cout << "No" << endl;
    return 0;
}

#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <bitset>
#include <climits>
#include <cmath>
#include <complex>
#include <functional>
#include <cassert>
#include <stack>
#include <numeric>
#include <iomanip>
#include <limits>
#include <random>
#include <unordered_set>

typedef int64_t ll;
typedef std::pair<int, int> Pii;
typedef std::pair<ll, ll> Pll;
typedef std::pair<double, double> Pdd;

#define rip(_i, _n, _s) for (int _i = (_s); _i < (int)(_n); _i++)
#define all(_l) _l.begin(), _l.end()
#define rall(_l) _l.rbegin(), _l.rend()
#define MM << " " <<

template<typename _T>
using MaxHeap = std::priority_queue<_T>;
template<typename _T>
using MinHeap = std::priority_queue<_T, std::vector<_T>, std::greater<_T>>;

template<typename _T>
inline bool chmax(_T &_l, const _T _b) {
    if (_l < _b) {
        _l = _b;
        return true;
    }
    return false;
}
template<typename _T>
inline bool chmin(_T &_l, const _T _b) {
    if (_l > _b) {
        _l = _b;
        return true;
    }
    return false;
}

template<typename _T>
void vdeb(const std::vector<_T> &bb) {
    for (unsigned int i = 0;i < bb.size();i++) {
        if (i == bb.size() - 1) std::cout << bb[i];
        else std::cout << bb[i] << ' ';
    }
    std::cout << '\n';
}
template<typename _T>
void vdeb(const std::vector<std::vector<_T>> &bb) {
    for (unsigned int i = 0;i < bb.size();i++) {
        // std::cout << i << ' ';
        vdeb(bb[i]);
    }
    std::cout << '\n';
}

using namespace std;

int conv(vector<int> &cnt) {
    int ret = 0;
    for(int i : cnt) {
        ret <<= 1;
        ret += (i ? 1: 0);
    }
    return ret;
}

int main() {
    int r, c; cin >> r >> c;
    vector<vector<int>> a(r, vector<int>(c-1));
    vector<vector<int>> b(r-1, vector<int>(c));
    rip(i,r,0) rip(j,c-1,0) cin >> a[i][j];
    rip(i,r-1,0) rip(j,c,0) cin >> b[i][j];
    vector<vector<Pii>> da(r*c*2, vector<Pii>(0));
    rip(i,r,0) rip(j,c,0) {
        int now = i*c+j;
        if(j+1 < c) da[now].push_back({now+1 ,a[i][j]});
        if(0 <= j-1) da[now].push_back({now-1 ,a[i][j-1]});
        if(i+1 < r) da[now].push_back({now+c, b[i][j]});
        da[now].push_back({now+r*c, 1});
        da[now+r*c].push_back({now, 0});
        if(0 <= i-1) da[now+r*c].push_back({now+r*c-c, 1});
    }
    MinHeap<Pii> pq;
    pq.push({0, 0});
    vector<int> used(r*c*2, -1);
    while(!pq.empty()) {
        Pii now = pq.top(); pq.pop();
        if(used[now.second] != -1) continue;
        used[now.second] = now.first;
        for(auto &&i : da[now.second]) {
            pq.push({now.first + i.second, i.first});
        } 
    }
    cout << used[r*c-1] << endl;
}