#include <bits/stdc++.h>
using namespace std;
const long long MOD = 1e9 + 9;
const int N = (int)1e3 + 21;
const int inf = 2e9;
const int MAX = 1e4 + 12;
class CartesianTree {
  struct tree {
    tree *l, *r, *p;
    int prior, key;
    int sz, cnt;
    tree() {}
    tree(int _key) {
      l = r = p = nullptr;
      prior = rand();
      key = _key, sz = cnt = 1;
    }
  };
  inline int Size(tree *t) { return t ? t->sz : 0; }
  inline int Cnt(tree *t) { return t ? t->cnt : 0; }
  inline void updc(tree *t) {
    if (t) {
      t->sz = Size(t->l) + Size(t->r) + t->cnt;
      if (t->l) t->l->p = t;
      if (t->r) t->r->p = t;
    }
  }
  void split(tree *t, tree *&l, tree *&r, int sk) {
    if (!t) return void(l = r = nullptr);
    if (t->key > sk)
      split(t->l, l, t->l, sk), r = t;
    else
      split(t->r, t->r, r, sk), l = t;
    updc(t);
  }
  void merge(tree *&t, tree *l, tree *r) {
    if (!l || !r)
      t = l ? l : r;
    else if (l->prior > r->prior)
      merge(l->r, l->r, r), t = l;
    else
      merge(r->l, l, r->l), t = r;
    updc(t);
  }
  void print(tree *t) {
    if (!t) return;
    print(t->l);
    cout << " (" << t->key << "; " << t->cnt << "), ";
    print(t->r);
  }
  inline void Insert(tree *&t, int x) {
    tree *tl, *tr, *tm;
    split(t, tl, tr, x);
    split(tl, tl, tm, x - 1);
    if (tm)
      tm->cnt++;
    else
      tm = new tree(x);
    merge(t, tl, tm);
    merge(t, t, tr);
  }
  inline bool Erase(tree *&t, int x) {
    bool was = false;
    tree *tl, *tm, *tr;
    split(t, tl, tr, x);
    split(tl, tl, tm, x - 1);
    if (tm) {
      was = true;
      tm->cnt--;
      if (!tm->cnt) tm = nullptr;
    }
    merge(t, tl, tm);
    merge(t, tl, tr);
    return was;
  }
  inline int EraseAll(tree *&t, int x) {
    tree *tl, *tm, *tr;
    split(t, tl, tr, x);
    split(tl, tl, tm, x - 1);
    int Sz = Size(tm);
    merge(t, tl, tr);
    return Sz;
  }
  inline bool Find(tree *t, int x) {
    tree *tmp = t;
    while (tmp) {
      if (tmp->key == x) return true;
      if (tmp->key < x)
        tmp = tmp->r;
      else
        tmp = tmp->l;
    }
    return false;
  }
  inline int Next(tree *t, int x) {
    tree *tl, *tr;
    split(t, tl, tr, x);
    int Last = (int)2e9;
    tree *tmp = tr;
    while (tmp) {
      Last = min(Last, tmp->key);
      tmp = tmp->l;
    }
    merge(t, tl, tr);
    return Last;
  }
  inline int Prev(tree *t, int x) {
    tree *tl, *tr;
    split(t, tl, tr, x - 1);
    int Last = -(int)2e9;
    tree *tmp = tl;
    while (tmp) {
      Last = max(Last, tmp->key);
      tmp = tmp->r;
    }
    merge(t, tl, tr);
    return Last;
  }
  inline int Kth(tree *t, int k) {
    if (!t) return (int)2e9;
    if (k == Size(t->l) + 1) return t->key;
    if (k <= Size(t->l))
      return Kth(t->l, k);
    else
      return Kth(t->r, k - Size(t->l) - 1);
  }
  tree *root;
  int n;

