#include <bits/stdc++.h>
const int MAX_NODE_COUNT = 5000000;
struct node;
typedef node *treap;
int get_size(treap t);
void inc_ref_cnt(treap &t);
struct node {
  int size, val;
  treap l, r;
  int ref_cnt;
  node() {}
  node(int val) : size(1), val(val), l(NULL), r(NULL), ref_cnt(0) {}
  node(int val, treap _l, treap _r)
      : size(get_size(_l) + get_size(_r) + 1),
        val(val),
        l(_l),
        r(_r),
        ref_cnt(0) {
    inc_ref_cnt(l);
    inc_ref_cnt(r);
  }
} * node_pool;
int *nxt_free_node, first_free_node;
void init_node_pool(int n) {
  node_pool = (node *)malloc(n * sizeof(node));
  nxt_free_node = (int *)malloc(n * sizeof(int));
  for (int i = 0; i < n - 1; ++i) nxt_free_node[i] = i + 1;
  nxt_free_node[n - 1] = -1;
  first_free_node = 0;
}
treap create_treap(int val, treap l, treap r) {
  treap t = &node_pool[first_free_node];
  first_free_node = nxt_free_node[first_free_node];
  t->size = get_size(l) + get_size(r) + 1;
  t->val = val;
  t->l = l;
  t->r = r;
  t->ref_cnt = 0;
  inc_ref_cnt(l);
  inc_ref_cnt(r);
  return t;
}
treap create_treap(int val) { return create_treap(val, NULL, NULL); }
void delete_treap(treap t) {
  if (!t) return;
  --t->ref_cnt;
  if (t->ref_cnt > 0) return;
  delete_treap(t->l);
  delete_treap(t->r);
  int treapNum = t - node_pool;
  nxt_free_node[treapNum] = first_free_node;
  first_free_node = treapNum;
}
inline int get_size(treap t) { return t ? t->size : 0; }
inline void update_size(treap &t) {
  if (t) t->size = get_size(t->l) + get_size(t->r) + 1;
}
inline void inc_ref_cnt(treap &t) {
  if (t) ++t->ref_cnt;
}
inline treap copy_treap(treap t) {
  if (!t) return NULL;
  return create_treap(t->val, t->l, t->r);
}
treap merge(treap l, treap r) {
  if (!l) return copy_treap(r);
  if (!r) return copy_treap(l);
  int ls = get_size(l), rs = get_size(r);
  return (rand() % (ls + rs) < ls) ? create_treap(l->val, l->l, merge(l->r, r))
                                   : create_treap(r->val, merge(l, r->l), r->r);
}
void split(int x, treap t, treap &l, treap &r) {
  treap tmp = NULL;
  if (!t)
    l = r = NULL;
  else if (x <= get_size(t->l)) {
    split(x, t->l, l, tmp);
    r = create_treap(t->val, tmp, t->r);
  } else {
    split(x - get_size(t->l) - 1, t->r, tmp, r);
    l = create_treap(t->val, t->l, tmp);
  }
}
inline void extract(int x, int k, treap t, treap &l, treap &m, treap &r) {
  treap tmp;
  split(x - 1, t, l, tmp);
  split(k, tmp, m, r);
  delete_treap(tmp);
}
inline int get(int x, treap t) {
  while (x != get_size(t->l) + 1) {
    if (x <= get_size(t->l))
      t = t->l;
    else {
      x -= get_size(t->l) + 1;
      t = t->r;
    }
  }
  return t->val;
}
treap read_treap(int n) {
  int x, y, cnt = 0, stack_y[1000];
  treap cur = NULL, stack[1000];
  memset(stack, 0, sizeof(stack_y));
  memset(stack, 0, sizeof(stack));
  for (int i = 0; i < n; ++i) {
    scanf("%d", &x);
    cur = create_treap(x);
    y = rand();
    while (cnt && y < stack_y[cnt - 1]) update_size(stack[--cnt]);
    cur->l = stack[cnt];
    update_size(cur);
    inc_ref_cnt(stack[cnt]);
    if (cnt) {
      stack[cnt - 1]->r = cur;
      update_size(stack[cnt - 1]);
      inc_ref_cnt(cur);
    }
    stack[cnt] = cur;
    stack_y[cnt++] = y;
    stack[cnt] = NULL;
    stack_y[cnt] = 0;
  }
  for (int i = cnt - 1; i >= 0; --i) update_size(stack[i]);
  return stack[0];
}
void print_treap(treap t) {
  if (!t) return;
  fprintf(stderr, "(");
  print_treap(t->l);
  fprintf(stderr, ")");
  fprintf(stderr, " %d ", t->val);
  fprintf(stderr, "(");
  print_treap(t->r);
  fprintf(stderr, ")");
}
int n, m;
treap a, b;
int main() {
  srand(time(0));
  scanf("%d%d", &n, &m);
  init_node_pool(MAX_NODE_COUNT);
  a = read_treap(n);
  b = read_treap(n);
  for (int i = 0; i < m; ++i) {
    int type;
    scanf("%d", &type);
    if (type & 1) {
      int x, y, k;
      scanf("%d%d%d", &x, &y, &k);
      treap trash, trash2, pa, lb, rb;
      extract(x, k, a, trash, pa, trash2);
      delete_treap(trash);
      delete_treap(trash2);
      extract(y, k, b, lb, trash, rb);
      delete_treap(trash);
      delete_treap(b);
      b = merge(lb, merge(pa, rb));
      delete_treap(pa);
      delete_treap(lb);
      delete_treap(rb);
    } else {
      int x;
      scanf("%d", &x);
      printf("%d\n", get(x, b));
    }
  }
  return 0;
}
