#include <bits/stdc++.h>
using namespace std;
template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &_p) {
  return os << "(" << _p.first << "," << _p.second << ")";
}
template <typename T>
ostream &operator<<(ostream &os, const vector<T> &_V) {
  bool f = true;
  os << "[";
  for (auto v : _V) {
    os << (f ? "" : ",") << v;
    f = false;
  }
  return os << "]";
}
template <typename T>
ostream &operator<<(ostream &os, const set<T> &_S) {
  bool f = true;
  os << "(";
  for (auto s : _S) {
    os << (f ? "" : ",") << s;
    f = false;
  }
  return os << ")";
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &_M) {
  return os << set<pair<T, U>>(_M.begin(), _M.end());
}
const signed long long INF = 1000000100;
const long double EPS = 1e-9;
inline int pop2(unsigned x, unsigned y) {
  x = x - ((x >> 1) & 0x55555555);
  y = y - ((y >> 1) & 0x55555555);
  x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
  y = (y & 0x33333333) + ((y >> 2) & 0x33333333);
  x = (x + (x >> 4)) & 0x0F0F0F0F;
  y = (y + (y >> 4)) & 0x0F0F0F0F;
  x = x + (x >> 8);
  y = y + (y >> 8);
  x = x + (x >> 16);
  y = y + (y >> 16);
  return (x + y) & 0x000000FF;
}
inline int pop(signed long long a) { return pop2(a << 32 >> 32, a >> 32); }
struct bits {
  vector<signed long long> data;
  int size;
  bits(int n) {
    data.resize((n + 63) / 64, 0);
    size = n;
  }
  void set(int k) { data[k / 64] |= (1LL << (k % 64)); }
  template <typename T>
  bits(T bs) : bits(int(bs.size())) {
    int bucket = 0;
    int bit_id = 0;
    for (bool b : bs) {
      if (b) {
        data[bucket] |= (1LL << bit_id);
      }
      ++bit_id;
      if (bit_id == 64) {
        ++bucket;
        bit_id = 0;
      }
    }
  }
  int popcount() {
    int ret = 0;
    for (signed long long a : data) {
      ret += __builtin_popcountll(a);
    }
    return ret;
  }
  friend ostream &operator<<(ostream &os, const bits &bs) {
    int id = 0;
    for (signed long long bucket : bs.data) {
      for (int(i) = (0); (i) < (64); (i)++) {
        if (id++ < bs.size) {
          if (((1LL << i) & bucket) != 0) {
            os << 1;
          } else {
            os << 0;
          }
        }
      }
    }
    return os;
  }
};
template <typename F>
bits binary_bits_op(const bits &p, const bits &q, F f) {
  const bits &x = (p.size < q.size) ? q : p;
  const bits &y = (p.size < q.size) ? p : q;
  bits ret = x;
  for (int(i) = (0); (i) < (int(y.data.size())); (i)++) {
    ret.data[i] = f(ret.data[i], y.data[i]);
  }
  return move(ret);
}
bits operator|(const bits &p, const bits &q) {
  return binary_bits_op(
      p, q, [](signed long long a, signed long long b) { return a | b; });
}
bits operator&(const bits &p, const bits &q) {
  return binary_bits_op(
      p, q, [](signed long long a, signed long long b) { return a & b; });
}
bits operator^(const bits &p, const bits &q) {
  return binary_bits_op(
      p, q, [](signed long long a, signed long long b) { return a ^ b; });
}
int collide(const bits &p, const bits &q) {
  const bits &x = (p.size < q.size) ? q : p;
  const bits &y = (p.size < q.size) ? p : q;
  int ret = 0;
  for (int(i) = (0); (i) < (int(y.data.size()) - 1); (i)++) {
    int d = pop(x.data[i] | y.data[i]);
    if (__builtin_expect(d == 64, true)) {
      ret += d;
    } else {
      return 0;
    }
  }
  return ret + pop(x.data.back() | y.data.back());
}
const int MAXN = 2525;
int A[MAXN][MAXN];
int N;
void read_data() {
  scanf("%d", &N);
  for (int(i) = (1); (i) <= (N); (i)++)
    for (int(j) = (1); (j) <= (N); (j)++) {
      scanf("%d", &A[i][j]);
    }
}
bool solve() {
  for (int(i) = (1); (i) <= (N); (i)++)
    for (int(j) = (1); (j) <= (N); (j)++)
      if (A[i][j] != A[j][i]) {
        return false;
      }
  for (int(i) = (1); (i) <= (N); (i)++)
    if (A[i][i] != 0) {
      return false;
    }
  vector<tuple<int, int, int>> edges;
  for (int(i) = (1); (i) <= (N); (i)++)
    for (int(j) = (i + 1); (j) <= (N); (j)++) {
      edges.emplace_back(A[i][j], i, j);
    }
  sort(edges.begin(), edges.end());
  reverse(edges.begin(), edges.end());
  vector<bits> first(N, bits(N));
  for (int(i) = (0); (i) < (int(edges.size())); (i)++) {
    int j = i;
    while (j + 1 < int(edges.size()) and
           get<0>(edges[j + 1]) == get<0>(edges[j])) {
      ++j;
    }
    for (int(k) = (i); (k) <= (j); (k)++) {
      int w, a, b;
      tie(w, a, b) = edges[k];
      first[a - 1].set(b - 1);
      first[b - 1].set(a - 1);
    }
    for (int(k) = (i); (k) <= (j); (k)++) {
      int w, a, b;
      tie(w, a, b) = edges[k];
      if (collide(first[a - 1], first[b - 1]) < N) {
        return false;
      }
    }
    i = j;
  }
  return true;
}
int main() {
  read_data();
  printf(solve() ? "MAGIC\n" : "NOT MAGIC\n");
}
