#include <cstdio>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <bitset>
#include <numeric>
#include <climits>
#include <cfloat>
using namespace std;

const int INF = INT_MAX / 2;

class Edge{
public:
    int to, time1, time2;
    Edge(int to0, int time01, int time02){
        to = to0;
        time1 = time01;
        time2 = time02;
    }
};

int toInt(string& s)
{
    return atoi(s.substr(0,2).c_str()) * 60 + atoi(s.substr(3, 2).c_str());
}

int main()
{
    for(;;){
        int s, t; // 駅の数、電車の数
        cin >> s >> t;
        if(s == 0)
            return 0;

        int start, goal;         // 出発地、目的地
        int startTime, goalTime; // 出発時間、待ち合わせの時間
        string tmp1, tmp2;
        cin >> start >> tmp1 >> goal >> tmp2;
        startTime = toInt(tmp1);
        goalTime = toInt(tmp2);

        vector<int> n(t);             // n[i]       : 電車iが停まる駅の数
        vector<vector<int> > stop(t); // stop[i][j] : 電車iがj番目に停まる駅
        vector<vector<int> > time(t); // time[i][j] : 電車iがj番目に停まる時間
        vector<vector<Edge> > edges(s+1);
        vector<vector<Edge> > invEdges(s+1);
        for(int i=0; i<t; ++i){
            cin >> n[i];
            stop[i].resize(n[i]);
            time[i].resize(n[i]);

            for(int j=0; j<n[i]; ++j){
                string tmp;
                cin >> stop[i][j] >> tmp;
                time[i][j] = toInt(tmp);
            }
            for(int j=1; j<n[i]; ++j){
                edges[stop[i][j-1]].push_back(Edge(stop[i][j], time[i][j-1], time[i][j]));
                invEdges[stop[i][j]].push_back(Edge(stop[i][j-1], time[i][j-1], time[i][j]));
            }
        }

        vector<int> minTime(s+1, INF); // minTime[i] : 出発地から駅iに向かったとき、駅iに到着する最も早い時間
        vector<int> maxTime(s+1, -1);  // maxTime[i] : 駅iから目的地に向かったとき、駅iを出発しなければならない最も遅い時間

        multimap<int, int> mm;
        mm.insert(make_pair(startTime, start));
        minTime[start] = startTime;
        while(!mm.empty()){
            int currTime = mm.begin()->first;
            int pos = mm.begin()->second;
            mm.erase(mm.begin());
            if(currTime > minTime[pos])
                continue;

            for(unsigned i=0; i<edges[pos].size(); ++i){
                Edge e = edges[pos][i];
                if(currTime <= e.time1 && e.time2 < minTime[e.to]){
                    minTime[e.to] = e.time2;
                    mm.insert(make_pair(e.time2, e.to));
                }
            }
        }

        mm.insert(make_pair(-goalTime, goal));
        maxTime[goal] = goalTime;
        while(!mm.empty()){
            int currTime = - mm.begin()->first;
            int pos = mm.begin()->second;
            mm.erase(mm.begin());
            if(currTime < maxTime[pos])
                continue;

            for(unsigned i=0; i<invEdges[pos].size(); ++i){
                Edge e = invEdges[pos][i];
                if(currTime >= e.time2 && e.time1 > maxTime[e.to]){
                    maxTime[e.to] = e.time1;
                    mm.insert(make_pair(-e.time1, e.to));
                }
            }
        }

        int ret = -1;
        if(start == goal && startTime <= goalTime)
            ret = 0;
        for(int i=0; i<t; ++i){
            for(int j=0; j<n[i]; ++j){
                for(int k=j+1; k<n[i]; ++k){
                    if(minTime[stop[i][j]] <= time[i][j] && time[i][k] <= maxTime[stop[i][k]])
                        ret = max(ret, time[i][k] - time[i][j]);
                }
            }
        }
        if(ret == -1)
            cout << "impossible" << endl;
        else
            cout << ret << endl;
    }
}

Measured memory_bytes: 5228