#include <bits/stdc++.h>
using namespace std;
inline int readint() {
  int a = 0;
  char c = getchar(), f = 1;
  for (; c < '0' || c > '9'; c = getchar())
    if (c == '-') f = -f;
  for (; '0' <= c && c <= '9'; c = getchar())
    a = (a << 3) + (a << 1) + (c ^ 48);
  return a * f;
}
template <typename T>
void getMax(T &a, const T &b) {
  if (a < b) a = b;
}
template <typename T>
void getMin(T &a, const T &b) {
  if (b < a) a = b;
}
const int MaxN = 2501;
namespace ufs {
int fa[MaxN];
void init(int n) {
  for (int i = 1; i <= n; ++i) fa[i] = i;
}
int find(int a) {
  if (a != fa[a]) fa[a] = find(fa[a]);
  return fa[a];
}
bool linked(int a, int b) { return find(a) == find(b); }
void link(int a, int b) { fa[find(a)] = find(b); }
}  // namespace ufs
struct Node {
  int x, y, val;
  bool operator<(const Node &that) const { return val < that.val; }
} node[MaxN * MaxN];
int n;
void kruskal() {
  sort(node + 1, node + n * n + 1);
  node[n * n + 1].val = -1;
  ufs::init(n);
  for (int l = 1, r = 0; l <= n * n; l = r + 1) {
    while (node[r + 1].val == node[l].val) ++r;
    if (node[l].val != 0)
      for (int i = l; i <= r; ++i)
        if (ufs::linked(node[i].x, node[i].y)) {
          puts("NOT MAGIC");
          return;
        }
    for (int i = l; i <= r; ++i) ufs::link(node[i].x, node[i].y);
  }
  puts("MAGIC");
}
int main() {
  n = readint();
  for (int i = 1; i <= n; ++i)
    for (int j = 1; j <= n; ++j) {
      Node &now = node[(i - 1) * n + j];
      now.x = i, now.y = j;
      now.val = readint();
      if (i == j && now.val) {
        puts("NOT MAGIC");
        return 0;
      }
    }
  kruskal();
  return 0;
}
