Problem:
Score : 1100 points

Problem Statement

You are given a directed graph with N vertices and M edges.
The vertices are numbered 1, 2, ..., N, and the edges are numbered 1, 2, ..., M.
Edge i points from Vertex a_i to Vertex b_i.

For each edge, determine whether the reversion of that edge would change the number of the strongly connected components in the graph.

Here, the reversion of Edge i means deleting Edge i and then adding a new edge that points from Vertex b_i to Vertex a_i.

Constraints

2 \leq N \leq 1000

1 \leq M \leq 200,000

1 \leq a_i, b_i \leq N

a_i \neq b_i

If i \neq j, then a_i \neq a_j or b_i \neq b_j.

Input

Input is given from Standard Input in the following format:

N M
a_1 b_1
a_2 b_2
:
a_M b_M

Output

Print M lines. In the i-th line, if the reversion of Edge i would change the number of the strongly connected components in the graph, print diff; if it would not, print same.

Sample Input 1

3 3
1 2
1 3
2 3

Sample Output 1

same
diff
same

The number of the strongly connected components is 3 without reversion of edges, but it will become 1 if Edge 2 is reversed.

Sample Input 2

2 2
1 2
2 1

Sample Output 2

diff
diff

Reversion of an edge may result in multiple edges in the graph.

Sample Input 3

5 9
3 2
3 1
4 1
4 2
3 5
5 3
3 4
1 2
2 5

Sample Output 3

same
same
same
same
same
diff
diff
diff
diff

Solution in C (GCC 9.2.1) (judge verdict: Accepted)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define N	1000
#define M	200000

int max(int a, int b) { return a > b ? a : b; }

int oo[1 + M * 3], oh[1 + M * 3];

int link(int o, int h) {
	static int _ = 1;

	oo[_] = o, oh[_] = h;
	return _++;
}

int ii[M], jj[M];
int ae[N], af[N], ae_[N], cc[N], qu[N], cnt;

void dfs1(int i) {
	int o;

	if (cc[i])
		return;
	cc[i] = -1;
	for (o = ae[i]; o; o = oo[o]) {
		int h = oh[o], j = jj[h];

		dfs1(j);
	}
	qu[--cnt] = i;
}

void dfs2(int j, int c) {
	int o;

	if (cc[j] != -1)
		return;
	cc[j] = c;
	for (o = af[j]; o; o = oo[o]) {
		int h = oh[o], i = ii[h];

		dfs2(i, c);
	}
}

char visited[N]; int c;
int hh[N * 2], cnt_;

void dfs3(int i) {
	int o;

	visited[i] = 1;
	for (o = ae[i]; o; o = oo[o]) {
		int h = oh[o], j = jj[h];

		if (!visited[j] && cc[j] == c)
			hh[cnt_++] = h, dfs3(j);
	}
}

void dfs4(int j) {
	int o;

	visited[j] = 2;
	for (o = af[j]; o; o = oo[o]) {
		int h = oh[o], i = ii[h];

		if (visited[i] == 1 && cc[i] == c)
			hh[cnt_++] = h, dfs4(i);
	}
}

int h_;

int dfs5(int i, int t) {
	int o;

	if (i == t)
		return 1;
	if (visited[i])
		return 0;
	visited[i] = 1;
	for (o = ae[i]; o; o = oo[o]) {
		int h = oh[o], j = jj[h];

		if (h != h_ && cc[j] == c && dfs5(j, t))
			return 1;
	}
	return 0;
}

int main() {
	static int dd[N];
	static char diff[M];
	int n, n_, m, g, g_, h, i, j, s;

	scanf("%d%d", &n, &m);
	for (h = 0; h < m; h++) {
		scanf("%d%d", &i, &j), i--, j--;
		ii[h] = i, jj[h] = j;
		ae[i] = link(ae[i], h);
		af[j] = link(af[j], h);
	}
	cnt = n;
	for (i = 0; i < n; i++)
		if (!cc[i])
			dfs1(i);
	n_ = 0;
	for (g = 0; g < n; g++) {
		i = qu[g];
		if (cc[i] == -1)
			dfs2(i, n_++);
	}
	for (h = 0; h < m; h++) {
		i = cc[ii[h]], j = cc[jj[h]];
		if (i != j)
			ae_[i] = link(ae_[i], h);
	}
	for (s = 0; s < n_; s++) {
		int o;

		memset(dd, 0, n_ * sizeof *dd);
		for (o = ae_[s]; o; o = oo[o]) {
			h = oh[o], j = cc[jj[h]];
			dd[j]++;
		}
		for (o = ae_[s]; o; o = oo[o]) {
			h = oh[o], j = cc[jj[h]];
			if (dd[j] > 1)
				diff[h] = 1;
		}
		memset(dd, -1, n_ * sizeof *dd), dd[s] = 0;
		for (i = s; i < n_; i++)
			if (dd[i] != -1)
				for (o = ae_[i]; o; o = oo[o]) {
					h = oh[o], j = cc[jj[h]];
					dd[j] = max(dd[j], dd[i] + 1);
				}
		for (o = ae_[s]; o; o = oo[o]) {
			h = oh[o], j = cc[jj[h]];
			if (dd[j] > 1)
				diff[h] = 1;
		}
	}
	for (c = 0; c < n_; c++) {
		cnt = 0;
		for (i = 0; i < n; i++)
			if (cc[i] == c)
				qu[cnt++] = i;
		cnt_ = 0;
		dfs3(qu[0]);
		dfs4(qu[0]);
		for (g_ = 0; g_ < cnt_; g_++) {
			h = hh[g_];
			for (g = 0; g < cnt; g++)
				visited[qu[g]] = 0;
			h_ = h;
			diff[h] = !dfs5(ii[h], jj[h]);
		}
	}
	for (h = 0; h < m; h++)
		printf(diff[h] ? "diff\n" : "same\n");
	return 0;
}