#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
const int N = 510;
typedef long long LL;
using namespace std;
LL INF = 0X3f3f3f3f3f3f3f3f;
typedef struct Node{
int cid;//节点所在路线
int sum;//距离初始节点的时间
int pid;//是当前编号为cid路线上的第几个节点
}Node;
typedef struct Line{
int x;//是节点号,不是第几个节点
int time;//到下一个节点的距离
}Line;
vector<Node>ps[N];//所有经过点i的路线
vector<Line>line[N];//每一条线路
int len[N];//第i条路线的总长度,走一圈的时间
LL dis[N];//每辆车最早拿到疫苗的时间
int pid[N];//每辆车最早拿到疫苗的是哪个点
LL ans[N];//每个节点最早拿到疫苗的时间
bool st[N];//i节点是否已经是最早拿到疫苗的时间
int n,m;//n个点,m条线路
LL exgcd(LL a, LL b, LL &x, LL &y) // 扩展欧几里得算法, 求x, y,使得ax + by = gcd(a, b)
{
if (!b)
{
x = 1; y = 0;
return a;
}
LL d = exgcd(b, a % b, y, x);
y -= (a / b) * x;
return d;
}
void dijkstra(){
for (int i = 0; i < m; i ++ ){//总共找m次
int t=-1;
for (int j = 0; j < m; j ++ ){//每次从m条线路中选择最早拿到疫苗的时间
if(!st[j]&&(t==-1||dis[j]<dis[t])){
t=j;
}
}
if(t!=-1){//t就是当前最早拿到疫苗的车
st[t]=true;
}
//用t来更新其他点
int num=pid[t];//求出t车在第几个节点拿到疫苗,t线路上,第num个节点
LL d = dis[t];//t车最早拿到疫苗的时间
auto& l = line[t];//t车所在线路
for (int j = 0,k=(num)%l.size();j < l.size(); j ++,k = (k+1)%l.size() ){//
ans[l[k].x] = min(ans[l[k].x],d);//更新每个点的最早拿到疫苗时间
//看看能不能更新其他路线最新拿到疫苗的时间
for(auto c:ps[l[k].x]){//c是经过l[k].x这个点的路线
if(st[c.cid])continue;//c.cid是路线编号
LL a = d,b=len[t]; //a是距离最早拿到疫苗的时间加上走到这个点的时间
LL x = c.sum,y = len[c.cid];
LL X,Y;
LL D = exgcd(b,y,X,Y);
if((x-a)%D){
continue;
}
X = (x-a)/D*X;
y /= D;
X = (X % y + y) % y;
if(dis[c.cid]>a + b*X){//c.cid当前路线编号
dis[c.cid]=a + b*X;
pid[c.cid]=c.pid;//当前
}
}
d+=l[k].time;
}
}
}
int main(){
cin>>n>>m;
memset(dis,INF,sizeof(dis));
memset(ans,INF,sizeof(ans));
for (int i = 0; i < m; i ++ ){
int num,sum=0;
cin>>num;
for (int j = 0; j < num; j ++ ){
int x,time;
cin>>x>>time;
line[i].push_back({x,time});
ps[x].push_back({i,sum,j});
if(x==1){
dis[i] = sum;//拿到疫苗的时间
pid[i] = j;//拿到疫苗的是第几个点,i是第几辆车,j是这条线路上的第j个节点
}
sum+=time;
}
len[i] = sum;
}
dijkstra();
for (int i = 2; i <= n; i ++ )
if (ans[i] == INF) puts("inf");
else printf("%lld\n", ans[i]);
}