#include
#include
#include
#include
#include
using namespace std;
const int maxn = 1e5 + 10;
const int INF = 2e9;
vector, int>> graph[maxn];
struct node {
int idx, shortest_path, is_snow_only;
node() {}
node(int _idx, int _shortest_path, int _is_snow_only) {
idx = _idx;
shortest_path = _shortest_path;
is_snow_only = _is_snow_only;
}
bool operator < (const node & tmp) const {
return shortest_path > tmp.shortest_path;
}
};
bool visited[maxn][2];
int main(){
int n, m;
cin >> n >> m;
for(int i = 0; i < m; i++) {
int a, b, c, d;
cin >> a >> b >> c >> d;
a--; b--;
graph[a].push_back(make_pair(make_pair(b, c), d));
graph[b].push_back(make_pair(make_pair(a, c), d));
}
memset(visited, false, sizeof visited);
priority_queue pq;
pq.push(node(0, 0, 1));
int res_shortest = 2e9, res_snow = -1;
while(!pq.empty()) {
node c = pq.top();
pq.pop();
if(c.idx == n - 1) {
if(res_shortest > c.shortest_path) {
res_shortest = c.shortest_path;
res_snow = max(res_snow, c.is_snow_only);
}
}
if(visited[c.idx][c.is_snow_only]) continue;
visited[c.idx][c.is_snow_only] = true;
for(int i = 0; i < (int) graph[c.idx].size(); i++) {
int neighbour = graph[c.idx][i].first.first;
int weight = graph[c.idx][i].first.second;
int snow = graph[c.idx][i].second;
int next_snow = min(snow, c.is_snow_only);
if(!visited[neighbour][next_snow]) {
pq.push(node(neighbour, c.shortest_path + weight, next_snow));
// cout << neighbour << endl;
}
}
}
cout << res_shortest << endl;
if(res_snow == 1) {
cout << "DA" << endl;
}
else {
cout << "NE" << endl;
}
return 0;
}