import java.io.*;
import java.util.*;
import java.util.Map.Entry;

public class E {
	FastScanner in;
	PrintWriter out;
	boolean systemIO = true;

	public class DSU {
		int[] sz;
		int[] p;

		public DSU(int n) {
			sz = new int[n];
			p = new int[n];
			for (int i = 0; i < p.length; i++) {
				p[i] = i;
				sz[i] = 1;
			}
		}

		public int get(int x) {
			if (x == p[x]) {
				return x;
			}
			int par = get(p[x]);
			p[x] = par;
			return par;
		}

		public boolean unite(int a, int b) {
			int pa = get(a);
			int pb = get(b);
			if (pa == pb) {
				return false;
			}
			if (sz[pa] < sz[pb]) {
				p[pa] = pb;
				sz[pb] += sz[pa];
			} else {
				p[pb] = pa;
				sz[pa] += sz[pb];
			}
			return true;
		}
	}

	public class SegmentTreeAdd {
		int pow;
		long[] min;
		long[] delta;
		boolean[] flag;

		public SegmentTreeAdd(long[] a) {
			pow = 1;
			while (pow < a.length) {
				pow *= 2;
			}
			flag = new boolean[2 * pow];
			min = new long[2 * pow];
			delta = new long[2 * pow];
			for (int i = 0; i < min.length; i++) {
				min[i] = Long.MAX_VALUE / 2;
			}
			for (int i = 0; i < a.length; i++) {
				min[pow + i] = a[i];
			}
			for (int i = pow - 1; i > 0; i--) {
				min[i] = f(min[2 * i], min[2 * i + 1]);
			}
		}

		public long get(int l, int r) {
			return get(1, 0, pow, l, r);
		}

		private long get(int v, int tl, int tr, int l, int r) {
			push(v, tl, tr);
			if (l >= tr || r <= tl) {
				return Long.MAX_VALUE / 2;
			}
			if (l <= tl && r >= tr) {
				return min[v];
			}
			int tm = (tl + tr) / 2;
			return f(get(2 * v, tl, tm, l, r), get(2 * v + 1, tm, tr, l, r));
		}

		public void set(int l, int r, long x) {
			set(1, 0, pow, l, r, x);
		}

		private void set(int v, int tl, int tr, int l, int r, long x) {
			push(v, tl, tr);
			if (l >= tr || r <= tl) {
				return;
			}
			if (l <= tl && r >= tr) {
				delta[v] += x;
				flag[v] = true;
				push(v, tl, tr);
				return;
			}
			int tm = (tl + tr) / 2;
			set(2 * v, tl, tm, l, r, x);
			set(2 * v + 1, tm, tr, l, r, x);
			min[v] = f(min[2 * v], min[2 * v + 1]);
		}

		public void push(int v, int tl, int tr) {
			if (flag[v]) {
				if (v < pow) {
					flag[2 * v] = true;
					flag[2 * v + 1] = true;
					delta[2 * v] += delta[v];
					delta[2 * v + 1] += delta[v];
				}
				flag[v] = false;
				min[v] += delta[v];
				delta[v] = 0;
			}
		}

		public long f(long a, long b) {
			return Math.min(a, b);
		}
	}

	public class SegmentTreeSet {
		int pow;
		int[] sum;
		int[] delta;
		boolean[] flag;

		public SegmentTreeSet(int[] a) {
			pow = 1;
			while (pow < a.length) {
				pow *= 2;
			}
			flag = new boolean[2 * pow];
			sum = new int[2 * pow];
			delta = new int[2 * pow];
			for (int i = 0; i < a.length; i++) {
				sum[pow + i] = a[i];
			}
		}

		public int get(int v, int tl, int tr, int l, int r) {
			push(v, tl, tr);
			if (l > r) {
				return 0;
			}
			if (l == tl && r == tr) {
				return sum[v];
			}
			int tm = (tl + tr) / 2;
			return f(get(2 * v, tl, tm, l, Math.min(r, tm)), get(2 * v + 1, tm + 1, tr, Math.max(l, tm + 1), r));
		}

		public void set(int v, int tl, int tr, int l, int r, int x) {
			push(v, tl, tr);
			if (l > tr || r < tl) {
				return;
			}
			if (l <= tl && r >= tr) {
				delta[v] = x;
				flag[v] = true;
				push(v, tl, tr);
				return;
			}
			int tm = (tl + tr) / 2;
			set(2 * v, tl, tm, l, r, x);
			set(2 * v + 1, tm + 1, tr, l, r, x);
			sum[v] = f(sum[2 * v], sum[2 * v + 1]);
		}

		public void push(int v, int tl, int tr) {
			if (flag[v]) {
				if (v < pow) {
					flag[2 * v] = true;
					flag[2 * v + 1] = true;
					delta[2 * v] = delta[v];
					delta[2 * v + 1] = delta[v];
				}
				flag[v] = false;
				sum[v] = delta[v] * (tr - tl + 1);
			}
		}

		public int f(int a, int b) {
			return a + b;
		}
	}

	Random random = new Random();

	public void shuffle(Pair[] a) {
		for (int i = 0; i < a.length; i++) {
			int x = random.nextInt(i + 1);
			Pair t = a[x];
			a[x] = a[i];
			a[i] = t;
		}
	}

	public void sort(int[][] a) {
		for (int i = 0; i < a.length; i++) {
			Arrays.sort(a[i]);
		}
	}

	public void add(HashMap<Long, Integer> map, long l) {
		if (map.containsKey(l)) {
			map.put(l, map.get(l) + 1);
		} else {
			map.put(l, 1);
		}
	}

	public void remove(TreeMap<Integer, Integer> map, Integer s) {
		if (map.get(s) > 1) {
			map.put(s, map.get(s) - 1);
		} else {
			map.remove(s);
		}
	}

	double eps = 1e-10;

	public int signum(double x) {
		if (x > eps) {
			return 1;
		}
		if (x < -eps) {
			return -1;
		}
		return 0;
	}

	public long abs(long x) {
		return x < 0 ? -x : x;
	}

	public long min(long x, long y) {
		return x < y ? x : y;
	}

	public long max(long x, long y) {
		return x > y ? x : y;
	}

	public long gcd(long x, long y) {
		while (y > 0) {
			long c = y;
			y = x % y;
			x = c;
		}
		return x;
	}

	// public class Vector implements Comparable<Vector> {
	// long x;
	// long y;
	// int type;
	// int number;
	//
	// public Vector() {
	// x = 0;
	// y = 0;
	// }
	//
	// public Vector(long x, long y, int type, int number) {
	// this.x = x;
	// this.y = y;
	// this.type = type;
	// this.number = number;
	// }
	//
	// public Vector(long x, long y) {
	//
	// }
	//
	// public Vector(Point begin, Point end) {
	// this(end.x - begin.x, end.y - begin.y);
	// }
	//
	// public void orient() {
	// if (x < 0) {
	// x = -x;
	// y = -y;
	// }
	// if (x == 0 && y < 0) {
	// y = -y;
	// }
	// }
	//
	// public void normalize() {
	// long gcd = gcd(abs(x), abs(y));
	// x /= gcd;
	// y /= gcd;
	// }
	//
	// public String toString() {
	// return x + " " + y;
	// }
	//
	// public boolean equals(Vector v) {
	// return x == v.x && y == v.y;
	// }
	//
	// public boolean collinear(Vector v) {
	// return cp(this, v) == 0;
	// }
	//
	// public boolean orthogonal(Vector v) {
	// return dp(this, v) == 0;
	// }
	//
	// public Vector ort(Vector v) {
	// return new Vector(-y, x);
	// }
	//
	// public Vector add(Vector v) {
	// return new Vector(x + v.x, y + v.y);
	// }
	//
	// public Vector multiply(long c) {
	// return new Vector(c * x, c * y);
	// }
	//
	// public int quater() {
	// if (x > 0 && y >= 0) {
	// return 1;
	// }
	// if (x <= 0 && y > 0) {
	// return 2;
	// }
	// if (x < 0) {
	// return 3;
	// }
	// return 0;
	// }
	//
	// public long len2() {
	// return x * x + y * y;
	// }
	//
	// @Override
	// public int compareTo(Vector o) {
	// if (quater() != o.quater()) {
	// return quater() - o.quater();
	// }
	// return signum(cp(o, this));
	// }
	// }

	// public long dp(Vector v1, Vector v2) {
	// return v1.x * v2.x + v1.y * v2.y;
	// }
	//
	// public long cp(Vector v1, Vector v2) {
	// return v1.x * v2.y - v1.y * v2.x;
	// }

	// public class Line implements Comparable<Line> {
	// Point p;
	// Vector v;
	//
	// public Line(Point p, Vector v) {
	// this.p = p;
	// this.v = v;
	// }
	//
	// public Line(Point p1, Point p2) {
	// if (p1.compareTo(p2) < 0) {
	// p = p1;
	// v = new Vector(p1, p2);
	// } else {
	// p = p2;
	// v = new Vector();
	// }
	// }
	//
	// public boolean collinear(Line l) {
	// return v.collinear(l.v);
	// }
	//
	// public boolean inLine(Point p) {
	// return hv(p) == 0;
	// }
	//
	// public boolean inSegment(Point p) {
	// if (!inLine(p)) {
	// return false;
	// }
	// Point p1 = p;
	// Point p2 = p.add(v);
	// return p1.x <= p.x && p.x <= p2.x && min(p1.y, p2.y) <= p.y && p.y <=
	// max(p1.y, p2.y);
	// }
	//
	// public boolean equalsSegment(Line l) {
	// return p.equals(l.p) && v.equals(l.v);
	// }
	//
	// public boolean equalsLine(Line l) {
	// return collinear(l) && inLine(l.p);
	// }
	//
	// public long hv(Point p) {
	// Vector v1 = new Vector(this.p, p);
	// return cp(v, v1);
	// }
	//
	// public double h(Point p) {
	// Vector v1 = new Vector(this.p, p);
	// return cp(v, v1) / Math.sqrt(v.len2());
	// }
	//
	// public long[] intersectLines(Line l) {
	// if (collinear(l)) {
	// return null;
	// }
	// long[] ans = new long[4];
	//
	// return ans;
	// }
	//
	// public long[] intersectSegment(Line l) {
	// long[] ans = intersectLines(l);
	// if (ans == null) {
	// return null;
	// }
	// Point p1 = p;
	// Point p2 = p.add(v);
	// boolean f1 = p1.x * ans[1] <= ans[0] && ans[0] <= p2.x * ans[1] && min(p1.y,
	// p2.y) * ans[3] <= ans[2]
	// && ans[2] <= max(p1.y, p2.y) * ans[3];
	// p1 = l.p;
	// p2 = l.p.add(v);
	// boolean f2 = p1.x * ans[1] <= ans[0] && ans[0] <= p2.x * ans[1] && min(p1.y,
	// p2.y) * ans[3] <= ans[2]
	// && ans[2] <= max(p1.y, p2.y) * ans[3];
	// if (!f1 || !f2) {
	// return null;
	// }
	// return ans;
	// }
	//
	// @Override
	// public int compareTo(Line o) {
	// return v.compareTo(o.v);
	// }
	// }

	public class Rect {
		long x1;
		long x2;
		long y1;
		long y2;
		int number;

		public Rect(long x1, long x2, long y1, long y2, int number) {
			this.x1 = x1;
			this.x2 = x2;
			this.y1 = y1;
			this.y2 = y2;
			this.number = number;
		}
	}

	public static class Fenvik {
		int[] t;

		public Fenvik(int n) {
			t = new int[n];
		}

		public void add(int x, int delta) {
			for (int i = x; i < t.length; i = (i | (i + 1))) {
				t[i] += delta;
			}
		}

		private int sum(int r) {
			int ans = 0;
			int x = r;
			while (x >= 0) {
				ans += t[x];
				x = (x & (x + 1)) - 1;
			}
			return ans;
		}

		public int sum(int l, int r) {
			return sum(r) - sum(l - 1);
		}
	}

	public class SegmentTreeMaxSum {
		int pow;
		int[] sum;
		int[] maxPrefSum;
		int[] maxSufSum;
		int[] maxSum;

		public SegmentTreeMaxSum(int[] a) {
			pow = 1;
			while (pow < a.length) {
				pow *= 2;
			}
			sum = new int[2 * pow];
			maxPrefSum = new int[2 * pow];
			maxSum = new int[2 * pow];
			maxSufSum = new int[2 * pow];
			for (int i = 0; i < a.length; i++) {
				sum[pow + i] = a[i];
				maxSum[pow + i] = Math.max(a[i], 0);
				maxPrefSum[pow + i] = maxSum[pow + i];
				maxSufSum[pow + i] = maxSum[pow + i];
			}
			for (int i = pow - 1; i > 0; i--) {
				update(i);
			}
		}

