#include <bits/stdc++.h>
using namespace std;
const int MAXN = 2005;
const int MAXM = 4000005;
inline int read() {
  int weight = 0, symbol = 1;
  char in = getchar();
  while (!isdigit(in)) {
    if (in == '-') symbol = -1;
    in = getchar();
  }
  while (isdigit(in)) {
    weight = weight * 10 + in - '0';
    in = getchar();
  }
  return symbol * weight;
}
int n;
int head[MAXN];
struct node {
  int from, to;
  int next;
} edge[MAXM];
int edge_cnt;
void add_edge(int fr, int to) {
  edge[++edge_cnt].from = fr;
  edge[edge_cnt].to = to;
  edge[edge_cnt].next = head[fr];
  head[fr] = edge_cnt;
}
int dfn[MAXN], low[MAXN];
bool vis[MAXN];
stack<int> s;
int scc_cnt, cnt;
void tarjan(int x) {
  dfn[x] = low[x] = ++cnt;
  s.push(x), vis[x] = 1;
  for (int i = head[x]; i; i = edge[i].next) {
    int y = edge[i].to;
    if (!dfn[y]) {
      tarjan(y);
      low[x] = min(low[x], low[y]);
    } else if (vis[y])
      low[x] = min(low[x], dfn[y]);
  }
  if (dfn[x] == low[x]) {
    scc_cnt++;
    int y;
    do {
      y = s.top(), s.pop();
      vis[y] = 0;
    } while (x != y);
  }
}
int main() {
  n = read();
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j++) {
      int x = read();
      if (x) add_edge(i, j);
    }
  }
  for (int i = 1; i <= n; i++) {
    if (!dfn[i]) tarjan(i);
  }
  if (scc_cnt == 1)
    printf("YES\n");
  else
    printf("NO\n");
  return 0;
}