 public:
  CartesianTree() {
    n = 0;
    root = nullptr;
  }
  void insert(int x) { Insert(root, -x); }
  void erase(int x) { n -= Erase(root, x); }
  void eraseall(int x) { n -= EraseAll(root, -x); }
  bool find(int x) { return Find(root, x); }
  void print() {
    print(root);
    cout << endl;
  }
  int Next(int x) { return Next(root, x); }
  int Prev(int x) { return Prev(root, x); }
  inline int Kth(int k) { return Kth(root, k); }
};
struct MinSegmentTree {
  vector<int> mn;
  int n;
  MinSegmentTree() {}
  MinSegmentTree(int sz, int a[]) {
    n = 1;
    while (n < sz) n <<= 1;
    mn.assign(2 * n, (int)2e9);
    for (int i = 0; i < n; i++) mn[n + i] = a[i];
    for (int i = n - 1; i > 0; i--) mn[i] = min(mn[2 * i], mn[2 * i + 1]);
  }
  inline int getmin(int l, int r) {
    int ret = (int)2e9;
    r--;
    for (l += n, r += n; l <= r; l >>= 1, r >>= 1) {
      if (l & 1) ret = min(ret, mn[l++]);
      if (!(r & 1)) ret = min(ret, mn[r--]);
    }
    return ret;
  }
};
template <const int N = 2500>
struct SuffixArray {
  int p[N], p2[N];
  int len[N];
  int nlen;
  int num[N + 1], col[N];
  MinSegmentTree Tr;
  template <class T>
  void build(int n, T *s) {
    int ma = n, t, cc = 0;
    for (int i = 0; i < n; i++) ma = max(ma, t = s[i]), col[i] = s[i], p[i] = i;
    for (int k2 = 1; (k2 >> 1) < n && cc != n - 1; k2 <<= 1) {
      int k = k2 >> 1;
      cc = 0;
      memset(num, 0, sizeof(num[0]) * (ma + 1));
      for (int i = 0; i < n; i++) num[col[i] + 1]++;
      for (int i = 0; i < ma; i++) num[i + 1] += num[i];
      for (int i = 0; i < n; i++)
        p2[num[col[(p[i] - k + n) % n]]++] = (p[i] - k + n) % n;
      for (int i = 0; i < n; i++) {
        cc += (i && (col[p2[i]] != col[p2[i - 1]] ||
                     col[(p2[i] + k) % n] != col[(p2[i - 1] + k) % n]));
        num[p2[i]] = cc;
      }
      for (int i = 0; i < n; i++) p[i] = p2[i], col[i] = num[i];
    }
    for (int i = 0; i < n; i++) p2[p[i]] = i;
  }
  template <class T>
  void buildLcp(int n, T s[]) {
    int lcp = 0;
    nlen = n;
    for (int i = 0; i < n; i++) {
      int j = p2[i];
      if (--lcp < 0) lcp = 0;
      if (j != n - 1)
        while (lcp < n && s[(p[j] + lcp) % n] == s[(p[j + 1] + lcp) % n]) lcp++;
      len[j] = lcp;
    }
    Tr = MinSegmentTree(n, len);
  }
  inline int Lcp(int num1, int num2) {
    if (num1 == num2) return nlen - num1 - 1;
    return Tr.getmin(min(num1, num2), max(num1, num2));
  }
};
template <class T>
struct StackMin {
  stack<pair<T, T> > st;
  void push(T x) {
    if (st.empty())
      st.push(make_pair(x, x));
    else
      st.push(make_pair(x, min(x, st.top().second)));
  }
  void pop() {
    if (!st.empty()) st.pop();
  }
  bool empty() { return st.empty(); }
  T top() {
    if (!st.empty()) return st.top().first;
  }
  T getmin() {
    if (!st.empty())
      return st.top().second;
    else
      return (int)2e9;
  }
};
template <class T>
struct QueueMin {
  QueueMin() {}
  StackMin<T> in, out;
  void trans() {
    while (!in.empty()) {
      out.push(in.top());
      in.pop();
    }
  }
  void push(T x) { in.push(x); }
  T front() {
    if (out.empty()) trans();
    return out.top();
  }
  T getmin() { return min(in.getmin(), out.getmin()); }
  void pop() {
    if (out.empty()) trans();
    out.pop();
  }
  inline bool empty() { return in.empty() && out.empty(); }
};
template <const int N = 2500>
struct MultySuffixArray {
  int p[N], p2[N];
  int len[N], Type[N];
  int nlen, CntOfAll;
  int num[N + 1], col[N];
  MinSegmentTree Tr;
  template <class T>
  void build(int n, pair<T, int> s[]) {
    int ma = n, t, cc = 0;
    nlen = n;
    CntOfAll = 0;
    for (int i = 0; i < n; i++)
      ma = max(ma, t = s[i].first), col[i] = s[i].first, p[i] = i;
    for (int k2 = 1; (k2 >> 1) < n && cc != n - 1; k2 <<= 1) {
      int k = k2 >> 1;
      cc = 0;
      memset(num, 0, sizeof(num[0]) * (ma + 1));
      for (int i = 0; i < n; i++) num[col[i] + 1]++;
      for (int i = 0; i < ma; i++) num[i + 1] += num[i];
      for (int i = 0; i < n; i++)
        p2[num[col[(p[i] - k + n) % n]]++] = (p[i] - k + n) % n;
      for (int i = 0; i < n; i++) {
        cc += (i && (col[p2[i]] != col[p2[i - 1]] ||
                     col[(p2[i] + k) % n] != col[(p2[i - 1] + k) % n]));
        num[p2[i]] = cc;
      }
      for (int i = 0; i < n; i++) p[i] = p2[i], col[i] = num[i];
    }
    for (int i = 0; i < n; i++) p2[p[i]] = i;
    for (int i = 0; i < n; i++) {
      Type[i] = s[p[i]].second;
      CntOfAll += (s[p[i]].second == 0);
    }
  }
  template <class T>
  void buildLcp(int n, pair<T, int> s[]) {
    int lcp = 0;
    nlen = n;
    for (int i = 0; i < n; i++) {
      int j = p2[i];
      if (--lcp < 0) lcp = 0;
      if (j != n - 1)
        while (lcp < n &&
               s[(p[j] + lcp) % n].first == s[(p[j + 1] + lcp) % n].first)
          lcp++;
      len[j] = lcp;
    }
    Tr = MinSegmentTree(n, len);
  }
  inline int Lcp(int num1, int num2) {
    if (num1 == num2) return nlen - num1 - 1;
    return Tr.getmin(min(p2[num1], p2[num2]), max(p2[num1], p2[num2]));
  }
  inline pair<int, int> LcsOfAll() {
    vector<int> was(nlen + 1, 0);
    int cnt = 0, l = 0, ans = 0;
    QueueMin<int> q;
    string ret = "";
    int pos = -1;
    for (int r = 0; r < nlen; r++) {
      if (Type[r] && !was[Type[r]]) cnt++;
      was[Type[r]]++;
      while (!q.empty() && CntOfAll <= cnt) {
        if (q.getmin() > ans) {
          ans = q.getmin();
          pos = l;
        }
        ans = max(ans, q.getmin());
        was[Type[l]]--;
        if (Type[l] && !was[Type[l]]) cnt--;
        l++;
        q.pop();
      }
      q.push(len[r]);
    }
    if (pos == -1) return make_pair(-1, -1);
    return make_pair(pos, ans);
  }
};
int main() {
  int n;
  cin >> n;
  vector<int> a(n), b(n);
  vector<int> xa, xb;
  for (int i = 0; i < n; i++) {
    cin >> a[i];
    if (a[i]) xa.push_back(a[i]);
  }
  for (int i = 0; i < n; i++) {
    cin >> b[i];
    if (b[i]) xb.push_back(b[i]);
  }
  int pos = -1;
  for (int i = 0; i < (int)a.size(); i++) {
    if (xa[i] == xb[0]) {
      pos = i;
      break;
    }
  }
  for (int i = 0; i < (int)xb.size(); i++) {
    if (xb[i] != xa[(i + pos) % (int)xa.size()]) {
      cout << "NO" << endl;
      return 0;
    }
  }
  cout << "YES" << endl;
}
