← Home
package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
)

type FastScanner struct {
	r *bufio.Reader
}

func NewFastScanner() *FastScanner {
	return &FastScanner{r: bufio.NewReaderSize(os.Stdin, 1<<20)}
}

func (fs *FastScanner) nextToken() (string, error) {
	b := make([]byte, 0, 16)
	// skip spaces
	for {
		c, err := fs.r.ReadByte()
		if err != nil {
			return "", err
		}
		if c > ' ' {
			b = append(b, c)
			break
		}
	}
	for {
		c, err := fs.r.ReadByte()
		if err != nil {
			break
		}
		if c <= ' ' {
			break
		}
		b = append(b, c)
	}
	return string(b), nil
}

func (fs *FastScanner) NextInt() (int, error) {
	tok, err := fs.nextToken()
	if err != nil {
		return 0, err
	}
	sign := 1
	i := 0
	if tok[0] == '-' {
		sign = -1
		i = 1
	}
	n := 0
	for ; i < len(tok); i++ {
		n = n*10 + int(tok[i]-'0')
	}
	return sign * n, nil
}

func (fs *FastScanner) NextString() (string, error) {
	return fs.nextToken()
}

type pair struct {
	a   int
	dir byte // 0=LEFT,1=RIGHT
}

type interval struct {
	l int
	r int
}

type minHeap struct {
	data []int
}

func (h *minHeap) push(x int) {
	h.data = append(h.data, x)
	i := len(h.data) - 1
	for i > 0 {
		p := (i - 1) >> 1
		if h.data[p] <= h.data[i] {
			break
		}
		h.data[p], h.data[i] = h.data[i], h.data[p]
		i = p
	}
}

func (h *minHeap) pop() int {
	n := len(h.data)
	if n == 0 {
		return 0
	}
	res := h.data[0]
	n--
	if n > 0 {
		h.data[0] = h.data[n]
	}
	h.data = h.data[:n]
	// heapify down
	i := 0
	for {
		l := i*2 + 1
		if l >= n {
			break
		}
		r := l + 1
		m := l
		if r < n && h.data[r] < h.data[l] {
			m = r
		}
		if h.data[i] <= h.data[m] {
			break
		}
		h.data[i], h.data[m] = h.data[m], h.data[i]
		i = m
	}
	return res
}

func (h *minHeap) top() int {
	if len(h.data) == 0 {
		return 0
	}
	return h.data[0]
}

func (h *minHeap) empty() bool {
	return len(h.data) == 0
}

func impossible() {
	fmt.Println("IMPOSSIBLE")
}

