// Mera solution mat hi dekh yaar!
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
#define inp_s ios_base::sync_with_stdio(false)
#define DRT() int test_case;cin>>test_case;while(test_case--)
#define VI vector<int>
#define VS vector<string>
#define VLL vector<LL>
#define PII pair<int,LL>
#define all(c) c.begin(),c.end()
#define sz(c) (int)c.size()
#define clr(c) c.clear()
#define pb push_back
#define mp make_pair
#define GI(x) scanf("%d",&x)
#define FOR(i,a,b) for(int i=(int)(a);i<(int)(b);i++)
#define RFOR(i,a,b) for(int i=(int)(b)-1;i>=(int)(a);i--)
#define MOD 1000000007
#define EPS 1E-10
#define PI acos(-1)
#define CASE(x) cout << "Case #" << x << ": ";
LL f[1010][1010];
int n,m;
LL mod;
LL preprocess(int i , int j)
{
if(i == j) return 0;
else if(i == 1 || j == 1) return (1%mod);
else if(f[i][j] != -1) return f[i][j];
LL ret = (preprocess(i-1,j) + preprocess(i,j-1)) % mod;
ret = (ret + preprocess(i-1,j-1)) % mod;
return (f[i][j] = ret);
}
int isBridge[1010][1010];
vector<VI> graph;
int dfsTime = 1;
vector<int> low , disc;
int visited[1010];
void bridgeDFS(int u , int par)
{
if(visited[u]) return ;
low[u] = disc[u] = dfsTime++;
visited[u] = 1;
FOR(i,0,sz(graph[u]))
{
int v = graph[u][i];
if(v == par) continue;
if(!visited[v])
{
bridgeDFS(v, u);
low[u] = min(low[u] , low[v]);
if(low[v] > disc[u])
isBridge[u][v] = isBridge[v][u] = 1;
}
else
low[u] = min(low[u] , disc[v]);
}
}
int conversion[1010] = {0};
void findBridges()
{
FOR(i,0,1010) visited[i] = 0;
bridgeDFS(1 , -1);
FOR(i,0,1010) conversion[i] = i;
}
vector< vector<PII> > bridgeGraph;
void bridgeTree()
{
FOR(i,0,1010) visited[i] = 0;
FOR(ii,1,n+1)
{
if(visited[ii]) continue;
queue<int> bfs;
bfs.push(ii);
visited[ii] = 1;
while(!bfs.empty())
{
int ele = bfs.front();
bfs.pop();
FOR(i,0,sz(graph[ele]))
{
int v = graph[ele][i];
if(isBridge[ele][v]) continue;
if(visited[v] == 0)
{
conversion[v] = ii;
visited[v] = 1;
bfs.push(v);
}
}
}
}
clr(bridgeGraph);
bridgeGraph.resize(n + 1);
FOR(i,1,n+1)
{
FOR(j,1,n+1)
{
if(isBridge[i][j])
{
int u = conversion[i];
int v = conversion[j];
bridgeGraph[u].pb(mp(v , f[i][j]));
bridgeGraph[v].pb(mp(u , f[i][j]));
}
}
}
}
LL cost[1010][1010] = {{0}};
LL shortestBridge[1010][1010] = {{0}};
void getans()
{
FOR(i,0,1010) FOR(j,0,1010) cost[i][j] = 0 ,shortestBridge[i][j] = INT_MAX;
FOR(i,1,n+1) FOR(j,1,n+1)
{
int u = conversion[i];
int v = conversion[j];
if(u == v) cost[u][v] = cost[v][u] = 0;
else cost[u][v] = cost[v][u] = max(cost[u][v] , f[i][j]);
}
FOR(i,1,n+1)
{
FOR(ii,0,1010) visited[ii] = 0;
int u = conversion[i];
if(visited[u]) continue;
queue<PII> bfs;
bfs.push(mp(u,INT_MAX));
visited[u] = 1;
while(!bfs.empty())
{
PII ele = bfs.front();
bfs.pop();
u = ele.first;
LL c = ele.second;
FOR(ii,0,sz(bridgeGraph[u]))
{
PII q = bridgeGraph[u][ii];
if(visited[q.first]) continue;
visited[q.first] = 1;
shortestBridge[conversion[i]][q.first] = shortestBridge[q.first][conversion[i]] = min(q.second , c);
bfs.push(mp(q.first , min(q.second , c) ));
}
}
}
LL ans = 0;
FOR(i,1,n+1)
{
FOR(j,1,n+1)
{
int u = conversion[i];
int v = conversion[j];
if(u == v) continue;
ans = max(ans , cost[u][v] - shortestBridge[u][v]);
}
}
cout << ans << endl;
}
int main()
{
inp_s;
DRT()
{
clr(low);
clr(disc);
clr(graph);
dfsTime = 1;
cin >> n >> m >> mod;
graph.resize(n + 1);
FOR(i,0,1010) FOR(j,0,1010) isBridge[i][j] = 0, f[i][j] = -1;
FOR(i,1,1010) FOR(j,1,1010) f[i][j] = preprocess(i,j);
//step 1 : preprocess , done!
FOR(i,0,m)
{
int a,b;
cin >> a >> b;
graph[a].pb(b);
graph[b].pb(a);
}
low.resize(n + 1);
disc.resize(n + 1);
findBridges();
//step 2 : finding bridges, done.
bridgeTree();
//step 3 : create the bridge tree, done.
getans();
//step 4 : this is what they need.. wonder why i couldnt make this step 1.
}
return 0;
}
Ly8gTWVyYSBzb2x1dGlvbiBtYXQgaGkgZGVraCB5YWFyIQoKI2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7Cgp0eXBlZGVmIGxvbmcgbG9uZyBMTDsKCiNkZWZpbmUgaW5wX3MgICAgIGlvc19iYXNlOjpzeW5jX3dpdGhfc3RkaW8oZmFsc2UpCiNkZWZpbmUgRFJUKCkgICAgIGludCB0ZXN0X2Nhc2U7Y2luPj50ZXN0X2Nhc2U7d2hpbGUodGVzdF9jYXNlLS0pCgojZGVmaW5lIFZJICAgICAgICB2ZWN0b3I8aW50PgojZGVmaW5lIFZTICAgICAgICB2ZWN0b3I8c3RyaW5nPgojZGVmaW5lIFZMTCAgICAgICB2ZWN0b3I8TEw+CiNkZWZpbmUgUElJICAgICAgIHBhaXI8aW50LExMPgojZGVmaW5lIGFsbChjKSAgICBjLmJlZ2luKCksYy5lbmQoKQojZGVmaW5lIHN6KGMpICAgICAoaW50KWMuc2l6ZSgpCiNkZWZpbmUgY2xyKGMpICAgIGMuY2xlYXIoKQojZGVmaW5lIHBiICAgICAgICBwdXNoX2JhY2sKI2RlZmluZSBtcCAgICAgICAgbWFrZV9wYWlyCgojZGVmaW5lIEdJKHgpICAgICBzY2FuZigiJWQiLCZ4KQoKI2RlZmluZSBGT1IoaSxhLGIpICAgICAgZm9yKGludCBpPShpbnQpKGEpO2k8KGludCkoYik7aSsrKQojZGVmaW5lIFJGT1IoaSxhLGIpICAgICBmb3IoaW50IGk9KGludCkoYiktMTtpPj0oaW50KShhKTtpLS0pCgojZGVmaW5lIE1PRCAgICAgICAxMDAwMDAwMDA3CiNkZWZpbmUgRVBTICAgICAgIDFFLTEwCgojZGVmaW5lIFBJICBhY29zKC0xKQoKI2RlZmluZSBDQVNFKHgpICAgY291dCA8PCAiQ2FzZSAjIiA8PCB4IDw8ICI6ICI7CgpMTCBmWzEwMTBdWzEwMTBdOwppbnQgbixtOwpMTCBtb2Q7CgpMTCBwcmVwcm9jZXNzKGludCBpICwgaW50IGopCnsKCWlmKGkgPT0gaikgcmV0dXJuIDA7CgllbHNlIGlmKGkgPT0gMSB8fCBqID09IDEpIHJldHVybiAoMSVtb2QpOwoJZWxzZSBpZihmW2ldW2pdICE9IC0xKSByZXR1cm4gZltpXVtqXTsKCUxMIHJldCA9IChwcmVwcm9jZXNzKGktMSxqKSArIHByZXByb2Nlc3MoaSxqLTEpKSAlIG1vZDsKCXJldCA9IChyZXQgKyBwcmVwcm9jZXNzKGktMSxqLTEpKSAlIG1vZDsKCXJldHVybiAoZltpXVtqXSA9IHJldCk7Cn0KCmludCBpc0JyaWRnZVsxMDEwXVsxMDEwXTsKdmVjdG9yPFZJPiBncmFwaDsKCmludCBkZnNUaW1lID0gMTsKdmVjdG9yPGludD4gbG93ICwgZGlzYzsKaW50IHZpc2l0ZWRbMTAxMF07Cgp2b2lkIGJyaWRnZURGUyhpbnQgdSAsIGludCBwYXIpCnsKCWlmKHZpc2l0ZWRbdV0pIHJldHVybiA7Cglsb3dbdV0gPSBkaXNjW3VdID0gZGZzVGltZSsrOwoJdmlzaXRlZFt1XSA9IDE7CglGT1IoaSwwLHN6KGdyYXBoW3VdKSkKCXsKCQlpbnQgdiA9IGdyYXBoW3VdW2ldOwoJCWlmKHYgPT0gcGFyKSBjb250aW51ZTsKCgkJaWYoIXZpc2l0ZWRbdl0pCgkJewoJCQlicmlkZ2VERlModiwgdSk7CgkJCWxvd1t1XSA9IG1pbihsb3dbdV0gLCBsb3dbdl0pOwoJCQlpZihsb3dbdl0gPiBkaXNjW3VdKQoJCQkJaXNCcmlkZ2VbdV1bdl0gPSBpc0JyaWRnZVt2XVt1XSA9IDE7CgkJfQoJCWVsc2UKCQkJbG93W3VdID0gbWluKGxvd1t1XSAsIGRpc2Nbdl0pOwoJfQp9CgppbnQgY29udmVyc2lvblsxMDEwXSA9IHswfTsKCnZvaWQgZmluZEJyaWRnZXMoKQp7CglGT1IoaSwwLDEwMTApIHZpc2l0ZWRbaV0gPSAwOwoJYnJpZGdlREZTKDEgLCAtMSk7CglGT1IoaSwwLDEwMTApIGNvbnZlcnNpb25baV0gPSBpOwp9Cgp2ZWN0b3I8IHZlY3RvcjxQSUk+ID4gYnJpZGdlR3JhcGg7Cgp2b2lkIGJyaWRnZVRyZWUoKQp7CglGT1IoaSwwLDEwMTApIHZpc2l0ZWRbaV0gPSAwOwoJRk9SKGlpLDEsbisxKQoJewoJCWlmKHZpc2l0ZWRbaWldKSBjb250aW51ZTsKCQlxdWV1ZTxpbnQ+IGJmczsKCQliZnMucHVzaChpaSk7CgkJdmlzaXRlZFtpaV0gPSAxOwoJCXdoaWxlKCFiZnMuZW1wdHkoKSkKCQl7CgkJCWludCBlbGUgPSBiZnMuZnJvbnQoKTsKCQkJYmZzLnBvcCgpOwoJCQlGT1IoaSwwLHN6KGdyYXBoW2VsZV0pKQoJCQl7CgkJCQlpbnQgdiA9IGdyYXBoW2VsZV1baV07CgkJCQlpZihpc0JyaWRnZVtlbGVdW3ZdKSBjb250aW51ZTsKCQkJCWlmKHZpc2l0ZWRbdl0gPT0gMCkKCQkJCXsKCQkJCQljb252ZXJzaW9uW3ZdID0gaWk7CgkJCQkJdmlzaXRlZFt2XSA9IDE7CgkJCQkJYmZzLnB1c2godik7CgkJCQl9CgkJCX0KCQl9Cgl9CgljbHIoYnJpZGdlR3JhcGgpOwoJYnJpZGdlR3JhcGgucmVzaXplKG4gKyAxKTsKCUZPUihpLDEsbisxKQoJewoJCUZPUihqLDEsbisxKQoJCXsKCQkJaWYoaXNCcmlkZ2VbaV1bal0pCgkJCXsKCQkJCWludCB1ID0gY29udmVyc2lvbltpXTsKCQkJCWludCB2ID0gY29udmVyc2lvbltqXTsKCQkJCWJyaWRnZUdyYXBoW3VdLnBiKG1wKHYgLCBmW2ldW2pdKSk7CgkJCQlicmlkZ2VHcmFwaFt2XS5wYihtcCh1ICwgZltpXVtqXSkpOwoJCQl9CgkJfQoJfQp9CgpMTCBjb3N0WzEwMTBdWzEwMTBdID0ge3swfX07CkxMIHNob3J0ZXN0QnJpZGdlWzEwMTBdWzEwMTBdID0ge3swfX07Cgp2b2lkIGdldGFucygpCnsKCUZPUihpLDAsMTAxMCkgRk9SKGosMCwxMDEwKSBjb3N0W2ldW2pdID0gMCAsc2hvcnRlc3RCcmlkZ2VbaV1bal0gPSBJTlRfTUFYOwoJRk9SKGksMSxuKzEpIEZPUihqLDEsbisxKQoJewoJCWludCB1ID0gY29udmVyc2lvbltpXTsKCQlpbnQgdiA9IGNvbnZlcnNpb25bal07CgkJaWYodSA9PSB2KSBjb3N0W3VdW3ZdID0gY29zdFt2XVt1XSA9IDA7CgkJZWxzZSBjb3N0W3VdW3ZdID0gY29zdFt2XVt1XSA9IG1heChjb3N0W3VdW3ZdICwgZltpXVtqXSk7Cgl9CglGT1IoaSwxLG4rMSkKCXsKCQlGT1IoaWksMCwxMDEwKSB2aXNpdGVkW2lpXSA9IDA7CgkJaW50IHUgPSBjb252ZXJzaW9uW2ldOwoJCWlmKHZpc2l0ZWRbdV0pIGNvbnRpbnVlOwoJCXF1ZXVlPFBJST4gYmZzOwoJCWJmcy5wdXNoKG1wKHUsSU5UX01BWCkpOwoKCQl2aXNpdGVkW3VdID0gMTsKCQl3aGlsZSghYmZzLmVtcHR5KCkpCgkJewoJCQlQSUkgZWxlID0gYmZzLmZyb250KCk7CgkJCWJmcy5wb3AoKTsKCQkJdSA9IGVsZS5maXJzdDsKCQkJTEwgYyA9IGVsZS5zZWNvbmQ7CgkJCUZPUihpaSwwLHN6KGJyaWRnZUdyYXBoW3VdKSkKCQkJewoJCQkJUElJIHEgPSBicmlkZ2VHcmFwaFt1XVtpaV07CgkJCQlpZih2aXNpdGVkW3EuZmlyc3RdKSBjb250aW51ZTsKCQkJCXZpc2l0ZWRbcS5maXJzdF0gPSAxOwoJCQkJc2hvcnRlc3RCcmlkZ2VbY29udmVyc2lvbltpXV1bcS5maXJzdF0gPSBzaG9ydGVzdEJyaWRnZVtxLmZpcnN0XVtjb252ZXJzaW9uW2ldXSA9IG1pbihxLnNlY29uZCAsIGMpOwoJCQkJYmZzLnB1c2gobXAocS5maXJzdCAsIG1pbihxLnNlY29uZCAsIGMpICkpOwoJCQl9CgkJfQoJfQoJTEwgYW5zID0gMDsKCUZPUihpLDEsbisxKQoJewoJCUZPUihqLDEsbisxKQoJCXsKCQkJaW50IHUgPSBjb252ZXJzaW9uW2ldOwoJCQlpbnQgdiA9IGNvbnZlcnNpb25bal07CgkJCWlmKHUgPT0gdikgY29udGludWU7CgkJCWFucyA9IG1heChhbnMgLCBjb3N0W3VdW3ZdIC0gc2hvcnRlc3RCcmlkZ2VbdV1bdl0pOwoJCX0KCX0KCWNvdXQgPDwgYW5zIDw8IGVuZGw7Cn0KCmludCBtYWluKCkKewoJaW5wX3M7CglEUlQoKQoJewoJCWNscihsb3cpOwoJCWNscihkaXNjKTsKCQljbHIoZ3JhcGgpOwoJCWRmc1RpbWUgPSAxOwoKCQljaW4gPj4gbiA+PiBtID4+IG1vZDsKCQlncmFwaC5yZXNpemUobiArIDEpOwoJCUZPUihpLDAsMTAxMCkgRk9SKGosMCwxMDEwKSBpc0JyaWRnZVtpXVtqXSA9IDAsIGZbaV1bal0gPSAtMTsKCQlGT1IoaSwxLDEwMTApIEZPUihqLDEsMTAxMCkgZltpXVtqXSA9IHByZXByb2Nlc3MoaSxqKTsKCQkvL3N0ZXAgMSA6IHByZXByb2Nlc3MgLCBkb25lIQoJCUZPUihpLDAsbSkKCQl7CgkJCWludCBhLGI7CgkJCWNpbiA+PiBhID4+IGI7CgkJCWdyYXBoW2FdLnBiKGIpOwoJCQlncmFwaFtiXS5wYihhKTsKCQl9CgkJbG93LnJlc2l6ZShuICsgMSk7CgkJZGlzYy5yZXNpemUobiArIDEpOwoJCWZpbmRCcmlkZ2VzKCk7CgkJLy9zdGVwIDIgOiBmaW5kaW5nIGJyaWRnZXMsIGRvbmUuCgkJYnJpZGdlVHJlZSgpOwoJCS8vc3RlcCAzIDogY3JlYXRlIHRoZSBicmlkZ2UgdHJlZSwgZG9uZS4KCQlnZXRhbnMoKTsKCQkvL3N0ZXAgNCA6IHRoaXMgaXMgd2hhdCB0aGV5IG5lZWQuLiB3b25kZXIgd2h5IGkgY291bGRudCBtYWtlIHRoaXMgc3RlcCAxLiAKCX0KCXJldHVybiAwOwp9