#include <bits/stdc++.h>
using namespace std;
struct Node {
  int left, right, pos;
  int mid() { return (left + right) >> 1; }
};
const int maxn = 100100;
int a[maxn], b[maxn], op, n, m, x, y, z;
Node tree[maxn * 5];
void pushDown(int idx) {
  if (tree[idx].pos) {
    tree[idx << 1].pos = tree[idx].pos;
    tree[idx].pos = 0;
    tree[idx << 1 | 1].pos =
        tree[idx << 1].pos + tree[idx << 1].right - tree[idx << 1].left + 1;
  }
}
void build(int left, int right, int idx) {
  tree[idx].left = left;
  tree[idx].right = right;
  tree[idx].pos = 0;
  if (left == right) return;
  int mid = tree[idx].mid();
  build(left, mid, idx << 1);
  build(mid + 1, right, idx << 1 | 1);
}
void update(int left, int right, int pos, int idx) {
  if (tree[idx].left >= left && tree[idx].right <= right) {
    tree[idx].pos = pos;
    return;
  }
  pushDown(idx);
  int mid = tree[idx].mid();
  if (mid >= right)
    update(left, right, pos, idx << 1);
  else if (mid < left)
    update(left, right, pos, idx << 1 | 1);
  else {
    update(left, mid, pos, idx << 1);
    update(mid + 1, right, pos + mid - left + 1, idx << 1 | 1);
  }
}
int query(int pos, int idx) {
  if (tree[idx].left == tree[idx].right) return tree[idx].pos;
  pushDown(idx);
  int mid = tree[idx].mid();
  if (mid >= pos)
    return query(pos, idx << 1);
  else
    return query(pos, idx << 1 | 1);
}
int main() {
  scanf("%d %d", &n, &m);
  for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
  for (int i = 1; i <= n; i++) scanf("%d", &b[i]);
  build(1, n, 1);
  for (int q = 0; q < m; q++) {
    scanf("%d", &op);
    if (op == 1) {
      scanf("%d %d %d", &x, &y, &z);
      update(y, y + z - 1, x, 1);
    } else {
      scanf("%d", &x);
      int res = query(x, 1);
      if (res == 0)
        printf("%d\n", b[x]);
      else
        printf("%d\n", a[res]);
    }
  }
  return 0;
}
