// 14th CPU Problem A
#include <bits/stdc++.h>
using namespace std;
 
#define all(v) v.begin(),v.end()
#define rall(v) v.rbegin(),v.rend()
#define pb push_back
#define ff first
#define ss second
#define ok cerr<<"Line "<<__LINE__<<" : "<<"ok"<<endl
#define DBG(a) cerr<< "Line "<<__LINE__ <<" : "<< #a <<" = "<<(a)<<endl
#define fastio {ios_base::sync_with_stdio(false);cin.tie(NULL);}


#define Gene template< class
#define Rics printer& operator,
Gene c> struct rge{c b, e;};
Gene c> rge<c> range(c i, c j){ return {i, j};}
struct printer{
 ~printer(){cerr<<endl;}
 Gene c >Rics(c x){ cerr<<boolalpha<<x; return *this;}
 Rics(string x){cerr<<x;return *this;}
 Gene c, class d >Rics(pair<c, d> x){ return *this,"(",x.first,", ",x.second,")";}
 Gene ... d, Gene ...> class c >Rics(c<d...> x){ return *this, range(begin(x), end(x));}
 Gene c >Rics(rge<c> x){
     *this,"["; for(auto it = x.b; it != x.e; ++it)
         *this,(it==x.b?"":", "),*it; return *this,"]";}
};
#define debug() cerr<<"LINE "<<__LINE__<<" >> ", printer()
#define dbg(x) "[",#x,": ",(x),"] "
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int my_rand(int l, int r) {
 return uniform_int_distribution<int>(l, r) (rng);
}

 
typedef long long ll;
typedef pair<int,int> pii;
 


const int N = 200009;
vector< array<int,3> > operation;
// 0-> value, 1->active, 2->label
vector<array<int,3>> finalAr; // 1 based index,dummy insert at first

struct Node {
  int value,active,label;
  Node* left;
  Node* right;
};

map<int,Node*> nodeMap;
map<int,int> labelToIdx;

Node* head = nullptr;
Node* tail = nullptr;

void append(int val, int label) {
    
    Node* newNode = new Node();
    newNode->value = val;
    newNode->active = 1;
    newNode-> label = label;
    newNode->left = nullptr;
    newNode->right = nullptr;
    
    nodeMap[val] = newNode;
    
    if (head == nullptr) {
        head = tail = newNode;
    } else {
        tail->right = newNode;
        newNode->left = tail;
        tail = newNode;
    }
}

void insertAfter(int newVal,int existingVal, int label) {
  Node* existingNode = nodeMap[existingVal];

  Node* newNode = new Node();
  newNode -> value = newVal;
  newNode->active = 1;
  newNode-> label = label;
  newNode -> left = existingNode;
  newNode -> right = existingNode -> right;

  // Update Links
  if (existingNode -> right != nullptr) {
    existingNode -> right -> left = newNode;
  } else {
    tail = newNode;
  }
  existingNode->right = newNode;

  nodeMap[newVal] = newNode;
}

void insertBefore(int newVal,int existingVal, int label) {
  

    Node* existingNode = nodeMap[existingVal];
    
    Node* newNode = new Node();
    newNode->value = newVal;
    newNode->active = 1;
    newNode->label = label;
    newNode->right = existingNode;
    newNode->left = existingNode->left;
    
  
    if (existingNode->left != nullptr) {
        existingNode->left->right = newNode;
    } else {
        head = newNode;
    }
    existingNode->left = newNode;
    
    nodeMap[newVal] = newNode;
}

void remove(int val) {
    Node* target = nodeMap[val];
    
    target -> active = 0;
    // if (target->left != nullptr) {
    //     target->left->right = target->right;
    // } else {
    //     head = target->right;  
    // }
    
    // if (target->right != nullptr) {
    //     target->right->left = target->left;
    // } else {
    //     tail = target->left;
    // }
    
    // Remove from map and free memory
    nodeMap.erase(val);
    // delete target;
}