		public int[] get(int v, int tl, int tr, int l, int r) {
			if (r <= tl || l >= tr) {
				int[] ans = { 0, 0, 0, 0 };
				return ans;
			}
			if (l <= tl && r >= tr) {
				int[] ans = { maxPrefSum[v], maxSum[v], maxSufSum[v], sum[v] };
				return ans;
			}
			int tm = (tl + tr) / 2;
			int[] left = get(2 * v, tl, tm, l, r);
			int[] right = get(2 * v + 1, tm, tr, l, r);
			int[] ans = { Math.max(left[0], right[0] + left[3]),
					Math.max(left[1], Math.max(right[1], left[2] + right[0])), Math.max(right[2], left[2] + right[3]),
					left[3] + right[3] };
			return ans;
		}

		public void set(int v, int tl, int tr, int x, int value) {
			if (v >= pow) {
				sum[v] = value;
				maxSum[v] = Math.max(value, 0);
				maxPrefSum[v] = maxSum[v];
				maxSufSum[v] = maxSum[v];
				return;
			}
			int tm = (tl + tr) / 2;
			if (x < tm) {
				set(2 * v, tl, tm, x, value);
			} else {
				set(2 * v + 1, tm, tr, x, value);
			}
			update(v);
		}

		public void update(int i) {
			sum[i] = f(sum[2 * i], sum[2 * i + 1]);
			maxSum[i] = Math.max(maxSum[2 * i], Math.max(maxSum[2 * i + 1], maxSufSum[2 * i] + maxPrefSum[2 * i + 1]));
			maxPrefSum[i] = Math.max(maxPrefSum[2 * i], maxPrefSum[2 * i + 1] + sum[2 * i]);
			maxSufSum[i] = Math.max(maxSufSum[2 * i + 1], maxSufSum[2 * i] + sum[2 * i + 1]);
		}

		public int f(int a, int b) {
			return a + b;
		}
	}

	public class Fraction implements Comparable<Fraction> {
		long x;
		long y;

		public Fraction(long x, long y, boolean needNorm) {
			this.x = x;
			this.y = y;
			if (y < 0) {
				this.x *= -1;
				this.y *= -1;
			}
			if (needNorm) {
				long gcd = gcd(this.x, this.y);
				this.x /= gcd;
				this.y /= gcd;
			}
		}

		public Fraction clone() {
			return new Fraction(x, y, false);
		}

		public String toString() {
			return x + "/" + y;
		}

		@Override
		public int compareTo(Fraction o) {
			long res = x * o.y - y * o.x;
			if (res > 0) {
				return 1;
			}
			if (res < 0) {
				return -1;
			}
			return 0;
		}
	}

	public class Event implements Comparable<Event> {
		Fraction f;
		int type;

		public Event(Fraction f, int type) {
			this.f = f;
			this.type = type;
		}

		@Override
		public int compareTo(Event o) {
			int c = f.compareTo(o.f);
			if (c != 0) {
				return c;
			}
			return type - o.type;
		}

	}

	public double sq(double x) {
		return x * x;
	}

	public long sq(long x) {
		return x * x;
	}

	public double hypot2(double x, double y) {
		return sq(x) + sq(y);
	}

	public long hypot2(long x, long y) {
		return sq(x) + sq(y);
	}

	public boolean kuhn(int v, int[][] edge, boolean[] used, int[] mt) {
		used[v] = true;
		for (int u : edge[v]) {
			if (mt[u] < 0 || (!used[mt[u]] && kuhn(mt[u], edge, used, mt))) {
				mt[u] = v;
				return true;
			}
		}
		return false;
	}

	public int matching(int[][] edge) {
		int n = edge.length;
		int[] mt = new int[n];
		Arrays.fill(mt, -1);
		boolean[] used = new boolean[n];
		int ans = 0;
		for (int i = 0; i < n; i++) {
			if (!used[i] && kuhn(i, edge, used, mt)) {
				Arrays.fill(used, false);
				ans++;
			}
		}
		return ans;
	}

	double sq2 = Math.sqrt(2);

	public class MyStack {
		int[] st;
		int sz;

		public MyStack(int n) {
			this.st = new int[n];
			sz = 0;
		}

		public boolean isEmpty() {
			return sz == 0;
		}

		public int peek() {
			return st[sz - 1];
		}

		public int pop() {
			sz--;
			return st[sz];
		}

		public void clear() {
			sz = 0;
		}

		public void add(int x) {
			st[sz++] = x;
		}

		public int get(int x) {
			return st[x];
		}
	}

	public int[][] readGraph(int n, int m) {
		int[][] to = new int[n][];
		int[] sz = new int[n];
		int[] x = new int[m];
		int[] y = new int[m];
		for (int i = 0; i < m; i++) {
			x[i] = in.nextInt() - 1;
			y[i] = in.nextInt() - 1;
			sz[x[i]]++;
			sz[y[i]]++;
		}
		for (int i = 0; i < to.length; i++) {
			to[i] = new int[sz[i]];
			sz[i] = 0;
		}
		for (int i = 0; i < x.length; i++) {
			to[x[i]][sz[x[i]]++] = y[i];
			to[y[i]][sz[y[i]]++] = x[i];
		}
		return to;
	}

	public class Pol {
		double[] coeff;

		public Pol(double[] coeff) {
			this.coeff = coeff;
		}

		public Pol mult(Pol p) {
			double[] ans = new double[coeff.length + p.coeff.length - 1];
			for (int i = 0; i < ans.length; i++) {
				for (int j = Math.max(0, i - p.coeff.length + 1); j < coeff.length && j <= i; j++) {
					ans[i] += coeff[j] * p.coeff[i - j];
				}
			}
			return new Pol(ans);
		}

		public String toString() {
			String ans = "";
			for (int i = 0; i < coeff.length; i++) {
				ans += coeff[i] + " ";
			}
			return ans;
		}

		public double value(double x) {
			double ans = 0;
			double p = 1;
			for (int i = 0; i < coeff.length; i++) {
				ans += coeff[i] * p;
				p *= x;
			}
			return ans;
		}

		public double integrate(double r) {
			Pol p = new Pol(new double[coeff.length + 1]);
			for (int i = 0; i < coeff.length; i++) {
				p.coeff[i + 1] = coeff[i] / fact[i + 1];
			}
			return p.value(r);
		}

		public double integrate(double l, double r) {
			return integrate(r) - integrate(l);
		}
	}

	int mod = 1000000007;

	public int sum(int a, int b) {
		if (a + b >= mod) {
			return a + b - mod;
		}
		return a + b;
	}

	public int diff(int a, int b) {
		if (a < b) {
			return a + mod - b;
		}
		return a - b;
	}

	public int mult(int a, int b) {
		return (int) ((a * 1L * b) % (1L * mod));
	}

	public int pow(int x, int p) {
		if (p <= 0) {
			return 1;
		}
		int ans = pow(x, p / 2);
		ans = mult(ans, ans);
		if (p % 2 == 1) {
			ans = mult(ans, x);
		}
		return ans;
	}

	public int modInv(int x) {
		return pow(x, mod - 2);
	}

	public int c_n_k(int n, int k) {
		if (n < 0 || k < 0 || n - k < 0) {
			return 0;
		}
		return mult(fact[n], mult(factInv[k], factInv[n - k]));
	}

	public class LinAl01 {

		public class Vector {
			BitSet vec;
			BitSet swtch;

			public Vector(BitSet vec, BitSet swtch) {
				this.vec = vec;
				this.swtch = swtch;
			}

			public String toString() {
				String s = "";
				for (int i = 0; i < basis.length; i++) {
					s += (vec.get(i) ? 1 : 0);
				}
				s += " ";
				for (int i = 0; i < basis.length; i++) {
					s += (swtch.get(i) ? 1 : 0);
				}
				return s;
			}
		}

		int n;
		Vector[] basis;

		public void update(Vector v) {
			for (int i = 0; i < n; i++) {
				if (v.vec.get(i)) {
					if (basis[i] == null) {
						basis[i] = v;
						break;
					}
					v.vec.xor(basis[i].vec);
					v.swtch.xor(basis[i].swtch);
				}
			}
		}

		public void diagonalize() {
			for (int i = 0; i < n; i++) {
				if (basis[i] == null) {
					continue;
				}
				for (int j = 0; j < i; j++) {
					if (basis[j] != null && basis[j].vec.get(i)) {
						basis[j].vec.xor(basis[i].vec);
						basis[j].swtch.xor(basis[i].swtch);
					}
				}
			}
		}

	}

	public class Point implements Comparable<Point> {
		double x;
		double y;

		public Point() {
			x = 0;
			y = 0;
		}

		public Point(double x, double y) {
			this.x = x;
			this.y = y;
		}

		public String toString() {
			return x + " " + y;
		}

		public boolean equals(Point p) {
			return x == p.x && y == p.y;
		}

		public double dist2() {
			return x * x + y * y;
		}

		public Point add(Point v) {
			return new Point(x + v.x, y + v.y);
		}

		public Point subtract(Point v) {
			return new Point(x - v.x, y - v.y);
		}

		@Override
		public int compareTo(Point o) {
			int z = signum(x + y - o.x - o.y);
			if (z != 0) {
				return z;
			}
			return signum(x - o.x) != 0 ? signum(x - o.x) : signum(y - o.y);
		}
	}

	public class Circle {
		Point p;
		long r;

		public Circle(Point p, long r) {
			this.p = p;
			this.r = r;
		}

		public boolean intersect(Line l) {
			return Math.abs(l.a * p.x + l.b * p.y + l.c) / Math.hypot(l.a, l.b) < r;
		}

		public boolean inside(Point p) {
			return hypot2(p.x - this.p.x, p.y - this.p.y) <= sq(r);
		}
	}

	public class Line {
		long a;
		long b;
		long c;

		public Line(long a, long b, long c) {
			if (a < 0 || (a == 0 && b < 0)) {
				a = -a;
				b = -b;
				c = -c;
				long gcd = gcd(a, Math.abs(b));
				a /= gcd;
				b /= gcd;
			}
			this.a = a;
			this.b = b;
			this.c = c;
		}

		public String toString() {
			return a + " " + b + " " + c;
		}

//    public Line(Point a, Point b) {
//      this.a = a.y - b.y;
//      this.b = b.x - a.x;
//      this.c = a.x * b.y - a.y * b.x;
//    }
	}

//  public long compareDist(Circle a, Circle b, Circle c) { // tangent to a, b; a.r, b.r may be < 0
//    long x = b.p.x - a.p.x;
//    long y = b.p.y - a.p.y;
//    long r = b.r - a.r;
//    long dx = c.p.x - a.p.x;
//    long dy = c.p.y - a.p.y;
//    long dr = c.r - a.r;
//    long left = y * dx - x * dy;
//    long sqrt = x * x + y * y - r * r;
//    long right = dr * (x * x + y * y) - r * (x * dx + y * dy);
//    if (sqrt == 0 || left == 0) {
//      if (right > 0) {
//        return -1;
//      }
//      if (right < 0) {
//        return 1;
//      }
//      return 0;
//    }
//    if (right == 0) {
//      if (left > 0) {
//        return 1;
//      }
//      return -1;
//    }
//    if (left > 0 && right < 0) {
//      return 1;
//    }
//    if (left < 0 && right > 0) {
//      return -1;
//    }
//    int mult = 1;
//    if (left < 0) {
//      mult = -1;
//    }
//    return BigInteger.valueOf(left).pow(2).multiply(BigInteger.valueOf(sqrt))
//        .compareTo(BigInteger.valueOf(right).pow(2)) * mult;
//  }

//  public boolean inOrTang(Circle a, Circle b, Circle c) {
//    return compareDist(a, b, c) <= 0 && compareDist(a, b, new Circle(c.p, -c.r)) >= 0;
//  }

//  public boolean in(Circle a, Circle b, Circle c) {
//    return compareDist(a, b, c) < 0 && compareDist(a, b, new Circle(c.p, -c.r)) > 0;
//  }

	public long sqr(long a) {
		return a * a;
	}

//  public void tangents(Point c, long r1, long r2, ArrayList<Line> ans) {
//    long r = r2 - r1;
//    long z = sqr(c.x) + sqr(c.y);
//    long delta = z - sqr(r);
//    if (delta <= 0) {
//      return;
//    }
//    double d = Math.sqrt(Math.abs(delta));
//    Line l = new Line((c.x * r + c.y * d) / z, (c.y * r - c.x * d) / z, r1);
//    if (r1 * r2 >= 0) {
//      ans.add(new Line(l.a, l.b, l.c + eps));
//      ans.add(new Line(l.a, l.b, l.c - eps));
//    } else {
//      double sqrt = Math.hypot(c.x, c.y);
//      double da = eps * c.y / sqrt;
//      double db = -eps * c.x / sqrt;
//      ans.add(new Line(l.a + da, l.b + db, l.c));
//      ans.add(new Line(l.a - da, l.b - db, l.c));
//    }
//  }

//  public ArrayList<Line> tangents(Circle a, Circle b) {
//    ArrayList<Line> ans = new ArrayList<>();
//    for (int i = -1; i <= 1; i += 2) {
//      for (int j = -1; j <= 1; j += 2) {
//        tangents(b.p.subtract(a.p), a.r * i, b.r * j, ans);
//      }
//    }
//    for (int i = 0; i < ans.size(); ++i) {
//      ans.get(i).c -= ans.get(i).a * a.p.x + ans.get(i).b * a.p.y;
//    }
//    return ans;
//  }

