Big Balls
Difficulty: Hard

In the jackpot round of a game show, Big Balls, you are given $N$ jackpot balls, each having an integer weight (in grams). Within the time alloted, you may put two balls on opposite sides of a scale in order to determine which ball is heavier. To help you with your task, the host added some extra balls (different from the $N$ jackpot balls) and reveals to you how heavy each of them are (in grams).

At the end of the allotted time, you must guess the weight of each of the $N$ balls. Take note that each of your guesses must be a positive integer. The only catch is that if the sum of your guesses exceeds the actual sum of the weights, you go home with nothing. Knowing this, you reckon that guessing too high at any point is too risky (it would cost you everything), you decide to guess the weight of each ball such that the sum of the weights of your guesses is minimized.

**Input Format**  
The first line of input will contain two positive integers, $N$ and $M$, separated by a space.
The next $M$ lines describe the comparisons you were able to do during the time alloted.
With each comparison you gain one of the following information:

* Type A: Ball $X$ is heavier than Ball $Y$.
* Type B: Ball $X$ is lighter than Ball $Y$.
* Type C: Ball $X$ is heavier than the ball weighing $W$ grams.
* Type D: Ball $X$ is lighter than the ball weighing $W$ grams.

The $M$ lines will each contain a letter from $A$ to $D$ representing the statement it describes and two integers. If the statement is of type $A$ or $B$, the two integers will be $X$ and $Y$ (in that order), describing which two balls were compared. If the statement is of type $C$ or $D$, the two integers will be $X$ and $W$ (in that order), giving an upper/lower bound for the weight of ball $X$.

**Output Format**  
If it is impossible to make a logical conclusion (i.e. there are contradictions with the statements given), output a single line containing the word `IMPOSSIBLE`.

Otherwise, output $N$ lines, each containing a single integer. The $i^\text{th}$ line should contain your guess (based on the strategy described above) for the weight of Ball $i$.

It is guaranteed that the answer is unique. Note that balls may have the same weights.

**Constraints**  
$1 \le N \le 2\cdot 10^5$  
$1 \le M \le 2\cdot 10^5$  
$1 \le X \le N$  
$1 \le Y \le N$  
$X \ne Y$  
$1 \le W \le 10^9$

**Sample Input 1**  

    1 1
    D 1 1

**Sample Output 1**  

    IMPOSSIBLE

**Sample Input 2**  

    5 6
    A 2 1
    B 1 2
    C 3 4
    D 4 12
    B 5 4
    C 1 1

**Sample Output 2**  

    2
    3
    5
    2
    1

**Explanation**  
The first case deals with $N = 1$ ball and exactly $M = 1$ statement stating that Ball $1$ is lighter than the ball weighing $1$ gram. Hence its weight must be less than $1$ gram. There is no positive integer less than $1$ and so this setup is impossible.

The second case deals with $N = 5$ balls and $M = 6$ statements which translate as follows:

* Ball 2 is heavier than Ball 1.
* Ball 1 is lighter than Ball 2.
* Ball 3 is heavier than the ball weighing 4 grams.
* Ball 4 is lighter than the ball weighing 12 grams.
* Ball 5 is lighter than Ball 4.
* Ball 1 is heavier than the ball weighing 1 gram.

Since the only lower bound for Ball 1 is the fact that it is heavier than $1$ gram, we should guess $2$ for Ball 1. We shouldn't guess any higher since we might go over the sum. Now, since Ball 2 is heavier than Ball 1, we should guess $3$ for that. And so on.


Input Format:

Output Format:

Sample Input:

Sample Output:

Python 3 starter code:


Reference solution (C++):
    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <queue>
    #include <set>
    #include <cassert>

    using namespace std;

    const int N = 200002;

    set<int> con[N];
    int ind[N],L[N],G[N],a[N];
    char s[5];
    queue<int> q;

    bool run(int n) {
    int m = 0;
        for (int i = 0; i < n; ++i) {
            if (L[i] - 1 < G[i] + 1) {
                return false;

            }
            //printf("%d %d %d\n",i,L[i],G[i]);
            if (ind[i] == 0) {
                q.push(i);	
            }
        }

        while (!q.empty()) {
            int x = q.front();
            q.pop();
            ++m;
            a[x] = G[x] + 1;
            //printf("a[%d] = %d\n",x,a[x]);
            for (set<int>::iterator t = con[x].begin(); t != con[x].end(); ++t) {
                G[*t] = max(a[x], G[*t]);
                if (L[*t] - 1 < G[*t] + 1) {
                    //puts("haha");
                    return false;
                }
                if (--ind[*t] == 0) {
                    q.push(*t);
                }
            }
        }
        //printf("m = %d\n",m);
        return (m == n);		
    }

    int main() {
    int n,m;

        scanf("%d%d",&n,&m);
        assert((n >= 1) && (n <= 200000));
        assert((m >= 1) && (m <= 200000));
        for (int i = 0; i < n; ++i) {
            L[i] = 2000000000;
            G[i] = 0;
        }
        for (int i = 0; i < m; ++i) {
            int x,y;		
            scanf("%s%d%d",s,&x,&y);
            assert((strcmp(s,"A") == 0) || (strcmp(s,"B") == 0) || (strcmp(s,"C") == 0) || (strcmp(s,"D") == 0));
            --x;
            switch(s[0]) {
            case 'A': 
                --y;
                assert((x >= 0) && (x < n));
                assert((y >= 0) && (y < n) && (y != x));
                if (con[y].find(x) == con[y].end()) {
                    con[y].insert(x);
                    ++ind[x];
                }
                break;
            case 'B':
                --y;
                assert((x >= 0) && (x < n));
                assert((y >= 0) && (y < n) && (y != x));
                if (con[x].find(y) == con[x].end()) {
                    con[x].insert(y);
                    ++ind[y];
                }
                break;
            case 'C':
                assert((y >= 1) && (y <= 1000000000));
                G[x] = max(G[x], y);
                break;
            case 'D':
                assert((y >= 1) && (y <= 1000000000));
                L[x] = min(L[x], y);
                break;
            }
        }
        if (run(n)) {
            for (int i = 0; i < n; ++i) {
                printf("%d\n",a[i]);
            }

        }	
        else {
            puts("IMPOSSIBLE");
        }		

        return 0;
    }