#include <bits/stdc++.h>
using namespace std;
int n, X, Y, a[1010][1010], c[2000010], tot;
long long ans;
struct node {
  int Min, flag;
  void push(int num) {
    Min = max(Min, num);
    flag = max(flag, num);
  }
};
struct seg_tre {
  node tr[5000010];
  void updata(int p) {
    tr[p].Min = min(tr[(p << 1)].Min, tr[((p << 1) + 1)].Min);
  }
  void pushdown(int p) {
    tr[(p << 1)].push(tr[p].flag);
    tr[((p << 1) + 1)].push(tr[p].flag);
    tr[p].flag = 0;
  }
  void Cover(int p, int l, int r, int a, int b, int num) {
    if (l == a && r == b) {
      tr[p].push(num);
      return;
    }
    if (tr[p].flag) pushdown(p);
    if (b <= ((l + r) >> 1))
      Cover((p << 1), l, ((l + r) >> 1), a, b, num);
    else if (a >= ((l + r) >> 1))
      Cover(((p << 1) + 1), ((l + r) >> 1), r, a, b, num);
    else {
      Cover((p << 1), l, ((l + r) >> 1), a, ((l + r) >> 1), num);
      Cover(((p << 1) + 1), ((l + r) >> 1), r, ((l + r) >> 1), b, num);
    }
    updata(p);
  }
  int GetMin(int p, int l, int r, int a, int b) {
    if (l == a && r == b) return tr[p].Min;
    if (tr[p].flag) pushdown(p);
    if (b <= ((l + r) >> 1)) return GetMin((p << 1), l, ((l + r) >> 1), a, b);
    if (a >= ((l + r) >> 1))
      return GetMin(((p << 1) + 1), ((l + r) >> 1), r, a, b);
    return min(GetMin((p << 1), l, ((l + r) >> 1), a, ((l + r) >> 1)),
               GetMin(((p << 1) + 1), ((l + r) >> 1), r, ((l + r) >> 1), b));
  }
} T;
void read(int &x) {
  char ch = getchar();
  int mark = 1;
  for (; ch != '-' && (ch < '0' || ch > '9'); ch = getchar())
    ;
  if (ch == '-') mark = -1, ch = getchar();
  for (x = 0; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - 48;
  x *= mark;
}
inline int make(const int &x, const int &y) { return Y * x - X * y; }
int main() {
  read(n);
  read(X);
  read(Y);
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= n; j++) read(a[i][j]);
  if (X < 0) {
    for (int i = 1; i <= n / 2; i++)
      for (int j = 1; j <= n; j++) swap(a[i][j], a[n - i + 1][j]);
    X = -X;
  }
  if (Y < 0) {
    for (int i = 1; i <= n; i++)
      for (int j = 1; j <= n / 2; j++) swap(a[i][j], a[i][n - j + 1]);
    Y = -Y;
  }
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= n; j++) {
      c[++tot] = make(i - 1, j);
      c[++tot] = make(i, j - 1);
    }
  sort(c + 1, c + tot + 1);
  tot = unique(c + 1, c + tot + 1) - (c + 1);
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= n; j++) {
      int l = lower_bound(c + 1, c + tot + 1, make(i - 1, j)) - c,
          r = lower_bound(c + 1, c + tot + 1, make(i, j - 1)) - c;
      int t = T.GetMin(1, 1, tot, l, r);
      if (a[i][j] > t) {
        ans += a[i][j] - t;
        T.Cover(1, 1, tot, l, r, a[i][j]);
      }
    }
  printf("%I64d\n", ans);
  return 0;
}