	int[] fact = new int[1000001];
	int[] factInv = new int[1000001];

	public int[] intersect(int y, int xdown, int ydown, int xup, int yup) {
		if (yup < y || ydown > y || (ydown == yup)) {
			return null;
		}
		long p = xup * 1L * (y - ydown) + xdown * 1L * (yup - y);
		if (p < 0) {
			int[] ans = { -1, 0 };
			return ans;
		}
		long q = 2 * (yup - ydown);
		int[] ans = { (int) (p / q), (int) ((p + q - 1) / q) };
		return ans;
	}

	public void I(int[][] a) {
		for (int i = 0; i < a.length; i++) {
			int[] b = new int[a.length];
			for (int j = 0; j < b.length; j++) {
				b[a[i][j]] = j;
			}
			a[i] = b;
		}
	}

	public void C(int[][] a) {
		for (int i = 0; i < a.length; i++) {
			int[] b = new int[a.length];
			for (int j = 0; j < b.length; j++) {
				b[a[j][i]] = j;
			}
			for (int j = 0; j < b.length; j++) {
				a[j][i] = b[j];
			}
		}
	}

	public class SegmentTree {
		int pow;
		Pair[] min;

		public SegmentTree(int[] a) {
			pow = 1;
			while (pow < a.length) {
				pow *= 2;
			}
			min = new Pair[2 * pow];
			for (int i = 0; i < a.length; i++) {
				min[pow + i] = new Pair(a[i], i);
			}
			for (int i = a.length; i < pow; i++) {
				min[pow + i] = new Pair(Integer.MAX_VALUE / 2, -1);
			}
			for (int i = pow - 1; i > 0; i--) {
				min[i] = f(min[2 * i], min[2 * i + 1]);
			}
		}

		public Pair get(int l, int r) {
			return get(1, 0, pow, l, r);
		}

		private Pair get(int v, int tl, int tr, int l, int r) {
			if (l >= tr || r <= tl) {
				return new Pair(Integer.MAX_VALUE / 2, -1);
			}
			if (l <= tl && r >= tr) {
				return min[v];
			}
			int tm = (tl + tr) / 2;
			return f(get(2 * v, tl, tm, l, r), get(2 * v + 1, tm, tr, l, r));
		}

		public void set(int x, int value) {
			set(1, 0, pow, x, value);
		}

		private void set(int v, int tl, int tr, int x, int value) {
			if (x >= tr || x < tl) {
				return;
			}
			if (v >= pow) {
				min[v] = new Pair(value, -1);
				return;
			}
			int tm = (tl + tr) / 2;
			set(2 * v, tl, tm, x, value);
			set(2 * v + 1, tm, tr, x, value);
			min[v] = f(min[2 * v], min[2 * v + 1]);
		}

		public Pair f(Pair a, Pair b) {
			if (a.compareTo(b) <= 0) {
				return a.clone();
			}
			return b.clone();
		}
	}

	public boolean nextPermutation(int[] a) {
		int n = a.length;
		for (int i = n - 2; i >= 0; i--) {
			if (a[i] < a[i + 1]) {
				for (int d = 1; d <= (n - 1 - i) / 2; d++) {
					a[i + d] ^= a[n - d];
					a[n - d] = a[i + d] ^ a[n - d];
					a[i + d] = a[i + d] ^ a[n - d];
				}
				for (int j = i + 1; j < n; j++) {
					if (a[j] > a[i]) {
						a[i] ^= a[j];
						a[j] = a[i] ^ a[j];
						a[i] = a[i] ^ a[j];
						return true;
					}
				}
			}
		}
		return false;
	}

	public class Pair implements Comparable<Pair> {
		int x;
		int y;

		public Pair(int x, int y) {
			this.x = x;
			this.y = y;
		}

		public Pair add(Pair p) {
			return new Pair(x + p.x, y + p.y);
		}

		public Pair clone() {
			return new Pair(x, y);
		}

		public String toString() {
			return x + " " + y;
		}

		@Override
		public int compareTo(Pair o) {
			if (x < o.x) {
				return -1;
			}
			if (x > o.x) {
				return 1;
			}
			if (y > o.y) {
				return 1;
			}
			if (y < o.y) {
				return -1;
			}
			return 0;
		}
	}

	public double intersection(Pair p1, Pair p2) {
		return (p2.y - p1.y) * 1.0 / (p1.x - p2.x);
	}

	HashMap<Integer, Integer> even = new HashMap<>();
	HashMap<Integer, Integer> odd = new HashMap<>();

	public void addOdd(int key, int value) {
		if (odd.containsKey(key)) {
			odd.put(key, Math.min(odd.get(key), value));
		} else {
			odd.put(key, value);
		}
	}

	public void addEven(int key, int value) {
		if (even.containsKey(key)) {
			even.put(key, Math.min(even.get(key), value));
		} else {
			even.put(key, value);
		}
	}

	public void solve() {
		int n = in.nextInt();
		int m = in.nextInt();
		int k = in.nextInt();
//		int n = 500;
//		int m = 500;
//		int k = 20;
		if (k % 2 == 1) {
			for (int i = 0; i < n; i++) {
				for (int j = 0; j < m; j++) {
					out.print(-1 + " ");
				}
				out.println();
			}
			return;
		}
		k /= 2;
		int[][] hor = new int[n][m - 1];
		for (int i = 0; i < hor.length; i++) {
			for (int j = 0; j < hor[0].length; j++) {
				hor[i][j] = in.nextInt() * 2;
//				hor[i][j] = random.nextInt(1000000) + 1;
			}
		}
		int[][] vert = new int[n - 1][m];
		for (int i = 0; i < vert.length; i++) {
			for (int j = 0; j < vert[0].length; j++) {
				vert[i][j] = in.nextInt() * 2;
//				vert[i][j] = random.nextInt(1000000) + 1;
			}
		}
		long time = System.currentTimeMillis();
		int[][][] ans = new int[k + 1][n][m];
		for (int l = 1; l <= k; l++) {
			for (int i = 0; i < n; i++) {
				for (int j = 0; j < m; j++) {
					ans[l][i][j] = Integer.MAX_VALUE;
					if (i > 0) {
						ans[l][i][j] = Math.min(ans[l][i][j], ans[l - 1][i - 1][j] + vert[i - 1][j]);
					}
					if (j > 0) {
						ans[l][i][j] = Math.min(ans[l][i][j], ans[l - 1][i][j - 1] + hor[i][j - 1]);
					}
					if (i < n - 1) {
						ans[l][i][j] = Math.min(ans[l][i][j], ans[l - 1][i + 1][j] + vert[i][j]);
					}
					if (j < m - 1) {
						ans[l][i][j] = Math.min(ans[l][i][j], ans[l - 1][i][j + 1] + hor[i][j]);
					}
				}
			}
		}
//		for (int i = 0; i < n; i++) {
//			for (int j = 0; j < m; j++) {
//				even.clear();
//				odd.clear();
//				even.put(i * m + j, 0);
//				for (int l = 0; l < k; l++) {
//					if (l % 2 == 0) {
//						odd.clear();
//						for (Entry<Integer, Integer> e : even.entrySet()) {
//							int x = e.getKey() / m;
//							int y = e.getKey() % m;
//							int value = e.getValue();
//							if (x > 0) {
//								addOdd((x - 1) * m + y, value + vert[x - 1][y]);
//							}
//							if (y > 0) {
//								addOdd(x * m + y - 1, value + hor[x][y - 1]);
//							}
//							if (x < n - 1) {
//								addOdd((x + 1) * m + y, value + vert[x][y]);
//							}
//							if (y < m - 1) {
//								addOdd(x * m + y + 1, value + hor[x][y]);
//							}
//						}
//					} else {
//						even.clear();
//						for (Entry<Integer, Integer> e : odd.entrySet()) {
//							int x = e.getKey() / m;
//							int y = e.getKey() % m;
//							int value = e.getValue();
//							if (x > 0) {
//								addEven((x - 1) * m + y, value + vert[x - 1][y]);
//							}
//							if (y > 0) {
//								addEven(x * m + y - 1, value + hor[x][y - 1]);
//							}
//							if (x < n - 1) {
//								addEven((x + 1) * m + y, value + vert[x][y]);
//							}
//							if (y < m - 1) {
//								addEven(x * m + y + 1, value + hor[x][y]);
//							}
//						}
//					}
//				}
//				ans[i][j] = Integer.MAX_VALUE;
//				if (k % 2 == 0) {
//					for (Entry<Integer, Integer> e : even.entrySet()) {
//						ans[i][j] = Math.min(ans[i][j], e.getValue() * 2);
//					}
//				} else {
//					for (Entry<Integer, Integer> e : odd.entrySet()) {
//						ans[i][j] = Math.min(ans[i][j], e.getValue() * 2);
//					}
//				}
//			}
//		}
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				out.print(ans[k][i][j] + " ");
			}
			out.println();
		}
		System.err.println(System.currentTimeMillis() - time);
	}

	public void add(HashMap<Integer, Integer> map, int x) {
		if (map.containsKey(x)) {
			map.put(x, map.get(x) + 1);
		} else {
			map.put(x, 1);
		}
	}

	public void run() {
		try {
			if (systemIO) {
				in = new FastScanner(System.in);
				out = new PrintWriter(System.out);
			} else {
				in = new FastScanner(new File("input.txt"));
				out = new PrintWriter(new File("output.txt"));
			}
			solve();

			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	class FastScanner {
		BufferedReader br;
		StringTokenizer st;

		FastScanner(File f) {
			try {
				br = new BufferedReader(new FileReader(f));
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
		}

		FastScanner(InputStream f) {
			br = new BufferedReader(new InputStreamReader(f));
		}

		String nextLine() {
			try {
				return br.readLine();
			} catch (IOException e) {
				return null;
			}
		}

		String next() {
			while (st == null || !st.hasMoreTokens()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			return st.nextToken();
		}

		int nextInt() {
			return Integer.parseInt(next());
		}

		long nextLong() {
			return Long.parseLong(next());
		}

		double nextDouble() {
			return Double.parseDouble(next());
		}

	}

	// AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	public static void main(String[] arg) {
		new E().run();
	}
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.StringTokenizer;

/*
height == 2, width == 3

2 3 2
1 1
1 1
1 1 1
 */
public class D {

	public static void main(String[] args) {
		FastScanner fs=new FastScanner();
		int h=fs.nextInt(), w=fs.nextInt(), k=fs.nextInt();
		PrintWriter out=new PrintWriter(System.out);
		if (k%2==1) {
			for (int y=0; y<h; y++) {
				for (int x=0; x<w; x++) {
					if (x!=0) out.print(" ");
					out.print(-1);
				}
				out.println();
			}
			out.close();
			return;
		}
		k/=2;

		int[][] rightCost=new int[w-1][h];
		int[][] downCost=new int[w][h-1];
		for (int y=0; y<h; y++)
			for (int x=0; x<w-1; x++)
				rightCost[x][y]=fs.nextInt();
		for (int y=0; y<h-1; y++)
			for (int x=0; x<w; x++)
				 downCost[x][y]=fs.nextInt();

		long[][] dp=new long[w][h];
		long[][] dpNext=new long[w][h];
		for (int i=0; i<k; i++) {
			for (int x=0; x<w; x++) {
				for (int y=0; y<h; y++) {
					long ans=(long)1e18;
					if (x!=0) ans=Math.min(ans, dp[x-1][y]+rightCost[x-1][y]);
					if (y!=0) ans=Math.min(ans, dp[x][y-1]+downCost[x][y-1]);
					if (x!=w-1) ans=Math.min(ans, dp[x+1][y]+rightCost[x][y]);
					if (y!=h-1) ans=Math.min(ans, dp[x][y+1]+downCost[x][y]);
					dpNext[x][y]=ans;
				}
			}
			dp=dpNext;
			dpNext=new long[w][h];
		}
		//TODO: double answer
		for (int y=0; y<h; y++) {
			for (int x=0; x<w; x++) {
				if (x!=0) out.print(" ");
				out.print(2*dp[x][y]);
			}
			out.println();
		}
		out.close();
	}

	static void sort(int[] a) {
		ArrayList<Integer> l=new ArrayList<>();
		for (int i:a) l.add(i);
		Collections.sort(l);
		for (int i=0; i<a.length; i++) a[i]=l.get(i);
	}

	static class FastScanner {
		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st=new StringTokenizer("");
		String next() {
			while (!st.hasMoreTokens())
				try {
					st=new StringTokenizer(br.readLine());
				} catch (IOException e) {
					e.printStackTrace();
				}
			return st.nextToken();
		}

		int nextInt() {
			return Integer.parseInt(next());
		}
		int[] readArray(int n) {
			int[] a=new int[n];
			for (int i=0; i<n; i++) a[i]=nextInt();
			return a;
		}
		long nextLong() {
			return Long.parseLong(next());
		}
	}

}


import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
	public static void main(String[] args)throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringBuilder sb = new StringBuilder();

		//idea 1 : K/2번까지만 실행해서, 그 최솟값 *2를 하면 된다
		//bfs로 i,j칸에 크거나 같은 값을 가지고 진입하면, 즉시 cut
		StringTokenizer st = new StringTokenizer(br.readLine(), " ");
		n = pint(st.nextToken());
		m = pint(st.nextToken());
		k = pint(st.nextToken());

		//up down left right
		//0 is wall
		map = new int[n][m][4];
		for (int i = 0; i < n; i++) {
			st = new StringTokenizer(br.readLine(), " ");
			for (int j = 0; j < m-1; j++) {
				int temp = pint(st.nextToken());
				map[i][j][3]=temp;
				map[i][j+1][2]=temp;
			}
		}
		for (int i = 0; i < n-1; i++) {
			st = new StringTokenizer(br.readLine(), " ");
			for (int j = 0; j < m; j++) {
				int temp = pint(st.nextToken());
				map[i][j][1]=temp;
				map[i+1][j][0]=temp;
			}
		}

		ans = new int[n][m][k/2+1];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				if(k%2==1) {
					sb.append("-1 ");
					continue;
				}

				int min=rec(i,j,0,k/2);

				sb.append(min*2).append(" ");

			}sb.append("\n");
		}

		System.out.println(sb);

	}
	static int n,m,k;
	//up down left right
	static int[]dx = {-1,1, 0, 0};
	static int[]dy = {0, 0, -1,1};
	static int[][][]map;
	static int[][][]ans;

	static int rec(int x, int y, int cost, int cnt) {
		if(cnt==0) {
			return 0;
		}
		if(ans[x][y][cnt]!=0)return ans[x][y][cnt];

		int temp=Integer.MAX_VALUE;
		for (int i = 0; i < 4; i++) {
			int tx=x+dx[i], ty=y+dy[i];

			if(tx<0||tx>=n||ty<0||ty>=m)continue;

			if(map[x][y][i]!=0) {
				temp=Math.min(temp, rec(tx, ty, cost, cnt-1)+map[x][y][i]);
			}
		}
		ans[x][y][cnt]=temp;

		return ans[x][y][cnt];
	}

	static int pint(String s) {
		return Integer.parseInt(s);
	}
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.*;

