#include #define fi first #define se second #define p_b push_back #define pll pair #define pii pair #define m_p make_pair #define all(x) x.begin(),x.end() #define sset ordered_set #define sqr(x) (x)*(x) #define pw(x) (1ll << x) #define sz(x) (int)x.size() #define fout(x) {cout << x << "\n"; return; } using namespace std; typedef long long ll; typedef long double ld; const int MAXN = 1123456; const int M = pw(16); const ll inf = 1e18; const long long mod = 1e9 + 7; const long long N = 3e5; template void vout(T s){cout << s << endl;exit(0);} //http://www.e-maxx-ru.1gb.ru/algo/segments_intersection const double EPS = 1E-9; struct pt{ ld x, y; pt(ld a, ld b){ x = a, y = b; } bool operator< (const pt & p) const { return x < p.x-EPS || abs(x-p.x) < EPS && y < p.y - EPS; } }; struct line { double a, b, c; line() {} line (pt p, pt q) { a = p.y - q.y; b = q.x - p.x; c = - a * p.x - b * p.y; norm(); } void norm() { double z = sqrt (a*a + b*b); if (abs(z) > EPS) a /= z, b /= z, c /= z; } double dist (pt p) const { return a * p.x + b * p.y + c; } }; #define det(a,b,c,d) (a*d-b*c) inline bool betw (double l, double r, double x) { return min(l,r) <= x + EPS && x <= max(l,r) + EPS; } inline bool intersect_1d (double a, double b, double c, double d) { if (a > b) swap (a, b); if (c > d) swap (c, d); return max (a, c) <= min (b, d) + EPS; } bool intersect (pt a, pt b, pt c, pt d, pt & left, pt & right) { if (! intersect_1d (a.x, b.x, c.x, d.x) || ! intersect_1d (a.y, b.y, c.y, d.y)) return false; line m (a, b); line n (c, d); double zn = det (m.a, m.b, n.a, n.b); if (abs (zn) < EPS) { if (abs (m.dist (c)) > EPS || abs (n.dist (a)) > EPS) return false; if (b < a) swap (a, b); if (d < c) swap (c, d); left = max (a, c); right = min (b, d); return true; } else { left.x = right.x = - det (m.c, m.b, n.c, n.b) / zn; left.y = right.y = - det (m.a, m.c, n.a, n.c) / zn; return betw (a.x, b.x, left.x) && betw (a.y, b.y, left.y) && betw (c.x, d.x, left.x) && betw (c.y, d.y, left.y); } } //// pt get_point_centre(ll x, ll y){ x--, y--; return pt(x * 2 + 1, y * 2 + 1); } ld dist_my(pt a, pt b){ return sqrt(sqr(a.x - b.x) + sqr(a.y - b.y)); } int main(){ ios_base::sync_with_stdio(0); cin.tie(0); ll w, h, sx, sy, ex, ey; cin >> w >> h >> sx >> sy >> ex >> ey; vector < vector > t(h + 2, vector (w + 2)); for(int i = 1; i <= h / 2; i++){ for(int j = 1; j <= w / 2; j++){ cin >> t[i][j]; } } pt s = pt(sx, sy); pt e = pt(ex, ey); ld ans = dist_my(s, e); ll answer = 0; vector v; vector < int > vl; pt ta=pt(0,0), tb=pt(0,0), tc=pt(0,0), td=pt(0,0), te=pt(0,0), tf=pt(0,0); vector tl(4); for(int i = 1; i <= h / 2; i++){ for(int j = 1; j <= w / 2; j++){ v.clear(); vl.clear(); tl[0] = abs(t[i][j] - t[i][j - 1]); tl[1] = abs(t[i][j] - t[i + 1][j]); tl[2] = abs(t[i][j] - t[i][j + 1]); tl[3] = abs(t[i][j] - t[i - 1][j]); v.p_b(pt(i * 2, j * 2)); v.p_b(pt(i * 2 + 2, j * 2)); v.p_b(pt(i * 2 + 2, j * 2 + 2)); v.p_b(pt(i * 2, j * 2 + 2)); for(int i1 = 0; i1 < 4; i1++){ if(intersect(s, e, v[i1], v[(i1 + 1) % 4], ta, tb)){ vl.p_b(i1); } } if(vl.size() == 4 || (vl.size() == 2 && (((vl[0] + 1) % 4 == vl[1]) || (vl[1] + 1) % 4 == vl[0]))){ if(vl.size() == 2){ answer += min(tl[vl[0]], tl[vl[1]]); }else{ intersect(s, e, v[0], v[1], ta, tb); intersect(s, e, v[1], v[2], tc, td); if(intersect(ta, tb, tc, td, te, tf)){ answer += min(tl[0], tl[1]); answer += min(tl[2], tl[3]); }else{ answer += min(tl[1], tl[2]); answer += min(tl[0], tl[3]); } } }else{ for(auto i1 : vl){ answer += tl[i1]; } } } } ans += answer; cout << fixed << setprecision(5) << ans << "\n"; return 0; }