Problem: At Akabe High School, a programmer training school, there is a unique study session run by the students themselves. It is important for programmers to constantly adopt new technologies, so the aim of this activity is to develop the habit of self-study through this study session.

There are a total of N students, each with a score obtained as a result of the programming contest at the time of admission. At the study session, some of the N students will become leaders, and each leader will run their own group and join the group they run.

Students other than the leader cannot join a group run by a leader with a score lower than their own. In addition, one value r that is 0 or more is decided so that the difference between the scores of the students participating in the group and the leader is within r. That is, if the leader of a group has a score of s and your score is greater than or less than s --r, you will not be able to join the group.

You are the executive committee chair of the study session and decided to do a simulation to prepare for the operation. In the simulation, start with no leader and repeat the following operations several times.

* Add students as leaders.
* Remove the student from the leader.
* For the combination of leaders at the time of request, find the minimum r such that the number of students who cannot participate in any group is x or less.



Create a program that performs such a simulation.



input

The input consists of one dataset. The input is given in the following format.


N Q
s1
s2
::
sN
QUERY1
QUERY2
::
QUERYQ


The first line gives the number of students N (1 ≤ N ≤ 1000000) and the number of processing requests Q (0 ≤ Q ≤ 1000).

The following N lines are given the integer si (0 ≤ si ≤ 1,000,000,000) indicating the score of the i-th student. Students shall be numbered 1,2, ..., N.

The processing request QUERYi is given to the following Q line. Processing requests are given in chronological order. There are three types of processing requests: ADD, REMOVE, and CHECK, and each QUERYi is given in one of the following formats.


ADD a


Or


REMOVE a


Or


CHECK x


ADD a stands for adding a student with the number a (1 ≤ a ≤ N) to the leader.

REMOVE a represents removing the student with the number a (1 ≤ a ≤ N) from the leader.

CHECK x represents an output request. An upper limit on the number of students who cannot join any group x (0 ≤ x ≤ N) is given.

The input shall satisfy the following conditions.

* At any given time, the number of leaders will not exceed 100.
* Do not add students who are leaders at that time to leaders.
* Students who are not leaders at that time will not be removed from the leader.

output

At the time of each output request in chronological order, the minimum r is output on one line so that the number of students who cannot join any group is x or less. However, if it is impossible to reduce the number of people to x or less no matter what r is selected, NA is output.

Example

Input

5 8
5
10
8
7
3
ADD 1
ADD 3
CHECK 0
CHECK 1
CHECK 2
CHECK 3
CHECK 4
CHECK 5


Output

NA
2
1
0
0
0

Solution (in CPP):

Solution:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
using namespace std;
#define REP(i, b, e) for ( int i = b; i < e; i++)
#define rep(i, n) REP(i, 0, n)

static const int MAX_N = 1000000;
static const int MAX_P = 2000000000;

int N, M, Q, S[MAX_N];

map<int, int> PM; // point map
vector<int> ATI, ATV;
vector<int> MS;
set<int> R;
vector<pair<int, int> > seg;

void init(){
  MS.clear();
  for ( set<int>::iterator it = R.begin(); it != R.end(); it++ ){
    MS.push_back(S[*it]);
  }
  sort(MS.begin(), MS.end());
}

int getCount(int r){
  seg.clear();

  if ( MS.size() > 0 ) seg.push_back(make_pair(MS[0]-r, MS[0]));

  for ( int i = 1; i < MS.size(); i++ ){
    int b = MS[i]-r;
    int e = MS[i];
    if ( b <= seg[seg.size()-1].second){
      seg[seg.size()-1].second = max(seg[seg.size()-1].second, e);
    } else {
      seg.push_back(make_pair(b, e));
    }
  }

  int cnt = 0;

  for ( int i = 0; i < seg.size(); i++ ){
    int a = distance(ATI.begin(), lower_bound(ATI.begin(), ATI.end(), max(0, seg[i].first) )) - 1;
    int b = distance(ATI.begin(), lower_bound(ATI.begin(), ATI.end(), max(0, seg[i].second) ));
    cnt += ATV[b] - ATV[a];
  }

  return cnt;
}

void bsearch(int X){
  init();

  int l = 0;
  int r = MAX_P+2000000;
  int m;
  int diff = r - l;
  int cnt = getCount(r);
  if ( cnt < X ){
    cout << "NA" << endl;
    return;
  }

  //  for (int i = 0; i < 100; i++ ){
  while(1){
    m = (l+r)/2;
    cnt = getCount(m);
    if ( cnt >= X ){
      r = m;
    } else if ( cnt < X ){
      l = m;
    }
    if ( diff == l - r ) break;
    diff = l - r;
  }
  cout << r << endl;
}

int main(){
  scanf("%d %d", &N, &Q);

  MS.clear();
  PM.clear();
  ATI.clear();
  ATV.clear();

  rep(i, N) {
    scanf("%d", &S[i]);
    PM[S[i]]++;
  }

  bool isR[MAX_N];
  rep(i, N) isR[i] = false;

  M = 0;

  ATI.push_back(-1);
  ATV.push_back(0);
  int pre = 0;
  for ( map<int, int>::iterator it = PM.begin(); it != PM.end(); it++ ){
    ATI.push_back((*it).first);
    ATV.push_back((*it).second + ATV[pre++]);
  }

  string com;
  int x;
  rep(i, Q){
    cin >> com >> x;
    if ( com[0] == 'C' ){
      bsearch(N - x);
    } else if ( com[0] == 'R' ){
      x--; // 0 base
      R.erase(R.find(x));
      M--;
    } else if ( com[0] == 'A' ){
      x--; // 0 base
      R.insert(x);
      M++;
    }
  }
}