func main() {
	in := NewFastScanner()
	n, err := in.NextInt()
	if err != nil {
		return
	}
	c, err := in.NextInt()
	if err != nil {
		return
	}

	A := make([]int, c)
	B := make([]int, c)
	D := make([]byte, c) // 0=LEFT 1=RIGHT

	LB := make([]int, n+2)   // s lower bound
	UB := make([]int, n+2)   // s upper bound
	rLB := make([]int, n+2)  // r lower bound
	for i := 1; i <= n; i++ {
		LB[i] = i + 1
		UB[i] = n + 1
		rLB[i] = i
	}

	for i := 0; i < c; i++ {
		ai, _ := in.NextInt()
		bi, _ := in.NextInt()
		dirStr, _ := in.NextString()
		var dir byte
		if dirStr[0] == 'L' {
			dir = 0
		} else {
			dir = 1
		}
		if ai < 1 || ai > n || bi < 1 || bi > n {
			impossible()
			return
		}
		if bi <= ai {
			impossible()
			return
		}
		A[i] = ai
		B[i] = bi
		D[i] = dir
		// Local LB/UB adjustments
		if dir == 0 {
			if bi+1 > LB[ai] {
				LB[ai] = bi + 1
			}
		} else {
			if bi < UB[ai] {
				UB[ai] = bi
			}
		}
	}

	// Group by B, then by A
	idx := make([]int, c)
	for i := 0; i < c; i++ {
		idx[i] = i
	}
	sort.Slice(idx, func(i, j int) bool {
		ib := idx[i]
		jb := idx[j]
		if B[ib] != B[jb] {
			return B[ib] < B[jb]
		}
		if A[ib] != A[jb] {
			return A[ib] < A[jb]
		}
		return D[ib] < D[jb]
	})

	// Process chains per b
	for p := 0; p < c; {
		start := p
		bv := B[idx[p]]
		for p < c && B[idx[p]] == bv {
			p++
		}
		// Compress duplicates by A
		tmp := make([]pair, 0, p-start)
		for q := start; q < p; {
			ai := A[idx[q]]
			dir := D[idx[q]]
			q2 := q + 1
			conflict := false
			for q2 < p && A[idx[q2]] == ai {
				if D[idx[q2]] != dir {
					conflict = true
					break
				}
				q2++
			}
			if conflict {
				impossible()
				return
			}
			tmp = append(tmp, pair{a: ai, dir: dir})
			q = q2
		}
		sort.Slice(tmp, func(i, j int) bool { return tmp[i].a < tmp[j].a })
		// Ensure increasing A
		for i := 1; i < len(tmp); i++ {
			if tmp[i-1].a >= tmp[i].a {
				impossible()
				return
			}
		}
		// Apply constraints along the chain
		for i := 0; i < len(tmp); i++ {
			ai := tmp[i].a
			dir := tmp[i].dir
			next := bv
			if i+1 < len(tmp) {
				next = tmp[i+1].a
			}
			if next <= ai {
				impossible()
				return
			}
			if dir == 0 {
				if next+1 > LB[ai] {
					LB[ai] = next + 1
				}
			} else {
				if next < UB[ai] {
					UB[ai] = next
				}
			}
			if next > rLB[ai] {
				rLB[ai] = next
			}
		}
	}

	// Finalize s bounds and choose s
	s := make([]int, n+2)
	for i := 1; i <= n; i++ {
		if LB[i] < i+1 {
			LB[i] = i + 1
		}
		if UB[i] > n+1 {
			UB[i] = n + 1
		}
		if LB[i] > UB[i] {
			impossible()
			return
		}
		s[i] = LB[i]
	}

	// Build intervals (a+1 .. s[a]-1) with end = s[a]-1
	ints := make([]interval, 0, n/2+1)
	for a := 1; a <= n; a++ {
		l := a + 1
		r := s[a] - 1
		if r >= l {
			ints = append(ints, interval{l: l, r: r})
		}
	}
	sort.Slice(ints, func(i, j int) bool {
		if ints[i].l != ints[j].l {
			return ints[i].l < ints[j].l
		}
		return ints[i].r < ints[j].r
	})

	// Sweep to compute r upper bounds
	rUB := make([]int, n+2)
	for i := 1; i <= n; i++ {
		rUB[i] = n
	}
	h := &minHeap{data: make([]int, 0)}
	ptr := 0
	for j := 2; j <= n; j++ {
		for ptr < len(ints) && ints[ptr].l == j {
			h.push(ints[ptr].r)
			ptr++
		}
		for !h.empty() && h.top() < j {
			h.pop()
		}
		if !h.empty() {
			rUB[j] = h.top()
		} else {
			rUB[j] = n
		}
	}
	rUB[1] = n

	// Choose r within [max(j, rLB), rUB]
	r := make([]int, n+2)
	for i := 1; i <= n; i++ {
		lb := rLB[i]
		if lb < i {
			lb = i
		}
		ub := rUB[i]
		if lb > ub {
			impossible()
			return
		}
		r[i] = ub
	}
	// Ensure root covers all
	if r[1] < n {
		r[1] = n
	}

	// Build tree using s and r
	left := make([]int, n+2)
	right := make([]int, n+2)
	stack := make([]int, 0, 64)
	stack = append(stack, 1)
	for k := 2; k <= n; k++ {
		for {
			if len(stack) == 0 {
				impossible()
				return
			}
			t := stack[len(stack)-1]
			if k > r[t] {
				stack = stack[:len(stack)-1]
				continue
			}
			if s[t] > k {
				if left[t] != 0 {
					impossible()
					return
				}
				left[t] = k
				stack = append(stack, k)
				break
			} else {
				if right[t] == 0 {
					right[t] = k
					stack = append(stack, k)
					break
				} else {
					stack = stack[:len(stack)-1]
				}
			}
		}
	}

	// Compute actual subtree end (Rcalc) and Lend for verification
	Rcalc := make([]int, n+2)
	Lend := make([]int, n+2)
	type stEl struct {
		v     int
		state byte
	}
	st := make([]stEl, 0, 2*n)
	st = append(st, stEl{v: 1, state: 0})
	for len(st) > 0 {
		el := st[len(st)-1]
		st = st[:len(st)-1]
		if el.state == 0 {
			st = append(st, stEl{v: el.v, state: 1})
			if right[el.v] != 0 {
				st = append(st, stEl{v: right[el.v], state: 0})
			}
			if left[el.v] != 0 {
				st = append(st, stEl{v: left[el.v], state: 0})
			}
		} else {
			maxv := el.v
			if left[el.v] != 0 {
				if Rcalc[left[el.v]] > maxv {
					maxv = Rcalc[left[el.v]]
				}
				Lend[el.v] = Rcalc[left[el.v]]
			} else {
				Lend[el.v] = el.v
			}
			if right[el.v] != 0 {
				if Rcalc[right[el.v]] > maxv {
					maxv = Rcalc[right[el.v]]
				}
			}
			Rcalc[el.v] = maxv
		}
	}

	// Verify constraints
	for i := 0; i < c; i++ {
		a := A[i]
		b := B[i]
		if a >= b {
			impossible()
			return
		}
		if D[i] == 0 {
			// LEFT: b must be <= Lend[a]
			if !(b <= Lend[a]) {
				impossible()
				return
			}
		} else {
			// RIGHT: b must be > Lend[a] and <= Rcalc[a]
			if !(b > Lend[a] && b <= Rcalc[a]) {
				impossible()
				return
			}
		}
	}

	// Output inorder traversal
	out := bufio.NewWriterSize(os.Stdout, 1<<20)
	defer out.Flush()
	// Iterative inorder
	itStack := make([]int, 0, 64)
	cur := 1
	first := true
	for cur != 0 || len(itStack) > 0 {
		if cur != 0 {
			itStack = append(itStack, cur)
			cur = left[cur]
		} else {
			cur = itStack[len(itStack)-1]
			itStack = itStack[:len(itStack)-1]
			if !first {
				out.WriteByte(' ')
			}
			first = false
			out.WriteString(strconv.Itoa(cur))
			cur = right[cur]
		}
	}
}