#include <bits/stdc++.h>
using namespace std;
template <typename Arg1>
void __f(const char* name, Arg1&& arg1) {
  cerr << name << " : " << arg1 << std::endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args) {
  const char* comma = strchr(names + 1, ',');
  cerr.write(names, comma - names) << " : " << arg1 << " | ";
  __f(comma + 1, args...);
}
template <class T>
T max(T a, T b, T c) {
  return ((a > b) ? ((a > c) ? a : c) : ((b > c) ? b : c));
}
template <class T>
T min(T a, T b, T c) {
  return ((a < b) ? ((a < c) ? a : c) : ((b < c) ? b : c));
}
const int MOD = (1e9) + 7;
const int MAXN = (1e5) + 9;
int T = 1, N = 1;
class node {
 public:
  int idx, mx;
  node() {
    idx = -1;
    mx = -1;
  }
};
vector<node> tree((8e5 + 4));
node merge(node a, node b) {
  node tmp;
  tmp.mx = max(a.mx, b.mx);
  if (a.mx == b.mx) {
    tmp.idx = max(a.idx, b.idx);
  } else {
    if (a.mx > b.mx)
      tmp.idx = a.idx;
    else
      tmp.idx = b.idx;
  }
  return tmp;
}
void build(vector<pair<int, int> >& vec, int idx, int st, int ed) {
  if (st == ed) {
    tree[idx].idx = st;
    tree[idx].mx = vec[st].second;
  } else {
    int mid = ((st + ed) >> 1);
    build(vec, (idx << 1), st, mid);
    build(vec, ((idx << 1) + 1), mid + 1, ed);
    tree[idx] = merge(tree[(idx << 1)], tree[((idx << 1) + 1)]);
  }
}
node query(int idx, int st, int ed, int l, int r) {
  node tmp;
  if (st > ed || st > r || ed < l) return tmp;
  if (st >= l && ed <= r) {
    return tree[idx];
  }
  int mid = ((st + ed) >> 1);
  return merge(query((idx << 1), st, mid, l, r),
               query(((idx << 1) + 1), mid + 1, ed, l, r));
}
int main() {
  ios_base ::sync_with_stdio(false);
  cin.tie(NULL);
  while (T--) {
    int n, m;
    cin >> n >> m;
    vector<int> vec(n);
    for (int i = 0; i < n; i++) {
      cin >> vec[i];
    }
    vector<pair<int, int> > q(m);
    for (int i = 0; i < m; i++) {
      cin >> q[i].first >> q[i].second;
      q[i].second--;
    }
    build(q, 1, 0, m - 1);
    int l = 0, r = m - 1;
    int x = 0, y = n - 1;
    vector<int> ans(n);
    int pre = 1;
    int updated = n;
    int idx = query(1, 0, m - 1, l, r).idx;
    idx = q[idx].second;
    sort(vec.begin(), vec.begin() + idx + 1);
    while (l <= r) {
      int idx = query(1, 0, m - 1, l, r).idx;
      if (pre == 1) {
        for (int i = updated - 1; i > q[idx].second; i--) {
          ans[i] = vec[y];
          y--;
        }
      } else {
        for (int i = updated - 1; i > q[idx].second; i--) {
          ans[i] = vec[x];
          x++;
        }
      }
      updated = q[idx].second + 1;
      pre = q[idx].first;
      l++;
    }
    vector<int> bar;
    for (int i = x; i <= y; i++) {
      bar.push_back(vec[i]);
    }
    sort(bar.begin(), bar.end());
    idx = 0;
    int sz = bar.size();
    if (pre == 1) {
      for (int i = updated - 1; i >= 0; i--) {
        ans[i] = bar[sz - idx - 1];
        idx++;
      }
    } else {
      for (int i = updated - 1; i >= 0; i--) {
        ans[i] = bar[idx];
        idx++;
      }
    }
    for (int i = 0; i < n; i++) {
      cout << ans[i] << " ";
    }
  }
  return 0;
}
