/*
加深一下对查分约束的理解
建图的时候为了保证所有点联通 虚拟一个点
它与所有点相连 权值为0
然后跑SPFA判负环
这题好像要写dfs的SPFA 要不超时
比较懒 改了改重复进队的条件~
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define maxn 40010
using namespace std;
int n,m,num,head[maxn],dis[maxn],f[maxn],c[maxn],falg;
struct node{
int v,t,pre;
}e[maxn];
queue<int>q;
void Add(int from,int to,int dis){
num++;e[num].v=to;
e[num].t=dis;
e[num].pre=head[from];
head[from]=num;
}
void SPFA(){
memset(dis,127/3,sizeof(dis));
f[n+1]=1;dis[n+1]=0;
q.push(n+1);c[n+1]++;
while(!q.empty()){
int k=q.front();q.pop();
if(c[k]>n){
falg=1;break;
}
f[k]=0;
for(int i=head[k];i;i=e[i].pre){
int v=e[i].v;
if(dis[v]>dis[k]+e[i].t){
dis[v]=dis[k]+e[i].t;
if(f[v]==0){
f[v]=1;c[v]++;
q.push(v);
}
}
}
}
}
int main()
{
scanf("%d%d",&n,&m);
int w,x,y,z;
for(int i=1;i<=m;i++){
scanf("%d",&w);
if(w==1){
scanf("%d%d%d",&x,&y,&z);
Add(y,x,-z);
}
if(w==2){
scanf("%d%d%d",&x,&y,&z);
Add(x,y,z);
}
if(w==3){
scanf("%d%d",&x,&y);
Add(x,y,0);Add(y,x,0);
}
}
for(int i=1;i<=n;i++)Add(n+1,i,0);
SPFA();
if(!falg)printf("Yes\n");
else printf("No\n");
return 0;
}