#include <iostream>
#include <fstream>
#include <vector>
#define MAXN 100001
using namespace std;
ifstream f("disjoint.in");
ofstream g("disjoint.out");
int n,m; //Numarul de multimi si de operatii
int tati[MAXN] ;
//int niv[100001] = {1}; //Nivelul fiecarei multimi reprezentata de arbori
int Find(int x)
{
//Gaseste radacina lui x + compreseaza multimea lui x
if(tati[x]==0)
return x;
return tati[x]=Find(tati[x]);
/*
if(tati[x] != 0)
return tati[x] = Find(tati[x]);
else return x;
*/
/*Varianta nerecursiva
int y, z;
for( y = x; tati[y] != 0; y = tati[y]); //Memoram radacina lui x in y
//Toate elementele din multimea lui x se leaga de radacina lui x
while( tati[x] != 0 )
{
z = tati[x];
tati[x] = y;
x = z;
}
return y;
*/
}
/*
void Unire(int x, int y) // x si y trebuie sa fie radacini
{
//Multimile radacinilor se unesc
if( niv[x] <= niv[y])
tati[x] = y;
else
tati[y] = x;
if(niv[x] == niv[y]) niv[y]++;
}*/
void Go()
{
int cod, x, y;
//Citire input + rezolvare
f>>n>>m;
/*for(int i = 1; i <= n; i++)
{
//Presupunem ca fiecare element formeaza o multime unica
tati[i] = i;
}*/
//Unim multimi sau verificam apartenenta
for(int i = 0; i < m; i++)
{
f>>cod>>x>>y;
/*int r1 = Find(x); //Radacina lui x
int r2 = Find(y); //Radacina lui y
//r1 si r2 diferite
*/
if(cod==1)
{
//Unim multimile cunoscute dupa radacinile r1 si r2
//Unire(r1, r2);
tati[Find(x)] = tati[Find(y)];
}
else
{
//Sunt din aceeasi multime/arbore?
g << (Find(x) == Find(y) ? "DA" : "NU") << endl;
}
}
}
int main()
{
Go();
}