#include <bits/stdc++.h>
using namespace std;

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

  int n;
  cin >> n;
  vector<pair<int, int>> pos(n);
  for (auto &&[x, y] : pos) {
    cin >> x >> y;
  }
  auto judge = [&](double r) -> bool {
    queue<int> q;
    for (auto i = 0; i != n; ++i) {
      if (100 - r < pos[i].second + r) {
        q.push(i);
      }
    }
    vector<bool> used(n);
    while (!q.empty()) {
      auto id = q.front();
      q.pop();
      if (used[id]) continue;
      used[id] = true;
      for (auto i = 0; i != n; ++i) {
        if (hypot(pos[i].first - pos[id].first,
                  pos[i].second - pos[id].second) < 2 * r) {
          q.push(i);
        }
      }
    }
    for (auto i = 0; i != n; ++i) {
      if (used[i]) {
        if (r - 100 > pos[i].second - r) {
          return false;
        }
      }
    }
    return true;
  };
  constexpr double eps = 1e-4;
  double ok = 0, ng = 100;
  while (ng - ok > eps) {
    auto r = (ok + ng) / 2;
    if (judge(r))
      ok = r;
    else
      ng = r;
  }
  cout << ok << endl;
}

#include<bits/stdc++.h>
using namespace std;
#define rep(i,n) for (int i = 0; i < (n); ++i)
template<typename T> bool chmin(T &a, T b) {if(a>b){a=b; return 1; } return 0; }
int h, w;

#ifndef dijkstra_hpp
#define dijkstra_hpp

#include<vector>
#include<queue>
#include<utility>

struct Dijkstra {
	// Edge: 辺の情報の構造体
	private:
		const long long MAX_DIST = 1e18;
		struct Edge {int to; long long cost; };
		int n;
		std::vector<std::vector<Edge>> es;
		std::vector<long long> dist;
	public:
		Dijkstra(int _n): n(_n), es(_n), dist(_n){}
		void add_edge(int from, int to, long long cost) {
			es[from].push_back(Edge{to, cost});
		}
		void solve(int s) {
			for (int i = 0; i < n; ++i) dist[i] = MAX_DIST;
			dist[s] = 0;
			std::priority_queue<std::pair<long long,int>, std::vector<std::pair<long long,int>>, std::greater<std::pair<long long,int>>> q;
			q.push({0, s});
			while (!q.empty()) {
				auto p = q.top(); q.pop();
				int v = p.second;
				if (dist[v] < p.first) continue;
				if (v >= w) {
					for (int i = 1; i <= v/w; ++i) {
						int to = v - i*w;
						if (chmin(dist[to], dist[v] + i+1)) {
							q.push({dist[to], to});
						}
					}
				}
				for (Edge e: es[v]) {
					if (dist[e.to] > p.first + e.cost) {
						dist[e.to] = p.first + e.cost;
						q.push({dist[e.to], e.to});
					}
				}
			}
		}
		long long get_dist(int t) {
			return dist[t];
		}
};

#endif // dijkstra_hpp

int main() {
	cin >> h >> w;
	Dijkstra g(h*w);
	vector<vector<int>> a(h, vector<int>(w));
	rep(i,h) {
		rep(j,w-1) {
			cin >> a[i][j];
		}
	}
	rep(i,h) {
		rep(j,w) {
			int now = i*w+j;
			if (0 < j) g.add_edge(now, now-1, a[i][j-1]);
			if (j < w-1) g.add_edge(now, now+1, a[i][j]);
		}
	}
	int b;
	rep(i,h-1) {
		rep(j,w) {
			cin >> b;
			int now = i*w+j;
			g.add_edge(now, now+w, b);
		}
	}

	g.solve(0);

	cout << g.get_dist(h*w-1) << endl;
}