#include <bits/stdc++.h>
using namespace std;
template <int POS, class TUPLE>
void deploy(std::ostream &os, const TUPLE &tuple) {}
template <int POS, class TUPLE, class H, class... Ts>
void deploy(std::ostream &os, const TUPLE &t) {
  os << (POS == 0 ? "" : ", ") << get<POS>(t);
  deploy<POS + 1, TUPLE, Ts...>(os, t);
}
template <class... Ts>
std::ostream &operator<<(std::ostream &os, const std::tuple<Ts...> &t) {
  os << "(";
  deploy<0, std::tuple<Ts...>, Ts...>(os, t);
  os << ")";
  return os;
}
template <class T>
std::ostream &operator<<(std::ostream &os, std::vector<T> &v) {
  int remain = v.size();
  os << "{";
  for (auto e : v) os << e << (--remain == 0 ? "" : ", ");
  os << "}";
  return os;
}
template <class T>
std::ostream &operator<<(std::ostream &os, std::set<T> &v) {
  int remain = v.size();
  os << "{";
  for (auto e : v) os << e << (--remain == 0 ? "" : ", ");
  os << "}";
  return os;
}
template <class T>
std::ostream &operator<<(std::ostream &os, std::queue<T> &q) {
  auto qq = q;
  os << "{";
  for (; !qq.empty(); qq.pop()) {
    os << qq.front() << (qq.size() != 1 ? ", " : "");
  }
  os << "}";
  return os;
}
template <class T>
std::ostream &operator<<(std::ostream &os, std::priority_queue<T> &q) {
  auto qq = q;
  os << "{";
  for (; !qq.empty(); qq.pop()) {
    os << qq.top() << (qq.size() != 1 ? ", " : "");
  }
  os << "}";
  return os;
}
template <class T, class K>
std::ostream &operator<<(std::ostream &os, std::pair<T, K> &p) {
  os << "(" << p.first << ", " << p.second << ")";
  return os;
}
template <class T, class K>
std::ostream &operator<<(std::ostream &os, std::map<T, K> &mp) {
  int remain = mp.size();
  os << "{";
  for (auto e : mp)
    os << "(" << e.first << " -> " << e.second << ")"
       << (--remain == 0 ? "" : ", ");
  os << "}";
  return os;
}
template <class T, class K>
std::ostream &operator<<(std::ostream &os, std::unordered_map<T, K> &mp) {
  int remain = mp.size();
  os << "{";
  for (auto e : mp)
    os << "(" << e.first << " -> " << e.second << ")"
       << (--remain == 0 ? "" : ", ");
  os << "}";
  return os;
}
void impossible() {
  cout << "IMPOSSIBLE" << endl;
  exit(0);
}
template <typename T>
class RangeMinimumQuery {
 public:
  T getMinimum(int left, int right);
  void update(int pos, T value);
  RangeMinimumQuery();
  RangeMinimumQuery(int size, T inf);
  ~RangeMinimumQuery();

 private:
  int size;
  T *tree;
  std::tuple<int, int, int, int> *dat;
};
template <typename T>
RangeMinimumQuery<T>::~RangeMinimumQuery() {
  delete[] dat;
  delete[] tree;
}
template <typename T>
RangeMinimumQuery<T>::RangeMinimumQuery() {
  size = 1;
  tree = new T[size];
  dat = new std::tuple<int, int, int, int>[size];
}
template <typename T>
RangeMinimumQuery<T>::RangeMinimumQuery(int size, T inf) {
  int dat_size = 3;
  for (this->size = 1; this->size < size; this->size <<= 1) dat_size += 2;
  dat = new std::tuple<int, int, int, int>[this->size];
  tree = new T[this->size * 2];
  for (int i = 0; i < this->size * 2; ++i) tree[i] = inf;
}
template <typename T>
inline T RangeMinimumQuery<T>::getMinimum(int left, int right) {
  std::tuple<int, int, int, int> *__restrict__ begin = dat;
  std::tuple<int, int, int, int> *__restrict__ ptr = begin;
  if (!(right <= 0 || size <= left)) {
    if (left <= 0 && size <= right)
      return tree[1];
    else
      *(ptr++) = std::make_tuple(1, 0, size, -1);
  }
  T minimum = tree[left + size];
  while (ptr != begin) {
    --ptr;
    int index = std::get<0>(*ptr);
    int cur_l = std::get<1>(*ptr);
    int cur_r = std::get<2>(*ptr);
    int mid = (cur_l + cur_r) >> 1;
    if (left < mid) {
      int next_index = (index << 1) + 0;
      if (left <= cur_l && mid <= right)
        minimum = std::min(minimum, tree[next_index]);
      else
        *(ptr++) = std::make_tuple(next_index, cur_l, mid, -1);
    }
    if (mid < right) {
      int next_index = (index << 1) + 1;
      if (left <= mid && cur_r <= right)
        minimum = std::min(minimum, tree[next_index]);
      else
        *(ptr++) = std::make_tuple(next_index, mid, cur_r, -1);
    }
  }
  return minimum;
}
template <typename T>
inline void RangeMinimumQuery<T>::update(int pos, T value) {
  pos += size;
  tree[pos] = value;
  while (1 < pos) {
    pos >>= 1;
    tree[pos] = min(tree[(pos << 1)], tree[(pos << 1) | 1]);
  }
}
const int64_t MAX = 1005000;
vector<int64_t> lefts[MAX];
vector<int64_t> rights[MAX];
void output(RangeMinimumQuery<int> &tree, int64_t pos, int64_t r) {
  if (r < pos) return;
  int right_most = -pos;
  for (auto t : lefts[pos]) {
    right_most = min(right_most, tree.getMinimum(pos + 1, t + 1));
  }
  int64_t next_r = abs(right_most);
  output(tree, pos + 1, next_r);
  printf("%d ", (int)pos);
  output(tree, next_r + 1, r);
}
int main() {
  int64_t n, m;
  cin >> n >> m;
  for (int64_t i = 0; i < ((int64_t)(m)); ++i) {
    int64_t p, c;
    string s;
    cin >> p >> c >> s;
    if (c <= p) impossible();
    if (s[0] == 'L') {
      lefts[p].push_back(c);
    } else {
      rights[p].push_back(c);
    }
  }
  RangeMinimumQuery<int> tree(MAX, 0);
  for (int64_t i = n; 0 <= i; --i) {
    int right_most = -i;
    for (auto t : lefts[i]) {
      right_most = min(right_most, tree.getMinimum(i + 1, t + 1));
    }
    for (auto t : rights[i])
      if (t <= abs(right_most)) impossible();
    for (auto t : rights[i]) {
      right_most = min(right_most, tree.getMinimum(i + 1, t + 1));
    }
    tree.update(i, right_most);
  }
  output(tree, 1, n);
}