public class Practice {
	public static long mod = (long) Math.pow(10, 9) + 7;
	public static long[][][]dp;
	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		PrintWriter pw = new PrintWriter(System.out);

		// int t = Integer.parseInt(br.readLine());
//		while (t-- > 0) {
		String[] s2 = br.readLine().split(" ");
		int n = Integer.parseInt(s2[0]);
		int m = Integer.parseInt(s2[1]);
		int k = Integer.parseInt(s2[2]);
		dp=new long[n][m][k+1];
		int[][] hori = new int[n][m - 1];
		int[][] verti = new int[n - 1][m];
		for (int i = 0; i < n; i++) {
			String str = (br.readLine());
			String[] s1 = str.split(" ");
			for (int j = 0; j < m - 1; j++) {
				hori[i][j] = Integer.parseInt(s1[j]);
			}
		}
		for (int i = 0; i < n - 1; i++) {
			String str = (br.readLine());
			String[] s1 = str.split(" ");
			for (int j = 0; j < m; j++) {
				verti[i][j] = Integer.parseInt(s1[j]);
			}
		}
		long[][]ans=new long[n][m];
		if(k%2!=0) {
			for(int i=0;i<n;i++) {
				for(int j=0;j<m;j++) {
					ans[i][j]=-1;
				}
			}
		}else {
			for(int i=0;i<n;i++) {
				for(int j=0;j<m;j++) {
					ans[i][j]=findAns(i,j,k,hori,verti,n,m,Integer.MAX_VALUE);
				}
			}
		}
		for(int i=0;i<n;i++) {
			StringBuilder str=new StringBuilder();
			for(int j=0;j<m;j++) {
				str.append(ans[i][j]+" ");
			}pw.println(str.toString());
		}
		// }

		pw.close();
	}

	private static long findAns(int i, int j, int k, int[][] hori, int[][] verti, int n, int m, int last) {
		// TODO Auto-generated method stub
		if(k==0) {
			return 0;
		}
		if(i<n&&j<m&&i>=0&&j>=0) {

		}else {
			return 100000000;
		}
	//	System.out.println(i+" "+j+" "+k);
		if(dp[i][j][k]!=0) {
			return dp[i][j][k];
		}
		long ans=k*((long)last);
		if(j>0) {
			long curr=2*hori[i][j-1];
			curr+=findAns(i, j-1, k-2, hori, verti, n, m, hori[i][j-1]);
			ans=Math.min(ans, curr);
		}
	//	System.out.println(ans+" 0");
		if(j<m-1) {
			long curr=2*hori[i][j];
			curr+=findAns(i, j+1, k-2, hori, verti, n, m, hori[i][j]);
			ans=Math.min(ans, curr);
		}
	//	System.out.println(ans+" 1");
		if(i>0) {
			long curr=2*verti[i-1][j];
			curr+=findAns(i-1, j, k-2, hori, verti, n, m, verti[i-1][j]);
			ans=Math.min(ans, curr);
		}
	//	System.out.println(ans+" 2");
		if(i<n-1) {
			long curr=2*verti[i][j];
			curr+=findAns(i+1, j, k-2, hori, verti, n, m, verti[i][j]);
			ans=Math.min(ans, curr);
		}
	//	System.out.println(ans+" 3");
		dp[i][j][k]=ans;
		return ans;
	}
}

//private static long getGCD(long l, long m) {
//// TODO Auto-generated method stub
//
//long t1 = Math.min(l, m);
//long t2 = Math.max(l, m);
//while (true) {
//	long temp = t2 % t1;
//	if (temp == 0) {
//		return t1;
//	}
//	t2 = t1;
//	t1 = temp;
//}
//}


import java.util.*;
import java.io.*;

public class _1517_D {
    public static void main(String[] args) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter out = new PrintWriter(System.out);
        StringTokenizer line = new StringTokenizer(in.readLine());
        int n = Integer.parseInt(line.nextToken());
        int m = Integer.parseInt(line.nextToken());
        int k = Integer.parseInt(line.nextToken());
        int[][] edges1 = new int[n][m - 1];
        int[][] edges2 = new int[n - 1][m];
        for(int i = 0; i < n; i++) {
            line = new StringTokenizer(in.readLine());
            for(int j = 0; j < m - 1; j++) {
                edges1[i][j] = Integer.parseInt(line.nextToken());
            }
        }
        for(int i = 0; i < n - 1; i++) {
            line = new StringTokenizer(in.readLine());
            for(int j = 0; j < m; j++) {
                edges2[i][j] = Integer.parseInt(line.nextToken());
            }
        }
        if(k % 2 == 1) {
            for(int i = 0; i < n; i++) {
                StringBuilder sb = new StringBuilder();
                for (int j = 0; j < m; j++) {
                    sb.append(-1);
                    if(j < m - 1) sb.append(' ');
                }
                out.println(sb.toString());
            }
        }else {
            int[][][] dp = new int[n][m][k + 1];
            for(int i = 0; i < n; i++) {
                for(int j = 0; j < m; j++) {
                    Arrays.fill(dp[i][j], Integer.MAX_VALUE);
                    dp[i][j][0] = 0;
                }
            }
            for(int a = 2; a <= k; a += 2) {
                for(int i = 0; i < n; i++) {
                    for(int j = 0; j < m; j++) {
                        if(i > 0) {
                            dp[i][j][a] = Math.min(dp[i][j][a], dp[i - 1][j][a - 2] + 2 * edges2[i - 1][j]);
                        }
                        if(i < n - 1) {
                            dp[i][j][a] = Math.min(dp[i][j][a], dp[i + 1][j][a - 2] + 2 * edges2[i][j]);
                        }
                        if(j > 0) {
                            dp[i][j][a] = Math.min(dp[i][j][a], dp[i][j - 1][a - 2] + 2 * edges1[i][j - 1]);
                        }
                        if(j < m - 1) {
                            dp[i][j][a] = Math.min(dp[i][j][a], dp[i][j + 1][a - 2] + 2 * edges1[i][j]);
                        }
                    }
                }
            }
            for(int i = 0; i < n; i++) {
                StringBuilder sb = new StringBuilder();
                for(int j = 0; j < m; j++) {
                    sb.append(dp[i][j][k]);
                    if(j < m - 1) sb.append(' ');
                }
                out.println(sb.toString());
            }
        }
        in.close();
        out.close();
    }
}


/*
bts songs to dance to:
I need U
Run
ON
Filter
I'm fine
 */
import static java.lang.Math.max;
import static java.lang.Math.min;
import static java.lang.Math.abs;

import java.util.*;
import java.io.*;

public class x1517D2
{
    static final int INF = Integer.MAX_VALUE/3;
    public static void main(String hi[]) throws Exception
    {
        FastScanner infile = new FastScanner();
        int N = infile.nextInt();
        int M = infile.nextInt();
        int K = infile.nextInt();
        int[][] weights1 = new int[N][M-1];
        for(int r=0; r < N; r++)
            weights1[r] = infile.nextInts(M-1);
        int[][] weights2 = new int[N-1][M];
        for(int r=0; r < N-1; r++)
            weights2[r] = infile.nextInts(M);
        //all are -1 if K is odd
        int[][] res = new int[N][M];
        if(K%2 == 1)
        {
            StringBuilder sb = new StringBuilder();
            for(int r=0; r < N; r++)
            {
                for(int c=0; c < M; c++)
                    sb.append("-1 ");
                sb.append("\n");
            }
            System.out.print(sb);
            return;
        }
        int[][] dp = new int[N][M];
        StringBuilder sb = new StringBuilder();
        for(int k=0; k < K/2; k++)
        {
            int[][] next = new int[N][M];
            for(int r=0; r < N; r++)
                Arrays.fill(next[r], INF);
            for(int r=0; r < N; r++)
                for(int c=0; c < M; c++)
                {
                    if(r > 0)
                        next[r-1][c] = min(next[r-1][c], dp[r][c]+weights2[r-1][c]);
                    if(r+1 < N)
                        next[r+1][c] = min(next[r+1][c], dp[r][c]+weights2[r][c]);
                    if(c > 0)
                        next[r][c-1] = min(next[r][c-1], dp[r][c]+weights1[r][c-1]);
                    if(c+1 < M)
                        next[r][c+1] = min(next[r][c+1], dp[r][c]+weights1[r][c]);
                }
            dp = next;
        }
        for(int r=0; r < N; r++)
        {
            for(int x: dp[r])
                sb.append((2*x)+" ");
            sb.append("\n");
        }
        System.out.print(sb);
    }
}
class FastScanner
{
    private int BS = 1 << 16;
    private char NC = (char) 0;
    private byte[] buf = new byte[BS];
    private int bId = 0, size = 0;
    private char c = NC;
    private double cnt = 1;
    private BufferedInputStream in;

    public FastScanner() {
        in = new BufferedInputStream(System.in, BS);
    }

    public FastScanner(String s) {
        try {
            in = new BufferedInputStream(new FileInputStream(new File(s)), BS);
        } catch (Exception e) {
            in = new BufferedInputStream(System.in, BS);
        }
    }

    private char getChar() {
        while (bId == size) {
            try {
                size = in.read(buf);
            } catch (Exception e) {
                return NC;
            }
            if (size == -1) return NC;
            bId = 0;
        }
        return (char) buf[bId++];
    }

    public int nextInt() {
        return (int) nextLong();
    }

    public int[] nextInts(int N) {
        int[] res = new int[N];
        for (int i = 0; i < N; i++) {
            res[i] = (int) nextLong();
        }
        return res;
    }

    public long[] nextLongs(int N) {
        long[] res = new long[N];
        for (int i = 0; i < N; i++) {
            res[i] = nextLong();
        }
        return res;
    }

    public long nextLong() {
        cnt = 1;
        boolean neg = false;
        if (c == NC) c = getChar();
        for (; (c < '0' || c > '9'); c = getChar()) {
            if (c == '-') neg = true;
        }
        long res = 0;
        for (; c >= '0' && c <= '9'; c = getChar()) {
            res = (res << 3) + (res << 1) + c - '0';
            cnt *= 10;
        }
        return neg ? -res : res;
    }

    public double nextDouble() {
        double cur = nextLong();
        return c != '.' ? cur : cur + nextLong() / cnt;
    }

    public double[] nextDoubles(int N) {
        double[] res = new double[N];
        for (int i = 0; i < N; i++) {
            res[i] = nextDouble();
        }
        return res;
    }

    public String next() {
        StringBuilder res = new StringBuilder();
        while (c <= 32) c = getChar();
        while (c > 32) {
            res.append(c);
            c = getChar();
        }
        return res.toString();
    }

    public String nextLine() {
        StringBuilder res = new StringBuilder();
        while (c <= 32) c = getChar();
        while (c != '\n') {
            res.append(c);
            c = getChar();
        }
        return res.toString();
    }

    public boolean hasNext() {
        if (c > 32) return true;
        while (true) {
            c = getChar();
            if (c == NC) return false;
            else if (c > 32) return true;
        }
    }
}


