#include<iostream>
#include <vector>
#include <cassert>

using namespace std;
typedef long long ll;

static const int MAX_V = 1010;

class SCC {
    vector<int> *G;
    vector<int> rG[MAX_V];
    vector<int> vs;
    bool used[MAX_V];

    void dfs(int v){
        used[v] = true;
        for (int i = 0; i < G[v].size(); i++){
            if (!used[G[v][i]]){
                dfs(G[v][i]);
            }
        }
        vs.push_back(v);
    }

    void rdfs(int v, int k){
        used[v] = true;
        cmp[v] = k;
        for (int i = 0; i < rG[v].size(); i++){
            if (!used[rG[v][i]]){
                rdfs(rG[v][i], k);
            }
        }
        return;
    }

public:
    int V;
    int cmp[MAX_V];

    SCC(vector<int>* _G, int _V){
        G = _G;
        V = _V;

        //initialize reverse graph
        for (int from = 0; from < V; from++){
            for (int i = 0; i < G[from].size(); i++){
                int to = G[from][i];
                rG[to].push_back(from);
            }
        }
    }

    int solve() {
        fill(cmp, cmp+V, -1);
        fill(used, used+V, false);
        vs.clear();
        for (int v = 0; v < V; v++){
            if (!used[v]){
                dfs(v);
            }
        }
        assert (vs.size() == V);

        fill(used, used+V, false);
        int k = 0;
        for (int i = vs.size() - 1; i >= 0; i--){
            int v = vs[i];
            if (!used[v]){
                rdfs(v, k++);
            }
        }
        return k;
    }

    bool query(int u, int v){
        return cmp[u] == cmp[v];
    }
};

struct Edge {int from, to;};

vector<int> G[MAX_V];
int reached[2][MAX_V];
bool mat[MAX_V][MAX_V];


void dfs(int v, int k, int* reached){
    reached[v] = k;
    for (int i = 0; i < G[v].size(); i++){
        if (reached[G[v][i]] == -1){
            dfs(G[v][i], k, reached);
        }
    }
}

int main() {
    int N, M;
    cin >> N >> M;

    Edge es[M];
    for (int i = 0; i < M; i++){
        int from, to;
        cin >> from >> to;
        from--; to--; // adjust to 1 origin
        es[i] = {from, to};
        G[from].push_back(to);
    }

    // strongly connected component
    SCC scc = SCC(G, N);
    scc.solve();
//    for (int v = 0; v < N; v++){
//        cout << scc.cmp[v] << ",";
//    }
//    cout << endl;

    for (int v = 0; v < N; v++){
//        cout << endl;
//        cout << "from:" <<  v << endl;

        fill(reached[0], reached[0]+N, -1);
        reached[0][v] = MAX_V;
        for (int i = 0; i < G[v].size(); i++){
            int to = G[v][i];
            if (reached[0][to] == -1){
                dfs(to, i, reached[0]);
            }
        }
//        for (int u = 0; u < N; u++){
//            cout << reached[0][u] << ",";
//        }
//        cout << endl;

        fill(reached[1], reached[1]+N, -1);
        reached[1][v] = MAX_V;
        for (int i = G[v].size() - 1; i >= 0; i--){
            int to = G[v][i];
            if (reached[1][to] == -1){
                dfs(to, i, reached[1]);
            }
        }
//        for (int u = 0; u < N; u++){
//            cout << reached[1][u] << ",";
//        }
//        cout << endl;

        for (int u = 0; u < N; u++){
            mat[v][u] = (reached[0][u] != reached[1][u]);
        }
    }

    for (int i = 0; i < M; i++){
        Edge e = es[i];
        if (scc.query(e.from, e.to) && mat[e.from][e.to]){
            cout << "same" << endl;
        } else if (scc.query(e.from, e.to) && !mat[e.from][e.to]){
            cout << "diff" << endl;
        } else if (!scc.query(e.from, e.to) && mat[e.from][e.to]){
            cout << "diff" << endl;
        } else if (!scc.query(e.from, e.to) && !mat[e.from][e.to]){
            cout << "same" << endl;
        }
    }

    return 0;
}



Measured memory_bytes: 6912