#include <bits/stdc++.h>
using namespace std;
void fastIO() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
}
struct SegTree {
  int n, Size;
  vector<vector<int>> vals, tree;
  SegTree(int N) {
    n = N;
    Size = 1;
    while (Size < n) Size <<= 1;
    Size <<= 1;
    vals.resize(Size);
    tree.resize(Size);
  }
  void init_update(int x, int lx, int rx, int poz, int val) {
    vals[x].emplace_back(val);
    if (lx == rx) return;
    int mid = (lx + rx) >> 1;
    if (poz <= mid)
      init_update(x << 1, lx, mid, poz, val);
    else
      init_update(x << 1 | 1, mid + 1, rx, poz, val);
  }
  void init_update(int x, int y) { init_update(1, 0, n - 1, x, y); }
  void init() {
    for (int i = 0; i < Size; ++i) {
      sort(vals[i].begin(), vals[i].end());
      vals[i].erase(unique(vals[i].begin(), vals[i].end()), vals[i].end());
      tree[i].resize(vals[i].size() + 1);
    }
  }
  void update(int x, int lx, int rx, int poz, int y, int val) {
    int pos = lower_bound(vals[x].begin(), vals[x].end(), y) - vals[x].begin();
    for (++pos; pos < (int)tree[x].size(); pos += pos & -pos)
      tree[x][pos] += val;
    if (lx == rx) return;
    int mid = (lx + rx) >> 1;
    if (poz <= mid)
      update(x << 1, lx, mid, poz, y, val);
    else
      update(x << 1 | 1, mid + 1, rx, poz, y, val);
  }
  void update(int x, int y, int val) { update(1, 0, n - 1, x, y, val); }
  int query(int x, int lx, int rx, int st, int dr, int val) {
    if (st <= lx && rx <= dr) {
      int pos = upper_bound(vals[x].begin(), vals[x].end(), val) -
                vals[x].begin() - 1;
      int ans = 0;
      for (++pos; pos > 0; pos -= pos & -pos) ans += tree[x][pos];
      return ans;
    }
    int mid = (lx + rx) >> 1, ans = 0;
    if (st <= mid) ans += query(x << 1, lx, mid, st, dr, val);
    if (mid < dr) ans += query(x << 1 | 1, mid + 1, rx, st, dr, val);
    return ans;
  }
  int query(int val, int st, int dr) { return query(1, 0, n - 1, st, dr, val); }
};
void solve() {
  int N, M;
  cin >> N >> M;
  vector<int> a(N), remap(N);
  for (int i = 0; i < N; ++i) {
    cin >> a[i];
    --a[i];
    remap[a[i]] = i;
  }
  vector<int> v(N);
  SegTree tree(N);
  for (int i = 0; i < N; ++i) {
    cin >> v[i];
    --v[i];
    v[i] = remap[v[i]];
    tree.init_update(i, v[i]);
  }
  vector<int> aux = v;
  vector<tuple<int, int, int, int>> queries;
  for (int i = 0; i < M; ++i) {
    int t;
    cin >> t;
    if (t == 1) {
      int l, r, lp, rp;
      cin >> l >> r >> lp >> rp;
      --l, --r, --lp, --rp;
      queries.emplace_back(l, r, lp, rp);
    } else {
      int x, y;
      cin >> x >> y;
      --x, --y;
      tree.init_update(x, v[y]);
      tree.init_update(y, v[x]);
      queries.emplace_back(x, y, -1, -1);
      swap(v[x], v[y]);
    }
  }
  v = aux;
  tree.init();
  for (int i = 0; i < N; ++i) tree.update(i, v[i], 1);
  for (int i = 0; i < M; ++i) {
    int l, r, lp, rp;
    tie(l, r, lp, rp) = queries[i];
    if (lp >= 0)
      cout << tree.query(r, lp, rp) - tree.query(l - 1, lp, rp) << '\n';
    else {
      int x = l, y = r;
      tree.update(x, v[x], -1);
      tree.update(y, v[y], -1);
      swap(v[x], v[y]);
      tree.update(x, v[x], 1);
      tree.update(y, v[y], 1);
    }
  }
}
int main() {
  fastIO();
  solve();
  return 0;
}