// Author : RegalBeast

import java.io.*;
import java.util.*;

public class Main {
  static final FastReader FR = new FastReader();
  static final BufferedWriter BW = new BufferedWriter(new OutputStreamWriter(System.out));

  public static void main(String[] args) throws IOException {
    StringBuilder solution = new StringBuilder();
    int rows = FR.nextInt();
    int cols = FR.nextInt();
    int moves = FR.nextInt();

    Map<Integer, Integer> horizontalEdgeWeights = new HashMap<Integer, Integer>();
    for (int r = 0; r < rows; r++) {
      for (int c = 0; c < cols - 1; c++) {
        int hash = getHash(r, c);
        horizontalEdgeWeights.put(hash, FR.nextInt());
      }
    }

    Map<Integer, Integer> verticalEdgeWeights = new HashMap<Integer, Integer>();
    for (int r = 0; r < rows - 1; r++) {
      for (int c = 0; c < cols; c++) {
        int hash = getHash(r, c);
        verticalEdgeWeights.put(hash, FR.nextInt());
      }
    }

    List<List<Integer>> result = getResult(rows, cols, moves, horizontalEdgeWeights, verticalEdgeWeights);
    for (int r = 0; r < rows; r++) {
      for (int c = 0; c < cols; c++) {
        int value = (result != null ? result.get(r).get(c) : -1);
        solution.append(value + " ");
      }
      solution.append("\n");
    }

		BW.write(solution.toString());
    BW.close();
  }

  static List<List<Integer>> getResult(int rows, int cols, int moves, Map<Integer, Integer> horizontalEdgeWeights, Map<Integer, Integer> verticalEdgeWeights) {
    if ((moves & 1) == 1) {
      return null;
    }

    int mid = moves >> 1;
    List<List<List<Integer>>> minForDistance = new ArrayList<List<List<Integer>>>(rows);
    for (int r = 0; r < rows; r++) {
      minForDistance.add(new ArrayList<List<Integer>>(cols));

      for (int c = 0; c < cols; c++) {
        minForDistance.get(r).add(new ArrayList<Integer>(Collections.nCopies(mid+1, Integer.MAX_VALUE)));
        minForDistance.get(r).get(c).set(0, 0);
      }
    }

    for (int m = 1; m <= mid; m++) {
      for (int r = 0; r < rows; r++) {
        for (int c = 0; c < cols; c++) {
          int minBoredom = minForDistance.get(r).get(c).get(m);
          int hash = getHash(r, c);

          if (r > 0) {
            if (minForDistance.get(r-1).get(c).get(m-1) < Integer.MAX_VALUE) {
              int candidateBoredom = minForDistance.get(r-1).get(c).get(m-1) + verticalEdgeWeights.get(getHash(r-1, c));
              minBoredom = Math.min(minBoredom, candidateBoredom);
            }
          }

          if (c > 0) {
            if (minForDistance.get(r).get(c-1).get(m-1) < Integer.MAX_VALUE) {
              int candidateBoredom = minForDistance.get(r).get(c-1).get(m-1) + horizontalEdgeWeights.get(getHash(r, c-1));
              minBoredom = Math.min(minBoredom, candidateBoredom);
            }
          }

          if (r + 1 < rows) {
            if (minForDistance.get(r+1).get(c).get(m-1) < Integer.MAX_VALUE) {
              int candidateBoredom = minForDistance.get(r+1).get(c).get(m-1) + verticalEdgeWeights.get(hash);
              minBoredom = Math.min(minBoredom, candidateBoredom);
            }
          }

          if (c + 1 < cols) {
            if (minForDistance.get(r).get(c+1).get(m-1) < Integer.MAX_VALUE) {
              int candidateBoredom = minForDistance.get(r).get(c+1).get(m-1) + horizontalEdgeWeights.get(hash);
              minBoredom = Math.min(minBoredom, candidateBoredom);
            }
          }

          minForDistance.get(r).get(c).set(m, minBoredom);
        }
      }
    }

    List<List<Integer>> result = new ArrayList<List<Integer>>(rows);
    for (int r = 0; r < rows; r++) {
      result.add(new ArrayList<Integer>(cols));

      for (int c = 0; c < cols; c++) {
        result.get(r).add(minForDistance.get(r).get(c).get(mid) << 1);
      }
    }

    return result;
  }

  static int getHash(int row, int col) {
    return (row * 1000 + col);
  }
  static int getRow(int hash) {
    return hash / 1000;
  }
  static int getCol(int hash) {
    return hash % 1000;
  }

  static class FastReader {
    BufferedReader br;
    StringTokenizer st;

    public FastReader() {
      br = new BufferedReader(new InputStreamReader(System.in));
    }

    String next() {
      while (st == null || !st.hasMoreElements()) {
        try {
          st = new StringTokenizer(br.readLine());
        } catch (IOException  e) {
          e.printStackTrace();
        }
      }
      return st.nextToken();
    }

    int nextInt() {
      return Integer.parseInt(next());
    }

    long nextLong() {
      return Long.parseLong(next());
    }

    double nextDouble() {
      return Double.parseDouble(next());
    }

    String nextLine() {
      String str = "";
      try {
        str = br.readLine();
      } catch (IOException e)  {
        e.printStackTrace();
      }
      return str;
    }
  }
}


import java.io.*;
import java.util.*;

import static java.lang.Math.*;
import static java.util.Arrays.*;

public class cf1517d {

    public static void main(String[] args) throws IOException {
        int n = rni(), m = ni(), k = ni(), ans[][] = new int[n][m];
        WGraph g = wgraph(n * m);
        for (int i = 0; i < n; ++i) {
            r();
            for (int j = 0; j < m - 1; ++j) {
                g.c(i * m + j, i * m + j + 1, ni());
            }
        }
        for (int i = 0; i < n - 1; ++i) {
            r();
            for (int j = 0; j < m; ++j) {
                g.c(i * m + j, (i + 1) * m + j, ni());
            }
        }
        if (k % 2 == 1) {
            for (int[] row : ans) {
                fill(row, -1);
                prln(row);
            }
            close();
            return;
        }
        k >>= 1;
        for (int l = 0; l < k; ++l) {
            int nans[][] = new int[n][m];
            for (int[] row : nans) {
                fill(row, IBIG);
            }
            for (int i = 0; i < n * m; ++i) {
                for (int ed[] : g.get(i)) {
                    int j = ed[0], d = ed[1];
                    if (ans[i / m][i % m] + d < nans[j / m][j % m]) {
                        nans[j / m][j % m] = ans[i / m][i % m] + d;
                    }
                }
            }
            ans = nans;
        }
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < m; ++j) {
                ans[i][j] *= 2;
            }
        }
        for (int[] row : ans) {
            prln(row);
        }
        close();
    }

    static int solve(WGraph g, int i, int k) {
        List<Map<Integer, Integer>> cost = new ArrayList<>();
        for (int j = 0; j <= k; ++j) {
            cost.add(new HashMap<>());
        }
        PriorityQueue<int[]> dijk = new PriorityQueue<>((a, b) -> a[2] - b[2]);
        dijk.offer(new int[] {i, 0, 0});
        cost.get(0).put(i, 0);
        while (!dijk.isEmpty()) {
            int e[] = dijk.poll(), node = e[0], dist = e[1], co = e[2];
            if (co > cost.get(dist).get(node)) {
                continue;
            }
            if (dist == k) {
                return 2 * co;
            }
            if (dist < k) {
                for (int ed[] : g.get(node)) {
                    int j = ed[0], c = ed[1];
                    if (co + c < cost.get(dist + 1).getOrDefault(j, IBIG)) {
                        cost.get(dist + 1).put(j, co + c);
                        dijk.offer(new int[] {j, dist + 1, co + c});
                    }
                }
            }
        }
        return -1;
    }

    static WGraph wgraph(int n) {
        WGraph g = new WGraph();
        for (int i = 0; i < n; ++i) {
            g.add(new ArrayList<>());
        }
        return g;
    }

    static WGraph wgraph(int n, int m) throws IOException {
        WGraph g = wgraph(n);
        for (int i = 0; i < m; ++i) {
            g.c(rni() - 1, ni() - 1, ni());
        }
        return g;
    }

    static WGraph wdigraph(int n, int m) throws IOException {
        WGraph g = wgraph(n);
        for (int i = 0; i < m; ++i) {
            g.cto(rni() - 1, ni() - 1, ni());
        }
        return g;
    }

    static class WGraph extends ArrayList<List<int[]>> {
        void cto(int u, int v, int w) {
            get(u).add(new int[] {v, w});
        }

        void c(int u, int v, int w) {
            cto(u, v, w);
            cto(v, u, w);
        }
    }

    static BufferedReader __i = new BufferedReader(new InputStreamReader(System.in));
    static PrintWriter __o = new PrintWriter(new OutputStreamWriter(System.out));
    static StringTokenizer input;
    static Random __r = new Random();

    // references
    // IBIG = 1e9 + 7
    // IMAX ~= 2e9
    // LMAX ~= 9e18

    // constants
    static final int IBIG = 1000000007;
    static final int IMAX = 2147483647;
    static final long LMAX = 9223372036854775807L;
    // math util
    static int minof(int a, int b, int c) {return min(a, min(b, c));}
    static int minof(int... x) {if (x.length == 1) return x[0]; if (x.length == 2) return min(x[0], x[1]); if (x.length == 3) return min(x[0], min(x[1], x[2])); int min = x[0]; for (int i = 1; i < x.length; ++i) if (x[i] < min) min = x[i]; return min;}
    static long minof(long a, long b, long c) {return min(a, min(b, c));}
    static long minof(long... x) {if (x.length == 1) return x[0]; if (x.length == 2) return min(x[0], x[1]); if (x.length == 3) return min(x[0], min(x[1], x[2])); long min = x[0]; for (int i = 1; i < x.length; ++i) if (x[i] < min) min = x[i]; return min;}
    static int maxof(int a, int b, int c) {return max(a, max(b, c));}
    static int maxof(int... x) {if (x.length == 1) return x[0]; if (x.length == 2) return max(x[0], x[1]); if (x.length == 3) return max(x[0], max(x[1], x[2])); int max = x[0]; for (int i = 1; i < x.length; ++i) if (x[i] > max) max = x[i]; return max;}
    static long maxof(long a, long b, long c) {return max(a, max(b, c));}
    static long maxof(long... x) {if (x.length == 1) return x[0]; if (x.length == 2) return max(x[0], x[1]); if (x.length == 3) return max(x[0], max(x[1], x[2])); long max = x[0]; for (int i = 1; i < x.length; ++i) if (x[i] > max) max = x[i]; return max;}
    static int powi(int a, int b) {if (a == 0) return 0; int ans = 1; while (b > 0) {if ((b & 1) > 0) ans *= a; a *= a; b >>= 1;} return ans;}
    static long powl(long a, int b) {if (a == 0) return 0; long ans = 1; while (b > 0) {if ((b & 1) > 0) ans *= a; a *= a; b >>= 1;} return ans;}
    static int fli(double d) {return (int) d;}
    static int cei(double d) {return (int) ceil(d);}
    static long fll(double d) {return (long) d;}
    static long cel(double d) {return (long) ceil(d);}
    static int gcd(int a, int b) {return b == 0 ? a : gcd(b, a % b);}
    static long gcd(long a, long b) {return b == 0 ? a : gcd(b, a % b);}
    static int[] exgcd(int a, int b) {if (b == 0) return new int[] {1, 0}; int[] y = exgcd(b, a % b); return new int[] {y[1], y[0] - y[1] * (a / b)};}
    static long[] exgcd(long a, long b) {if (b == 0) return new long[] {1, 0}; long[] y = exgcd(b, a % b); return new long[] {y[1], y[0] - y[1] * (a / b)};}
    static int randInt(int min, int max) {return __r.nextInt(max - min + 1) + min;}
    static long mix(long x) {x += 0x9e3779b97f4a7c15L; x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9L; x = (x ^ (x >> 27)) * 0x94d049bb133111ebL; return x ^ (x >> 31);}
    // array util
    static void reverse(int[] a) {for (int i = 0, n = a.length, half = n / 2; i < half; ++i) {int swap = a[i]; a[i] = a[n - i - 1]; a[n - i - 1] = swap;}}
    static void reverse(long[] a) {for (int i = 0, n = a.length, half = n / 2; i < half; ++i) {long swap = a[i]; a[i] = a[n - i - 1]; a[n - i - 1] = swap;}}
    static void reverse(double[] a) {for (int i = 0, n = a.length, half = n / 2; i < half; ++i) {double swap = a[i]; a[i] = a[n - i - 1]; a[n - i - 1] = swap;}}
    static void reverse(char[] a) {for (int i = 0, n = a.length, half = n / 2; i < half; ++i) {char swap = a[i]; a[i] = a[n - i - 1]; a[n - i - 1] = swap;}}
    static void shuffle(int[] a) {int n = a.length - 1; for (int i = 0; i < n; ++i) {int ind = randInt(i, n); int swap = a[i]; a[i] = a[ind]; a[ind] = swap;}}
    static void shuffle(long[] a) {int n = a.length - 1; for (int i = 0; i < n; ++i) {int ind = randInt(i, n); long swap = a[i]; a[i] = a[ind]; a[ind] = swap;}}
    static void shuffle(double[] a) {int n = a.length - 1; for (int i = 0; i < n; ++i) {int ind = randInt(i, n); double swap = a[i]; a[i] = a[ind]; a[ind] = swap;}}
    static void rsort(int[] a) {shuffle(a); sort(a);}
    static void rsort(long[] a) {shuffle(a); sort(a);}
    static void rsort(double[] a) {shuffle(a); sort(a);}
    static int[] copy(int[] a) {int[] ans = new int[a.length]; for (int i = 0; i < a.length; ++i) ans[i] = a[i]; return ans;}
    static long[] copy(long[] a) {long[] ans = new long[a.length]; for (int i = 0; i < a.length; ++i) ans[i] = a[i]; return ans;}
    static double[] copy(double[] a) {double[] ans = new double[a.length]; for (int i = 0; i < a.length; ++i) ans[i] = a[i]; return ans;}
    static char[] copy(char[] a) {char[] ans = new char[a.length]; for (int i = 0; i < a.length; ++i) ans[i] = a[i]; return ans;}
    // input
    static void r() throws IOException {input = new StringTokenizer(rline());}
    static int ri() throws IOException {return Integer.parseInt(rline());}
    static long rl() throws IOException {return Long.parseLong(rline());}
    static double rd() throws IOException {return Double.parseDouble(rline());}
    static int[] ria(int n) throws IOException {int[] a = new int[n]; r(); for (int i = 0; i < n; ++i) a[i] = ni(); return a;}
    static int[] riam1(int n) throws IOException {int[] a = new int[n]; r(); for (int i = 0; i < n; ++i) a[i] = ni() - 1; return a;}
    static long[] rla(int n) throws IOException {long[] a = new long[n]; r(); for (int i = 0; i < n; ++i) a[i] = nl(); return a;}
    static double[] rda(int n) throws IOException {double[] a = new double[n]; r(); for (int i = 0; i < n; ++i) a[i] = nd(); return a;}
    static char[] rcha() throws IOException {return rline().toCharArray();}
    static String rline() throws IOException {return __i.readLine();}
    static String n() {return input.nextToken();}
    static int rni() throws IOException {r(); return ni();}
    static int ni() {return Integer.parseInt(n());}
    static long rnl() throws IOException {r(); return nl();}
    static long nl() {return Long.parseLong(n());}
    static double rnd() throws IOException {r(); return nd();}
    static double nd() {return Double.parseDouble(n());}
    // output
    static void pr(int i) {__o.print(i);}
    static void prln(int i) {__o.println(i);}
    static void pr(long l) {__o.print(l);}
    static void prln(long l) {__o.println(l);}
    static void pr(double d) {__o.print(d);}
    static void prln(double d) {__o.println(d);}
    static void pr(char c) {__o.print(c);}
    static void prln(char c) {__o.println(c);}
    static void pr(char[] s) {__o.print(new String(s));}
    static void prln(char[] s) {__o.println(new String(s));}
    static void pr(String s) {__o.print(s);}
    static void prln(String s) {__o.println(s);}
    static void pr(Object o) {__o.print(o);}
    static void prln(Object o) {__o.println(o);}
    static void prln() {__o.println();}
    static void pryes() {prln("yes");}
    static void pry() {prln("Yes");}
    static void prY() {prln("YES");}
    static void prno() {prln("no");}
    static void prn() {prln("No");}
    static void prN() {prln("NO");}
    static boolean pryesno(boolean b) {prln(b ? "yes" : "no"); return b;};
    static boolean pryn(boolean b) {prln(b ? "Yes" : "No"); return b;}
    static boolean prYN(boolean b) {prln(b ? "YES" : "NO"); return b;}
    static void prln(int... a) {for (int i = 0, len = a.length - 1; i < len; pr(a[i]), pr(' '), ++i); if (a.length > 0) prln(a[a.length - 1]); else prln();}
    static void prln(long... a) {for (int i = 0, len = a.length - 1; i < len; pr(a[i]), pr(' '), ++i); if (a.length > 0) prln(a[a.length - 1]); else prln();}
    static void prln(double... a) {for (int i = 0, len = a.length - 1; i < len; pr(a[i]), pr(' '), ++i); if (a.length > 0) prln(a[a.length - 1]); else prln();}
    static <T> void prln(Collection<T> c) {int n = c.size() - 1; Iterator<T> iter = c.iterator(); for (int i = 0; i < n; pr(iter.next()), pr(' '), ++i); if (n >= 0) prln(iter.next()); else prln();}
    static void h() {prln("hlfd"); flush();}
    static void flush() {__o.flush();}
    static void close() {__o.close();}
}


