#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:512000000")
using namespace std;
template <class T>
inline T sqr(T x) {
  return x * x;
}
template <class T>
inline string tostr(const T& x) {
  stringstream ss;
  ss << x;
  return ss.str();
}
const long double EPS = 1e-12;
const int INF = 1000 * 1000 * 1000;
const char CINF = 102;
const long long LINF = INF * 1ll * INF;
const long double DINF = 1e200;
const long double PI = 3.1415926535897932384626433832795l;
int gcd(int a, int b) { return a ? gcd(b % a, a) : b; }
long long gcd(long long a, long long b) { return a ? gcd(b % a, a) : b; }
long long powmod(long long a, long long p, long long m) {
  long long r = 1;
  while (p) {
    if (p & 1) r = r * a % m;
    p >>= 1;
    a = a * a % m;
  }
  return r;
}
int n;
bool G[2100][2100];
vector<int> A;
bool was[2100];
void dfs1(int v) {
  if (was[v]) return;
  was[v] = true;
  for (int i = 0; i < (n); ++i) {
    if (!G[v][i]) continue;
    dfs1(i);
  }
  A.push_back(v);
}
int dfs2(int v) {
  if (was[v]) return 0;
  was[v] = true;
  int r = 1;
  for (int i = 0; i < (n); ++i) {
    if (!G[i][v]) continue;
    r += dfs2(i);
  }
  return r;
}
int main() {
  cin >> n;
  for (int i = 0; i < (n); ++i) {
    for (int j = 0; j < (n); ++j) {
      int a;
      scanf("%d", &a);
      G[i][j] = !!a;
    }
  }
  dfs1(0);
  if (((int)(A).size()) < n) {
    cout << "NO";
    return 0;
  }
  memset(was, 0, sizeof(was));
  if (dfs2(A.back()) != n) {
    cout << "NO";
    return 0;
  }
  cout << "YES";
  return 0;
}
