#include <iostream>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cstring>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <bitset>
#include <numeric>
#include <utility>
#include <iomanip>
#include <algorithm>
#include <functional>
#include <unordered_map>
using namespace std;

#define REP(i, s) for (int i = 0; i < s; ++i)
#define ALL(v) (v.begin(), v.end())
#define COUT(x) cout << #x << " = " << (x) << " (L" << __LINE__ << ")" << endl
#define EACH(i, s) for (__typeof__((s).begin()) i = (s).begin(); i != (s).end(); ++i)

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
template<class T1, class T2> ostream& operator << (ostream &s, pair<T1,T2> P)
{ return s << '<' << P.first << ", " << P.second << '>'; }
template<class T> ostream& operator << (ostream &s, vector<T> P)
{ for (int i = 0; i < P.size(); ++i) { if (i > 0) { s << " "; } s << P[i]; } return s; }
template<class T> ostream& operator << (ostream &s, vector<vector<T> > P)
{ for (int i = 0; i < P.size(); ++i) { s << endl << P[i]; } return s << endl; }
template<class T> ostream& operator << (ostream &s, set<T> P)
{ EACH(it, P) { s << "<" << *it << "> "; } return s << endl; }
template<class T1, class T2> ostream& operator << (ostream &s, map<T1,T2> P)
{ EACH(it, P) { s << "<" << it->first << "->" << it->second << "> "; } return s << endl; }



const int MAX_V = 1100;
struct Graph {
    int V;
    vector<int> list[MAX_V];
    vector<int> back[MAX_V];
    
    Graph(int n = 0) : V(n) {}
    void init(int n = 0) {V = n; for (int i = 0; i < MAX_V; ++i) {list[i].clear(); back[i].clear();} }
    inline vector<int>& operator [] (int i) {return list[i];}
    
    void direct(int f, int t) {
        list[f].push_back(t);
        back[t].push_back(f);
    }
    
    friend ostream& operator << (ostream& s, const Graph& G) {
        s << endl; for (int i = 0; i < G.V; ++i) {s << i << " : " << G.list[i] << endl;}return s;
    }
} G;

vector<vector<int> > scc;
Graph SG;
int cmp[MAX_V];

static bool used[MAX_V];
static set<pair<int,int> > se;
static vector<int> vs, rvs;

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

void rdfs(Graph &G, int v, int k) {
    used[v] = true;
    cmp[v] = k;
    for (int i = 0; i < G.back[v].size(); ++i) {
        if (!used[G.back[v][i]]) rdfs(G, G.back[v][i], k);
    }
    rvs.push_back(v);
}

void make_dag(Graph &G) {
    int SV = scc.size();
    SG.init(SV);
    se.clear();
    for (int i = 0; i < G.V; ++i) {
        int u = cmp[i];
        for (int j = 0; j < G[i].size(); ++j) {
            int v = cmp[G[i][j]];
            if (u == v) continue;
            if (!se.count(make_pair(u, v))) SG.direct(u, v);
            used[v] = true;
        }
    }
}

void SCC(Graph &G) {
    vs.clear();
    scc.clear();
    memset(used, 0, sizeof(used));
    for (int i = 0; i < G.V; ++i) {
        if (!used[i]) dfs(G, i);
    }
    int k = 0;
    memset(used, 0, sizeof(used));
    for (int i = vs.size()-1; i >= 0; --i) {
        if (!used[vs[i]]) {
            rvs.clear();
            rdfs(G, vs[i], k++);
            scc.push_back(rvs);
        }
    }
    make_dag(G);
}



int N, M;
int a[210000], b[210000];

bool can[MAX_V][MAX_V];
int dist[MAX_V][MAX_V];

int main() {
    while (cin >> N >> M) {
        G.init(N);
        for (int i = 0; i < M; ++i) {
            cin >> a[i] >> b[i];
            --a[i], --b[i];
            G.direct(a[i], b[i]);
        }
        SCC(G);
        
        memset(can, 0, sizeof(can));
        memset(dist, -1, sizeof(dist));
        for (int v = 0; v < N; ++v) {
            dist[v][v] = 0;
            queue<int> que;
            que.push(v);
            while (!que.empty()) {
                int cur = que.front();
                que.pop();
                for (auto e : G[cur]) {
                    if (dist[v][e] == 1 && dist[cur] > 0) {
                        can[v][e] = true;
                    }
                    if (dist[v][e] == -1) {
                        dist[v][e] = dist[v][cur] + 1;
                        que.push(e);
                    }
                }
            }
        }
        
        for (int i = 0; i < M; ++i) {
            bool isbri = false;
            if (cmp[a[i]] != cmp[b[i]]) {
                isbri = true;
            }
            
            if (isbri) {
                if (can[a[i]][b[i]]) puts("diff");
                else puts("same");
            }
            else {
                if (can[a[i]][b[i]]) puts("same");
                else puts("diff");
            }
        }
        
    }
}