// Author : RegalBeast

import java.io.*;
import java.util.*;

public class Main {
  static final FastReader FR = new FastReader();
  static final PrintWriter PW = new PrintWriter(new OutputStreamWriter(System.out));

  public static void main(String[] args) {
    StringBuilder solution = new StringBuilder();
    int rows = FR.nextInt();
    int cols = FR.nextInt();
    int moves = FR.nextInt();

    int[][] horizontalEdgeWeights = new int[rows][cols-1];

    for (int r = 0; r < rows; r++) {
      for (int c = 0; c < cols - 1; c++) {
        horizontalEdgeWeights[r][c] = FR.nextInt();
      }
    }

    int[][] verticalEdgeWeights = new int[rows-1][cols];
    for (int r = 0; r < rows - 1; r++) {
      for (int c = 0; c < cols; c++) {
        verticalEdgeWeights[r][c] = FR.nextInt();
      }
    }

    int[][] result = getResult(rows, cols, moves, horizontalEdgeWeights, verticalEdgeWeights);
    for (int r = 0; r < rows; r++) {
      for (int c = 0; c < cols; c++) {
        solution.append(result[r][c] + " ");
      }
      solution.append("\n");
    }

		PW.print(solution.toString());
    PW.close();
  }

  static int[][] getResult(int rows, int cols, int moves, int[][] horizontalEdgeWeights, int[][] verticalEdgeWeights) {
    int[][] result = new int[rows][cols];
    if ((moves & 1) == 1) {
      for (int r = 0; r < rows; r++) {
        for (int c = 0; c < cols; c++) {
          result[r][c] = -1;
        }
      }

      return result;
    }

    int mid = moves >> 1;
    int[][][] minForDistance = new int[rows][cols][mid+1];
    for (int r = 0; r < rows; r++) {
      for (int c = 0; c < cols; c++) {
        for (int m = 1; m <= mid; m++) {
          minForDistance[r][c][m] = Integer.MAX_VALUE;
        }
      }
    }

    for (int m = 1; m <= mid; m++) {
      for (int r = 0; r < rows; r++) {
        for (int c = 0; c < cols; c++) {
          int minBoredom = minForDistance[r][c][m];

          if (r > 0) {
            int candidateBoredom = minForDistance[r-1][c][m-1] + verticalEdgeWeights[r-1][c];
            minBoredom = Math.min(minBoredom, candidateBoredom);
          }

          if (c > 0) {
            int candidateBoredom = minForDistance[r][c-1][m-1] + horizontalEdgeWeights[r][c-1];
            minBoredom = Math.min(minBoredom, candidateBoredom);
          }

          if (r + 1 < rows) {
            int candidateBoredom = minForDistance[r+1][c][m-1] + verticalEdgeWeights[r][c];
            minBoredom = Math.min(minBoredom, candidateBoredom);
          }

          if (c + 1 < cols) {
            int candidateBoredom = minForDistance[r][c+1][m-1] + horizontalEdgeWeights[r][c];
            minBoredom = Math.min(minBoredom, candidateBoredom);
          }

          minForDistance[r][c][m] = minBoredom;
        }
      }
    }

    for (int r = 0; r < rows; r++) {
      for (int c = 0; c < cols; c++) {
        result[r][c] = minForDistance[r][c][mid] << 1;
      }
    }

    return result;
  }

  static class FastReader {
    BufferedReader br;
    StringTokenizer st;

    public FastReader() {
      br = new BufferedReader(new InputStreamReader(System.in));
    }

    String next() {
      while (st == null || !st.hasMoreElements()) {
        try {
          st = new StringTokenizer(br.readLine());
        } catch (IOException  e) {
          e.printStackTrace();
        }
      }
      return st.nextToken();
    }

    int nextInt() {
      return Integer.parseInt(next());
    }

    long nextLong() {
      return Long.parseLong(next());
    }

    double nextDouble() {
      return Double.parseDouble(next());
    }

    String nextLine() {
      String str = "";
      try {
        str = br.readLine();
      } catch (IOException e)  {
        e.printStackTrace();
      }
      return str;
    }
  }
}


import java.util.*;
import java.lang.*;
import java.io.*;

public class Main {
    static class Fast {
		StringTokenizer st;
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

		public String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public int nextInt() throws IOException {
			return Integer.parseInt(next());
		}

		public long nextLong() throws IOException {
			return Long.parseLong(next());
		}
	}
    static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
    static Fast scn = new Fast();
    public static void main(String args[]) throws Exception {
        int t = 1;
        while(t-- > 0){
            func();
        }
        bw.close();
    }
    private static void func() throws Exception{
        int n = scn.nextInt();
        int m = scn.nextInt();
        int k = scn.nextInt();
        int[][] hori = new int[n][m - 1];
        int[][] vert = new int[n - 1][m];
        for(int i = 0; i < n; i++){
            for(int j = 0; j < m - 1; j++){
                hori[i][j] = scn.nextInt();
            }
        }

        for(int i = 0; i < n - 1; i++){
            for(int j = 0; j < m; j++){
                vert[i][j] = scn.nextInt();
            }
        }
        if(k % 2 != 0){
            for(int i = 0; i < n; i++){
                for(int j = 0; j < m; j++){
                    bw.append(-1 + " ");
                }
                bw.append("\n");
            }
            return;
        }
        int[][][] strg = new int[n][m][k + 1];
        // for(int i = 0; i < n; i++){
        //     for(int j = 0; j < m; j++){
        //         for(int x = 0; x < k; x++)
        //     }
        // }
        int[][] answer = new int[n][m];
        for(int i = 0; i < n; i++){
            for(int j = 0; j < m; j++){
                answer[i][j] = steps(i, j, hori, vert, k, strg);
            }
        }
      for(int i = 0; i < n; i++){
          for(int j = 0; j < m; j++){
              bw.append(answer[i][j] + " ");
          }
          bw.append("\n");
      }

    }

    static int steps(int x, int y, int[][] hori, int[][] vert, int k, int[][][] strg){
        if(k == 0)
            return 0;
        if(strg[x][y][k] != 0)
            return strg[x][y][k];
        int xmove = x;
        int ymove = y;
        int ans = 0;
        int val = Integer.MAX_VALUE;
        if(y < hori[0].length){
            xmove = x;
            ymove = y + 1;
            val = Math.min(val, steps(xmove, ymove, hori, vert, k - 2, strg) + (2 * hori[x][y]));
        }
        if(y - 1 >= 0){
            xmove = x;
            ymove = y - 1;
            val = Math.min(val, steps(xmove, ymove, hori, vert, k - 2, strg) + (2 * hori[x][y - 1]));
            // val = hori[x][y - 1];
        }
        if(x - 1 >= 0){
            xmove = x - 1;
            ymove = y;
            val = Math.min(val, steps(xmove, ymove, hori, vert, k - 2, strg) + (2 * vert[x - 1][y]));
            // val = vert[x - 1][y];
        }
        if(x < vert.length){
            xmove = x + 1;
            ymove = y;
            val = Math.min(val, steps(xmove, ymove, hori, vert, k - 2, strg) + (2 * vert[x][y]));
            // val = vert[x + 1][y];
        }
        // System.out.println(val);
        ans += val;
        return strg[x][y][k] = ans;
    }
}


/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.HashSet;
import java.util.Set;
import java.util.StringTokenizer;

/**
 *
 * @author is2ac
 */
public class D_CF {

    public static void main(String[] args) {
        FastScanner58 fs = new FastScanner58();
        PrintWriter pw = new PrintWriter(System.out);
        //int t = fs.ni();
        int t = 1;
        // for (int tc = 0; tc < t; tc++) {
        for (int tc = 0; tc < t; tc++) {
            int n = fs.ni();
            int m = fs.ni();
            int k = fs.ni();
            int[][] a = new int[n][m - 1];
            int[][] b = new int[n - 1][m];
            for (int i = 0; i < n; i++) {
                a[i] = fs.intArray(m - 1);
            }
            for (int i = 0; i < n - 1; i++) {
                b[i] = fs.intArray(m);
            }
            int[][] res = new int[n][m];
            Integer[][][] dp = new Integer[n][m][k / 2 + 1];
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    res[i][j] = recur(i, j, k / 2, dp, a, b) * 2;
                }
            }
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < res.length; i++) {
                for (int j = 0; j < m; j++) {
                    //matrix[i][j]++;
                    if (k%2==1) {
                        sb.append(-1 + " ");
                    } else {
                        sb.append(res[i][j] + " ");
                    }
                }
                sb.append("\n");
            }
            pw.println(sb);
        }
        pw.close();
    }

    public static int recur(int i, int j, int k, Integer[][][] dp, int[][] a, int[][] b) {
        if (k == 0) {
            return 0;
        }
        int n = (int) (1e9);
        if (dp[i][j][k] != null) {
            return dp[i][j][k];
        }
        if (i != 0) {
            n = Math.min(n, recur(i - 1, j, k - 1, dp, a, b) + b[i - 1][j]);
        }
        if (j != 0) {
            n = Math.min(n, recur(i, j - 1, k - 1, dp, a, b) + a[i][j - 1]);
        }
        if (i != a.length - 1) {
            n = Math.min(n, recur(i + 1, j, k - 1, dp, a, b) + b[i][j]);
        }
        if (j != b[0].length - 1) {
            n = Math.min(n, recur(i, j + 1, k - 1, dp, a, b) + a[i][j]);
        }
        return dp[i][j][k] = n;
    }
}

