#include<iostream>
#include<queue>
#include<cstdio>
#define INF 1<<28
using namespace std;

struct edge{
  int to;
  int cost; //ちょっと処理を楽にするために
};

typedef pair < int, int > P; // < 最短経路, ノードの番号 >

int V;
vector < edge > G[100]; //入力(iからjはコストG[i][j]でいける)
int d[100]; //答えを入れる(最小コストを入れる)

int dijkstra(int s){ //スタート地点
  priority_queue <P, vector<P>, greater<P> > que; //小さい順になるようにqueueに代入
  
  fill(d, d+V+1, INF); //全ノードのコストをINFで初期化(d[0]~d[V])
  d[s] = 0; //スタート地点のコストを0で初期化
  
  que.push(P(0, s)); //最短経路(0), 頂点の番号(スタート)
  
  while( !que.empty() ){ //queueの中身が空になるまでループ(行ける場所が無くなるまで)
    
    P p = que.top(); que.pop(); //最小コストを取得
    int v = p.second; //最小コストであるノードの番号
    
    if(d[v] < p.first) continue; //取り出した最小コストが大きかったらループの最初に戻る
    
    for(int i=0;i<G[v].size();i++){ //今居る頂点からつながってる辺の数だけループ
      edge e = G[v][i]; //i番目のvからいけるノードとそのコストを代入
      
      if(d[e.to] > d[v] + e.cost){ //最短経路が見つかった
	d[e.to] = d[v] + e.cost; //最短経路を更新
	que.push( P(d[e.to], e.to) ); //新しい最短経路をqueueにpush
      }
    }
  }
}

int main(){
  
  int m; //エッジ数
  int a,b,ca,cb; //abでつながっている cost_a cost_b
  int x1,x2,y1,y2; //スタート、ゴール、所持金、柱の代金
  
  cin >> V >> m;
  
  edge k;
  for(;m>0;m--){
    scanf("%d,%d,%d,%d",&a,&b,&ca,&cb);
    
    k.to = b, k.cost = ca;
    G[a].push_back( k );
    
    k.to = a, k.cost = cb;
    G[b].push_back( k );
  }
  
  scanf("%d,%d,%d,%d",&x1,&x2,&y1,&y2);
  
  //行き
  dijkstra(x1);
  y1 -= d[x2];
  
  //帰り
  dijkstra(x2);
  y1 -= d[x1];
  
  //for(int i=1;i<=V;i++) cout << d[i] << endl; //確認
  
  cout << y1-y2 << endl;
  
}