#include <bits/stdc++.h>
#pragma GCC optimize("O3")
#pragma GCC target("sse4")
using namespace std;
const int mxN = 1e5 + 5;
template <class T>
T gcd(T a, T b) {
  return ((b == 0) ? a : gcd(b, a % b));
}
int n, m;
int ind = 0;
int a[mxN], b[mxN];
struct segTree {
  int l, r;
  segTree *left, *right;
  long long val = 0, lazy = 0;
  segTree(int a, int b) {
    l = a;
    r = b;
    if (l != r) {
      int mid = (l + r) / 2;
      left = new segTree(l, mid);
      right = new segTree(mid + 1, r);
    }
  }
  void add(int a, int b, int v) {
    if (b < l || r < a) return;
    if (a <= l && r <= b) {
      lazy = v;
      val = v;
      return;
    }
    if (lazy) val = lazy;
    if (lazy) left->lazy = lazy;
    left->add(a, b, v);
    if (lazy) right->lazy = lazy;
    right->add(a, b, v);
    lazy = 0;
  }
  long long qry(int a, int b) {
    if (lazy) val = lazy;
    if (r < a || b < l) return 0;
    if (a <= l && r <= b) return val;
    if (lazy) {
      left->lazy = lazy;
      right->lazy = lazy;
    }
    lazy = 0;
    return max(left->qry(a, b), right->qry(a, b));
  }
};
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cin >> n >> m;
  for (int i = (int)(1); i < (int)(n + 1); i++) cin >> a[i];
  for (int i = (int)(1); i < (int)(n + 1); i++) cin >> b[i];
  vector<array<int, 3>> op;
  segTree tree(1, n);
  for (int i = 0; i < (int)(m); i++) {
    int t;
    cin >> t;
    if (t == 1) {
      int x, y, k;
      cin >> x >> y >> k;
      op.push_back({x, y, k});
      ind++;
      tree.add(y, y + k - 1, ind);
    } else {
      int nm;
      cin >> nm;
      int r = tree.qry(nm, nm);
      if (!r)
        cout << b[nm] << endl;
      else {
        r--;
        cout << a[op[r][0] + (nm - op[r][1])] << endl;
      }
    }
  }
  return 0;
}