class FastScanner58 {

    BufferedReader br;
    StringTokenizer st;

    public FastScanner58() {
        br = new BufferedReader(new InputStreamReader(System.in), 32768);
        st = null;
    }

    String next() {
        while (st == null || !st.hasMoreElements()) {
            try {
                st = new StringTokenizer(br.readLine());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return st.nextToken();
    }

    int ni() {
        return Integer.parseInt(next());
    }

    int[] intArray(int N) {
        int[] ret = new int[N];
        for (int i = 0; i < N; i++) {
            ret[i] = ni();
        }
        return ret;
    }

    long nl() {
        return Long.parseLong(next());
    }

    long[] longArray(int N) {
        long[] ret = new long[N];
        for (int i = 0; i < N; i++) {
            ret[i] = nl();
        }
        return ret;
    }

    double nd() {
        return Double.parseDouble(next());
    }

    String nextLine() {
        String str = "";
        try {
            str = br.readLine();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return str;
    }
}

class UnionFind17 {

    int[] id;

    public UnionFind17(int size) {
        id = new int[size];
        for (int i = 0; i < size; i++) {
            id[i] = i;
        }
    }

    public int find(int p) {
        int root = p;
        while (root != id[root]) {
            root = id[root];
        }
        while (p != root) {
            int next = id[p];
            id[p] = root;
            p = next;
        }
        return root;
    }

    public void union(int p, int q) {
        int a = find(p), b = find(q);
        if (a == b) {
            return;
        }
        id[b] = a;
    }
}


import java.util.*;
import java.io.*;

public class Main {
    static FastScanner sc = new FastScanner(System.in);
    static PrintWriter pw = new PrintWriter(System.out);
    static StringBuilder sb = new StringBuilder();
    static long mod = (long) 1e9 + 7;
    public static void main(String[] args) throws Exception {
        solve();
        pw.flush();
    }

    static ArrayList<ArrayList<ArrayList<int[]>>> kruscal = new ArrayList<>();
    static long ans = Integer.MAX_VALUE;
    static int[][][] map;
    public static void solve() {
        int n = sc.nextInt(), m = sc.nextInt(), k = sc.nextInt();
        for(int i = 0; i < n; i++){
            kruscal.add(new ArrayList<>());
            for(int j = 0; j < m; j++){
                kruscal.get(i).add(new ArrayList<>());
            }
        }
        map = new int[n][m][k+1];
        for(int i = 0; i < n; i++){
            for(int j = 0; j < m-1; j++){
                //int now = (int)(Math.random()*1000000)*2;
                int now = sc.nextInt();
                kruscal.get(i).get(j).add(new int[]{now,i,j+1});
                kruscal.get(i).get(j+1).add(new int[]{now,i,j});
            }
        }
        for(int i = 0; i < n-1; i++){
            for(int j = 0; j < m; j++){
                //int now = (int)(Math.random()*1000000)*2;
                int now = sc.nextInt();
                kruscal.get(i).get(j).add(new int[]{now,i+1,j});
                kruscal.get(i+1).get(j).add(new int[]{now,i,j});
            }
        }
        if(k % 2 != 0){
            for(int i = 0; i < n; i++){
                for(int j = 0; j < m; j++){
                    sb.append(-1).append(" ");
                }
                pw.println(sb.toString().trim());
                sb.setLength(0);
            }
            return;
        }
        for(int i = 0; i < n; i++){
            for(int j = 0; j < m; j++){
                Arrays.fill(map[i][j],Integer.MAX_VALUE/2);
                map[i][j][k/2] = 0;
            }
        }
        for(int kk = k/2; kk > 0; kk--){
            for(int i = 0; i < n; i++){
                for(int j = 0; j < m; j++){
                    for(int[] next : kruscal.get(i).get(j)){
                        int d = next[0], i2 = next[1], j2 = next[2];
                        map[i2][j2][kk-1] = Math.min(map[i2][j2][kk-1],map[i][j][kk]+d);
                    }
                }
            }
        }
        for(int i = 0; i < n; i++){
            for(int j = 0; j < m; j++){
                sb.append(map[i][j][0]*2).append(" ");
            }
            pw.println(sb.toString().trim());
            sb.setLength(0);
        }
    }

    static void dfs(Stack<Integer> st, int y, int x, int cnt, long total){
        if(st.size() == cnt){
            ans = Math.min(total,ans);
        }
        for(int[] next : kruscal.get(y).get(x)){
            int d = next[0], i = next[1], j = next[2];
            if(Math.abs(i-y)+Math.abs(j-x)-st.size() < 0){
                continue;
            }
            Stack<Integer> stk = (Stack<Integer>)st.clone();
            stk.push(d);
            dfs(stk,i,j,cnt,total + d);
        }
        int rem = cnt - st.size();
        long tmp = 0;
        int c = 0;
        while(st.size() > 0){
            tmp += st.pop();
            c++;
            if(rem % c == 0){
                ans = Math.min(ans,total + tmp * (rem/c));
            }
        }
    }

    static class ArrayComparator implements Comparator<int[]> {
        @Override
        public int compare(int[] a1, int[] a2) {
            for (int i = 0; i < a1.length; i++) {
                if (a1[i] < a2[i]) {
                    return -1;
                } else if (a1[i] > a2[i]) {
                    return 1;
                }
            }
            if (a1.length < a2.length) {
                return -1;
            } else if (a1.length > a2.length) {
                return 1;
            } else {
                return 0;
            }
        }
    }

    private static String ArraysToString(int[] arr){
        String s = Arrays.toString(arr);
        s = s.replaceAll(",","");
        s = s.substring(1,s.length()-1);
        return s;
    }

    static class GeekInteger {
        public static void save_sort(int[] array) {
            shuffle(array);
            Arrays.sort(array);
        }

        public static int[] shuffle(int[] array) {
            int n = array.length;
            Random random = new Random();
            for (int i = 0, j; i < n; i++) {
                j = i + random.nextInt(n - i);
                int randomElement = array[j];
                array[j] = array[i];
                array[i] = randomElement;
            }
            return array;
        }

        public static void save_sort(long[] array) {
            shuffle(array);
            Arrays.sort(array);
        }

        public static long[] shuffle(long[] array) {
            int n = array.length;
            Random random = new Random();
            for (int i = 0, j; i < n; i++) {
                j = i + random.nextInt(n - i);
                long randomElement = array[j];
                array[j] = array[i];
                array[i] = randomElement;
            }
            return array;
        }

    }
}

class DSU {
    private int n;
    private int[] parentOrSize;
    private java.util.ArrayList<java.util.ArrayList<Integer>> map;

    public DSU(int n) {
        this.n = n;
        this.map = new java.util.ArrayList<java.util.ArrayList<Integer>>();
        for (int i = 0; i < n; i++) {
            this.map.add(new java.util.ArrayList<Integer>());
            this.map.get(i).add(i);
        }
        this.parentOrSize = new int[n];
        java.util.Arrays.fill(parentOrSize, -1);
    }

    int merge(int a, int b) {
        if (!(0 <= a && a < n))
            throw new IndexOutOfBoundsException("a=" + a);
        if (!(0 <= b && b < n))
            throw new IndexOutOfBoundsException("b=" + b);

        int x = leader(a);
        int y = leader(b);
        if (x == y)
            return x;
        if (-parentOrSize[x] < -parentOrSize[y]) {
            int tmp = x;
            x = y;
            y = tmp;
        }
        parentOrSize[x] += parentOrSize[y];
        parentOrSize[y] = x;
        this.map.get(x).addAll(this.map.get(y));
        return x;
    }

    boolean same(int a, int b) {
        if (!(0 <= a && a < n))
            throw new IndexOutOfBoundsException("a=" + a);
        if (!(0 <= b && b < n))
            throw new IndexOutOfBoundsException("b=" + b);
        return leader(a) == leader(b);
    }

    int leader(int a) {
        if (parentOrSize[a] < 0) {
            return a;
        } else {
            parentOrSize[a] = leader(parentOrSize[a]);
            return parentOrSize[a];
        }
    }

    int size(int a) {
        if (!(0 <= a && a < n))
            throw new IndexOutOfBoundsException("" + a);
        return -parentOrSize[leader(a)];
    }

    java.util.ArrayList<java.util.ArrayList<Integer>> groups() {
        int[] leaderBuf = new int[n];
        int[] groupSize = new int[n];
        for (int i = 0; i < n; i++) {
            leaderBuf[i] = leader(i);
            groupSize[leaderBuf[i]]++;
        }
        java.util.ArrayList<java.util.ArrayList<Integer>> result = new java.util.ArrayList<>(n);
        for (int i = 0; i < n; i++) {
            result.add(new java.util.ArrayList<>(groupSize[i]));
        }
        for (int i = 0; i < n; i++) {
            result.get(leaderBuf[i]).add(i);
        }
        result.removeIf(java.util.ArrayList::isEmpty);
        return result;
    }

    java.util.ArrayList<Integer> getArray(int n) {
        return this.map.get(n);
    }
}

class FastScanner {
    private BufferedReader reader = null;
    private StringTokenizer tokenizer = null;

    public FastScanner(InputStream in) {
        reader = new BufferedReader(new InputStreamReader(in));
        tokenizer = null;
    }

    public FastScanner(FileReader in) {
        reader = new BufferedReader(in);
        tokenizer = null;
    }

    public String next() {
        if (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    public String nextLine() {
        if (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                return reader.readLine();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken("\n");
    }

    public long nextLong() {
        return Long.parseLong(next());
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }

    public double nextDouble() {
        return Double.parseDouble(next());
    }

    public String[] nextArray(int n) {
        String[] a = new String[n];
        for (int i = 0; i < n; i++)
            a[i] = next();
        return a;
    }

    public int[] nextIntArray(int n) {
        int[] a = new int[n];
        for (int i = 0; i < n; i++)
            a[i] = nextInt();
        return a;
    }

    public long[] nextLongArray(int n) {
        long[] a = new long[n];
        for (int i = 0; i < n; i++)
            a[i] = nextLong();
        return a;
    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.StringTokenizer;

public class A {

    private static final int INF = (int) 1e9 + 7;

    public static void main(String[] args) {
        FastScanner fs=new FastScanner();
        PrintWriter pr = new PrintWriter(System.out);
//        int T=fs.nextInt();
//        for (int tt=1; tt<=T; tt++) {
            int n = fs.nextInt(), m = fs.nextInt(), k = fs.nextInt();
            int[][] right = new int[n][m -1], down = new int[n - 1][m];
            for(int i = 0; i < n; i++) right[i] = fs.readArray(m - 1);
            for(int i = 0; i < n - 1; i++) down[i] = fs.readArray(m);
            if (k % 2 == 1) {
                for (int i = 0; i < n; i++) {
                    for (int j = 0; j < m; j++) pr.print(-1 + " ");
                    pr.println();
                }
            } else {
                int[][][] dp = new int[k / 2 + 1][n][m];

                for(int r = 1; 2 * r <= k; r++) {
                    for(int i = 0; i < n; i++) Arrays.fill(dp[r][i], INF);
                    for(int i = 0; i < n; i++)
                        for(int j = 0; j  + 1 < m; j++) {
                            int cost = right[i][j];
                            dp[r][i][j] = Integer.min(dp[r][i][j], dp[r - 1][i][j + 1] + cost);
                            dp[r][i][j + 1] = Integer.min(dp[r][i][j + 1], dp[r - 1][i][j] + cost);
                        }
                    for(int i = 0; i + 1 < n; i++)
                        for(int j = 0; j < m; j++) {
                            int cost = down[i][j];
                            dp[r][i][j] = Integer.min(dp[r][i][j], dp[r - 1][i + 1][j] + cost);
                            dp[r][i + 1][j] = Integer.min(dp[r][i + 1][j], dp[r - 1][i][j] + cost);
                        }
                }
                for(int i = 0; i < n; i++) {
                    for(int j = 0; j < m; j++) {
                        pr.print(2 * dp[k/2][i][j] + " ");
                    }
                    pr.println();
                }
            }

//        }

        pr.flush();
        pr.close();
    }

    static void sort(int[] a) {
        ArrayList<Integer> l=new ArrayList<>();
        for (int i:a) l.add(i);
        Collections.sort(l);
        for (int i=0; i<a.length; i++) a[i]=l.get(i);
    }

    static class FastScanner {
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st=new StringTokenizer("");
        String next() {
            while (!st.hasMoreTokens())
                try {
                    st=new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }
        int[] readArray(int n) {
            int[] a=new int[n];
            for (int i=0; i<n; i++) a[i]=nextInt();
            return a;
        }
        long[] readLongArray(int n) {
            long[] a=new long[n];
            for (int i=0; i<n; i++) a[i]=nextLong();
            return a;
        }
        long nextLong() {
            return Long.parseLong(next());
        }
    }
}


import java.io.*;
import java.util.*;

public class a{
    static BufferedReader br;
    static PrintWriter pw;
    static int N, M, K;
    static ArrayList<Integer> graph[][];
    public static void main(String args[]) throws IOException{
        br = new BufferedReader(new InputStreamReader(System.in));
        pw = new PrintWriter(System.out);
        StringTokenizer st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        K = Integer.parseInt(st.nextToken());
        if(K % 2 == 1){
            for(int i = 0; i < N; i++){
                for(int j = 0; j < M; j++){
                    pw.print("-1 ");
                }
                pw.println();
            }
            br.close(); pw.close();
            return;
        }
        graph = new ArrayList[N][M];
        for(int i = 0; i < N; i++){
            for(int j = 0; j < M; j++){
                graph[i][j] = new ArrayList<Integer>();
            }
        }
        for(int i = 0; i < N; i++){
            st = new StringTokenizer(br.readLine());
            for(int j = 0; j < M-1; j++){
                int w = Integer.parseInt(st.nextToken());
                graph[i][j].add(w);
            }
        }
        for(int i = 0; i < N; i++){
            graph[i][M-1].add(0);
        }
        for(int i = 0; i < N-1; i++){
            st = new StringTokenizer(br.readLine());
            for(int j = 0; j < M; j++){
                int w = Integer.parseInt(st.nextToken());
                graph[i][j].add(w);
            }
        }
        K /= 2;
        for(int i = 0; i < M; i++) graph[N-1][i].add(0);
        long ans[][][] = new long[K+1][N][M];
        for(int i = 0; i < N; i++){
            Arrays.fill(ans[0][i], 0);
        }
        for(int i = 1; i <= K; i++){
            for(int x = 0; x < N; x++){
                for(int y = 0; y < M; y++){
                    long cur = (long)1e17;
                    if(x < N-1){
                        cur = (long)Math.min(cur, graph[x][y].get(1) + ans[i-1][x+1][y]);
                    }
                    if(y < M-1){
                        cur = (long)Math.min(cur, graph[x][y].get(0) + ans[i-1][x][y+1]);
                    }
                    if(x > 0){
                        cur = (long)Math.min(cur, graph[x-1][y].get(1) + ans[i-1][x-1][y]);
                        //pw.println("CUR: " + cur + " X: " + x + " Y: " + y + " get = " + graph[x-1][y].get(0));
                    }
                    if(y > 0){
                        cur = (long)Math.min(cur, graph[x][y-1].get(0) + ans[i-1][x][y-1]);
                    }
                    ans[i][x][y] = cur;
                }
            }
        }
        for(int i = 0; i < N; i++){
            for(int j = 0; j < M; j++){
                pw.print(ans[K][i][j] * 2 + " ");
            }
            pw.println();
        }
        br.close(); pw.close();
    }
    static class pii implements Comparable<pii>{
        int f, s, k;
        pii(int f, int s, int k){
            this.f = f;
            this.s = s;
            this.k = k;
        }
        public int compareTo(pii x){
            return Integer.compare(f, x.f);
        }
    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

/**
 * @Author:
 * @Date: 2021/4/23 23:55
 */
public class ExplorerSpace {
    static int n;
    static int m;
    static int k;
    static int [][] rows;
    static int [][] cols;
    static int max;
    static int orix;
    static int oriy;
    static int [][] dirs = new int[][]{{0,1},{0,-1},{1,0},{-1,0}};
    static int [][][][][] mem;
    public static void main(String[] args) {
        FastScanner fs = new FastScanner();
        n = fs.nextInt();
        m =fs.nextInt();
        k = fs.nextInt();
        rows = new int[n][m-1];
        cols = new int[n-1][m];
        for(int i = 0; i < n; i++){
            for(int j = 0; j < m-1; j++){
                rows[i][j] = fs.nextInt();
            }
        }
        for(int i = 0; i < n-1; i++){
            for(int j = 0; j < m; j++){
                cols[i][j] = fs.nextInt();
            }
        }
        int [][][] res = new int[100][n][m];
        for(int o = 2; o <= k; o+=2){
            for(int i = 0; i < n; i++){
                for(int j = 0; j < m; j++){
                    res[o][i][j] = 0x3f3f3f3f;
                    if(i>0){
                        res[o][i][j] = Math.min(res[o][i][j], res[o-2][i-1][j] + 2*cols[i-1][j]);
                    }
                    if(i+1<n){
                        res[o][i][j] = Math.min(res[o][i][j], res[o-2][i+1][j] + 2 * cols[i][j]);
                    }
                    if(j>0){
                        res[o][i][j] = Math.min(res[o][i][j], res[o-2][i][j-1] + 2 * rows[i][j-1]);
                    }
                    if(j+1<m){
                        res[o][i][j] = Math.min(res[o][i][j], res[o-2][i][j+1] + 2 * rows[i][j]);
                    }
                }
            }
        }

        for(int i = 0; i < n; i++){
            for(int j = 0; j < m;j ++){
                if(k%2==1){
                    System.out.print(-1+" ");
                }else{
                    System.out.print(res[k][i][j] + " ");
                }

            }
            System.out.println();
        }
    }

//    static void dfs(int x, int y,int cur, int left){
//        if(x<0||x>=n||y<0||y>=m){
//            return;
//        }
//        if(left==0&&x==orix&&y==oriy){
//            max = Math.min(max,cur);
//            return;
//        }
//        if(left<=0){
//            return;
//        }
//        if(cur>=max){
//            return;
//        }
//        if(x+1<n){
//            dfs(x+1,y,cur+cols[x][y],left-1);
//        }
//        if(x-1>=0){
//            dfs(x-1,y,cur+cols[x-1][y],left-1);
//        }
//        if(y+1<m){
//            dfs(x,y+1,cur+rows[x][y],left-1);
//        }
//        if(y-1>=0){
//            dfs(x,y-1,cur+rows[x][y-1],left-1);
//        }
//
//    }
    static class  FastScanner{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer("");
        String next(){
            while (!st.hasMoreTokens()){
                try {
                    st = new StringTokenizer(br.readLine());
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }
        int nextInt(){
            return Integer.parseInt(next());
        }
        long nextLong(){
            return Long.parseLong(next());
        }
    }
}


import java.awt.*;
import java.io.*;
import java.sql.Array;
import java.util.*;
import java.util.List;

public class Main {
    static class FastReader {
        BufferedReader br;
        StringTokenizer st;

        public FastReader()
        {
            br = new BufferedReader(
                    new InputStreamReader(System.in));
        }

        String next()
        {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                }
                catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() { return Integer.parseInt(next()); }

        long nextLong() { return Long.parseLong(next()); }

        double nextDouble()
        {
            return Double.parseDouble(next());
        }

        String nextLine()
        {
            String str = "";
            try {
                str = br.readLine();
            }
            catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }
    }

    static final int N=205;
    static final int mod=1000000007;
    static final int INF=1000000009;
    static final int numBit=17;
    static FastReader r=new FastReader();
    static PrintWriter pw = new PrintWriter(System.out);

    public static void main(String[] args) throws IOException {
        int n=r.nextInt();
        int m=r.nextInt();
        int k=r.nextInt();
        int [][]hor=new int[n][m-1];
        int [][]ver=new int[n-1][m];
        for(int i=0;i<n;++i){
            for(int j=0;j<m-1;++j) hor[i][j]=r.nextInt();
        }
        for(int i=0;i<n-1;++i){
            for(int j=0;j<m;++j) ver[i][j]=r.nextInt();
        }
        int [][]dp=new int[n][m];
        if(k%2!=0){
            for(int i=0;i<n;++i){
                for(int j=0;j<m;++j) dp[i][j]=-1;
            }
        }
        else{
            int [][]new_dp=new int[n][m];
            for(int step=0;step<k/2;++step){
                for(int i=0;i<n;++i){
                    for(int j=0;j<m;++j){
                        new_dp[i][j]=INF;
                        if(i>0){
                            new_dp[i][j]=Math.min(new_dp[i][j],dp[i-1][j]+ver[i-1][j]*2);
                        }
                        if(i<n-1){
                            new_dp[i][j]=Math.min(new_dp[i][j],dp[i+1][j]+ver[i][j]*2);
                        }
                        if(j>0){
                            new_dp[i][j]=Math.min(new_dp[i][j],dp[i][j-1]+hor[i][j-1]*2);
                        }
                        if(j<m-1){
                            new_dp[i][j]=Math.min(new_dp[i][j],dp[i][j+1]+hor[i][j]*2);
                        }
                    }
                }
                for(int i=0;i<n;++i){
                    for(int j=0;j<m;++j){
                        dp[i][j]=new_dp[i][j];
                    }
                }
            }
        }
        for(int i=0;i<n;++i){
            for(int j=0;j<m;++j){
                pw.print(dp[i][j]+" ");
            }
            pw.println();
        }
        pw.close();
    }
}


import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.PriorityQueue;
import java.util.StringTokenizer;
import java.io.*;

public class ExplorerSpace {

	private static class MyScanner {
	    BufferedReader br;
	    StringTokenizer st;

	    public MyScanner() {
	       br = new BufferedReader(new InputStreamReader(System.in));
	    }

	    String next() {
	        while (st == null || !st.hasMoreElements()) {
	            try {
	                st = new StringTokenizer(br.readLine());
	            } catch (IOException e) {
	                e.printStackTrace();
	            }
	        }
	        return st.nextToken();
	    }

	    int nextInt() {
	        return Integer.parseInt(next());
	    }

	    long nextLong() {
	        return Long.parseLong(next());
	    }

	    double nextDouble() {
	        return Double.parseDouble(next());
	    }

	    String nextLine(){
	        String str = "";
		  try {
		     str = br.readLine();
		  } catch (IOException e) {
		     e.printStackTrace();
		  }
		  return str;
	    }

	 }

	public static long[][][] dp;

	public static boolean valid(int i, int j, int n, int m)
	{
		return i>=0 && i<n &&j>=0 && j<m;
	}

	public static void solution(int n, int m, int k, int[][] h, int[][] v)

	{
		if(k%2==1)
		{
			for(int i = 0; i<n; i++)
			{
				for(int j = 0; j<m; j++)
				   out.print(-1+" ");

				out.println();

			}

			return;
		}

		dp = new long[n][m][k/2+1];

		for(int t = 1; t<=k/2; t++)
		{
			for(int i = 0; i<n; i++)
			{
				for(int j = 0; j<m; j++)
				{
					dp[i][j][t] = Long.MAX_VALUE;

				}
			}
		}

		for(int i = 0; i<n; i++)
		{
			for(int j = 0; j<m; j++)
			{
				dp[i][j][0] = 0;

			}
		}

		for(int t = 1; t<=k/2; t++)
		{
			for(int i = 0; i<n; i++)
			{
				for(int j = 0; j<m; j++)
				{
					if(valid(i,j+1,n,m))
						dp[i][j][t] = Math.min(dp[i][j][t], h[i][j] + dp[i][j+1][t-1]);

					if(valid(i,j-1,n,m))
						 dp[i][j][t] = Math.min(dp[i][j][t], h[i][j-1] + dp[i][j-1][t-1]);

					if(valid(i+1,j,n,m))
						 dp[i][j][t] = Math.min(dp[i][j][t], v[i][j] + dp[i+1][j][t-1]);

					if(valid(i-1,j,n,m))
						dp[i][j][t] = Math.min(dp[i][j][t], v[i-1][j] + dp[i-1][j][t-1]);

				}
			}
		}

		for(int i = 0; i<n; i++)
		{
			for(int j = 0; j<m; j++)
				out.print((dp[i][j][k/2]*2)+" ");

			out.println();
		}

	}

private static PrintWriter out = new PrintWriter(System.out);

public static void main (String[] args)
{
	MyScanner s =  new MyScanner();

    int n = s.nextInt();
    int m = s.nextInt();
    int k = s.nextInt();

    int[][] h = new int[n][m-1];

    for(int i = 0; i<n; i++)
    {
    	for(int j = 0; j<m-1; j++)
    	{
    		h[i][j] = s.nextInt();
    	}
    }

    int[][] v = new int[n-1][m];

    for(int i = 0; i<n-1; i++)
    {
    	for(int j = 0; j<m; j++)
    	{
    		v[i][j] = s.nextInt();
    	}
    }

   solution(n,m,k,h,v);

    out.flush();
    out.close();

}
}