void buildFinalArray() {
    finalAr.clear();
    // 1 base index, push a dummy value;
    finalAr.push_back({-1,-1,-1});

    Node* cur = head;
    int idx = 1;
    while (cur != nullptr) {
        // cout << curr->value;
        finalAr.push_back({cur->value,cur->active,cur->label});
        labelToIdx[cur->label] = idx++;
        cur = cur->right;
    }
   
    // for(int i = 0; i < (int)finalAr.size(); i++){
    //   cout << "( " << finalAr[i][0] << " " << finalAr[i][1] << " ";
    //   cout << finalAr[i][2] << ") ";
    // }
    // cout << endl;
}

// ====== Segment Tree Portion ======
// idx 0 : sum, idx 1: count
ll treeInfo[N*4][2];

void build(int n,int b,int e) {
  if (b == e) {
    treeInfo[n][0] = treeInfo[n][1] = 0;
    if (finalAr[b][1] == 1) {
      treeInfo[n][0] = finalAr[b][0];
      treeInfo[n][1] =1;
    }
    return;
  }

  int mid = (b + e) >> 1, l = n << 1, r = l | 1;
  build(l, b, mid);
  build(r, mid + 1, e);
  //merge
  treeInfo[n][0] = treeInfo[l][0] + treeInfo[r][0];
  treeInfo[n][1] = treeInfo[l][1] + treeInfo[r][1];
}

void update(int n,int b,int e, int idx, int value)
{
  if (b > idx || e < idx) return;
  if (b == e && b == idx) {
    treeInfo[n][0] = value;
    if (value > 0) {
      treeInfo[n][1] = 1;
    }
    else treeInfo[n][1] = 0;

    return;
  }

  int mid = (b + e) >> 1, l = n << 1, r = l | 1;
  update(l,b,mid,idx,value);
  update(r,mid+1,e,idx,value);

  //merge
  treeInfo[n][0] = treeInfo[l][0] + treeInfo[r][0];
  treeInfo[n][1] = treeInfo[l][1] + treeInfo[r][1];
}

// return sum of first m element
ll query(int n,int b,int e, int m)
{
  if (treeInfo[n][1] == m) return treeInfo[n][0];

  int mid = (b + e) >> 1, l = n << 1, r = l | 1;
  if (treeInfo[l][1] > m) {
    return query(l,b,mid,m);
  } else {
    return treeInfo[l][0] + query(r,mid+1,e, m - treeInfo[l][1]);
  }
}

int main()
{
  // fastio;
  int q,first;
  cin >> q >> first;

  append(first,0);
  map<int,int> labelLook;
  labelLook[first] = 0;
  operation.push_back({-1,first,-1});

  for(int i = 1; i <= q; i++){
    int typ = 0, l = -1, r = -1;
    cin >> typ;
  
    if (typ == 3) {
      cin >> l;
      remove(l);
      operation.push_back({typ,l,labelLook[l]});
      labelLook.erase(l);
    } 
    else {
    
      cin >> l >> r;

      if (typ == 1) {
      
        insertBefore(l,r,i);
        labelLook[l] = i;
      }
      else if(typ == 2) {
        insertAfter(l,r,i);
        labelLook[l] = i;
      }
      operation.push_back({typ,l,r});
    }
   
  }

  buildFinalArray();
 
  // build update query
  int n = finalAr.size() - 1;
  build(1,1,n);

  vector<ll> output;

  for(int i = operation.size()-1; i >= 1; i--) {
    int typ = operation[i][0];
    int l = operation[i][1];
    int r = operation[i][2];

    if (typ == 1 || typ == 2) {
      int idx = labelToIdx[i];
      update(1,1,n,idx,0);
    }
    else if (typ == 3) {
      int idx = labelToIdx[r]; // r is the label of removing numbr
      update(1,1,n,idx,l); // l is the value of removed number, as we iterate reverse. add the number
    }
    else if (typ == 4) {
      ll ans = query(1,1,n,r) - query(1,1,n,l-1);
      output.push_back(ans);
    }
  }

 
  for(int i = output.size()-1; i >= 0; i--){
    cout << output[i] << "\n";
  }


  return 0;
}