#include <iostream>
#include <cstring>
using namespace std;
const int maxn=510;
const int inf=10000;
struct node
{
int type,len;//type为类型,len为道路长度
}map[maxn][maxn];
bool vis[maxn];//标记当前节点是否来过
void fiset(int n)//初始化数组
{
for(int i=0;i<=n;i++)
{
for(int j=0;j<=n;j++)
{
map[i][j].len=inf;
}
vis[i]=0;
}
return ;
}
int dou(int x)//计算x的平方
{
return x*x;
}
int dij(int n)//迪杰斯特拉算法
{
int dist[maxn],small[maxn];//small数组记录到当前节点连续走过的小道长度
for(int i=1;i<=n;i++)
{
if(map[1][i].type==0)
{
small[i]=0;
dist[i]=map[1][i].len;
}
else
{
small[i]=map[1][i].len;
dist[i]=dou(map[1][i].len);
}
}
vis[1]=1;
for(int i=2;i<=n;i++)
{
int minn=inf,u;
for(int j=1;j<=n;j++)
{
if(!vis[j]&&minn>dist[j])
{
minn=dist[j];
u=j;
}
}
vis[u]=1;
for(int j=1;j<=n;j++)
{
if(vis[j])continue;
if(map[u][j].type==0)//判断为大道,进行正常的松弛操作
{
if(dist[u]+map[u][j].len<dist[j])
{
small[j]=0;
dist[j]=dist[u]+map[u][j].len;
}
}
else//判断为小道则比较连续走小道的疲劳度再进行比较
{
if(dist[j]>(dist[u]-dou(small[u])+dou(small[u]+map[u][j].len)))
{
small[j]=small[u]+map[u][j].len;
dist[j]=dist[u]-dou(small[u])+dou(small[u]+map[u][j].len);
}
}
}
}
return dist[n];//最终返回到达n点的最小疲劳度
}
int main()
{
int n,m;
int t,a,b,c;
while(cin>>n>>m)
{
fiset(n);
for(int i=0;i<m;i++)
{
map[i+1][i+1].len=0;//将节点到自身的长度初始化为0
cin>>t>>a>>b>>c;
map[a][b].type=t;
map[b][a].type=t;
map[a][b].len=map[b][a].len=c;
}
cout<<dij(n)<<endl;
}
return 0;
}
/*
6 7
1 1 2 3
1 2 3 2
0 1 3 30
0 3 4 20
0 4 5 30
1 3 5 6
1 5 6 1
*/